Large mechanical patch.
[oota-llvm.git] / lib / Bitcode / Reader / BitcodeReader.h
index 0655a1a91c2be875e5d7da5aac18472bca7c3748..e8ad1ddaca7a92bb9909deb47b2cdc6f96cd8995 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Chris Lattner and is distributed under
-// the University of Illinois Open Source License.  See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -15,8 +15,9 @@
 #define BITCODE_READER_H
 
 #include "llvm/ModuleProvider.h"
+#include "llvm/Attributes.h"
 #include "llvm/Type.h"
-#include "llvm/User.h"
+#include "llvm/OperandTraits.h"
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Bitcode/LLVMBitCodes.h"
 #include "llvm/ADT/DenseMap.h"
 
 namespace llvm {
   class MemoryBuffer;
-  class ParamAttrsList;
   
+//===----------------------------------------------------------------------===//
+//                          BitcodeReaderValueList Class
+//===----------------------------------------------------------------------===//
+
 class BitcodeReaderValueList : public User {
-  std::vector<Use> Uses;
+  unsigned Capacity;
+  
+  /// ResolveConstants - As we resolve forward-referenced constants, we add
+  /// information about them to this vector.  This allows us to resolve them in
+  /// bulk instead of resolving each reference at a time.  See the code in
+  /// ResolveConstantForwardRefs for more information about this.
+  ///
+  /// The key of this vector is the placeholder constant, the value is the slot
+  /// number that holds the resolved value.
+  typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;
+  ResolveConstantsTy ResolveConstants;
 public:
-  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) {}
-  
+  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0)
+                           , Capacity(0) {}
+  ~BitcodeReaderValueList() {
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+  }
+
+  /// Provide fast operand accessors
+  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
   // vector compatibility methods
   unsigned size() const { return getNumOperands(); }
+  void resize(unsigned);
   void push_back(Value *V) {
-    Uses.push_back(Use(V, this));
-    OperandList = &Uses[0];
-    ++NumOperands;
+    unsigned OldOps(NumOperands), NewOps(NumOperands + 1);
+    resize(NewOps);
+    NumOperands = NewOps;
+    OperandList[OldOps] = V;
   }
   
   void clear() {
-    std::vector<Use>().swap(Uses);
+    assert(ResolveConstants.empty() && "Constants not resolved?");
+    if (OperandList) dropHungoffUses(OperandList);
+    Capacity = 0;
   }
   
   Value *operator[](unsigned i) const { return getOperand(i); }
   
-  Value *back() const { return Uses.back(); }
-  void pop_back() { Uses.pop_back(); --NumOperands; }
+  Value *back() const { return getOperand(size() - 1); }
+  void pop_back() { setOperand(size() - 1, 0); --NumOperands; }
   bool empty() const { return NumOperands == 0; }
   void shrinkTo(unsigned N) {
     assert(N <= NumOperands && "Invalid shrinkTo request!");
-    Uses.resize(N);
-    NumOperands = N;
+    while (NumOperands > N)
+      pop_back();
   }
   virtual void print(std::ostream&) const {}
   
@@ -62,22 +87,43 @@ public:
     if (Idx == size()) {
       push_back(V);
     } else if (Value *OldV = getOperand(Idx)) {
-      // If there was a forward reference to this value, replace it.
-      setOperand(Idx, V);
-      OldV->replaceAllUsesWith(V);
-      delete OldV;
+      // Handle constants and non-constants (e.g. instrs) differently for
+      // efficiency.
+      if (Constant *PHC = dyn_cast<Constant>(OldV)) {
+        ResolveConstants.push_back(std::make_pair(PHC, Idx));
+        setOperand(Idx, V);
+      } else {
+        // If there was a forward reference to this value, replace it.
+        setOperand(Idx, V);
+        OldV->replaceAllUsesWith(V);
+        delete OldV;
+      }
     } else {
       initVal(Idx, V);
     }
   }
   
+  /// ResolveConstantForwardRefs - Once all constants are read, this method bulk
+  /// resolves any forward references.
+  void ResolveConstantForwardRefs();
+  
 private:
   void initVal(unsigned Idx, Value *V) {
-    assert(Uses[Idx] == 0 && "Cannot init an already init'd Use!");
-    Uses[Idx].init(V, this);
+    if (Idx >= size()) {
+      // Insert a bunch of null values.
+      resize(Idx * 2 + 1);
+    }
+    assert(getOperand(Idx) == 0 && "Cannot init an already init'd Use!");
+    OperandList[Idx] = V;
   }
 };
-  
+
+template <>
+struct OperandTraits<BitcodeReaderValueList>
+  : HungoffOperandTraits</*16 FIXME*/> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)  
 
 class BitcodeReader : public ModuleProvider {
   MemoryBuffer *Buffer;
@@ -90,10 +136,10 @@ class BitcodeReader : public ModuleProvider {
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
   
-  /// ParamAttrs - The set of parameter attributes by index.  Index zero in the
+  /// Attributes - The set of parameter attributes by index.  Index zero in the
   /// file is for null, and is thus not represented here.  As such all indices
   /// are off by one.
-  std::vector<const ParamAttrsList*> ParamAttrs;
+  std::vector<AttrListPtr> Attributes;
   
   /// FunctionBBs - While parsing a function body, this is a list of the basic
   /// blocks for the function.
@@ -117,7 +163,8 @@ class BitcodeReader : public ModuleProvider {
   /// stream) and what linkage the original function had.
   DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
 public:
-  BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {
+  explicit BitcodeReader(MemoryBuffer *buffer)
+      : Buffer(buffer), ErrorString(0) {
     HasReversedFunctionsWithBodies = false;
   }
   ~BitcodeReader() {
@@ -156,10 +203,10 @@ private:
     if (ID >= FunctionBBs.size()) return 0; // Invalid ID
     return FunctionBBs[ID];
   }
-  const ParamAttrsList *getParamAttrs(unsigned i) const {
-    if (i-1 < ParamAttrs.size())
-      return ParamAttrs[i-1];
-    return 0;
+  AttrListPtr getAttributes(unsigned i) const {
+    if (i-1 < Attributes.size())
+      return Attributes[i-1];
+    return AttrListPtr();
   }
   
   /// getValueTypePair - Read a value/type pair out of the specified record from
@@ -192,7 +239,7 @@ private:
 
   
   bool ParseModule(const std::string &ModuleID);
-  bool ParseParamAttrBlock();
+  bool ParseAttributeBlock();
   bool ParseTypeTable();
   bool ParseTypeSymbolTable();
   bool ParseValueSymbolTable();