[llvm-commits] CVS: llvm/lib/Bitcode/Reader/BitcodeReader.cpp BitcodeReader.h

Chris Lattner sabre at nondot.org
Mon Apr 23 22:49:14 PDT 2007



Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.8 -> 1.9
BitcodeReader.h updated: 1.6 -> 1.7
---
Log message:

implement support for reading aggregate constants, including handling forward
constant references, etc.


---
Diffs of the changes:  (+108 -5)

 BitcodeReader.cpp |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 BitcodeReader.h   |   35 +++++++++++++++++++++---
 2 files changed, 108 insertions(+), 5 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.8 llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.9
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.8	Mon Apr 23 23:04:35 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp	Tue Apr 24 00:48:56 2007
@@ -55,6 +55,39 @@
   }
 }
 
+namespace {
+  /// @brief A class for maintaining the slot number definition
+  /// as a placeholder for the actual definition for forward constants defs.
+  class ConstantPlaceHolder : public ConstantExpr {
+    ConstantPlaceHolder();                       // DO NOT IMPLEMENT
+    void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
+public:
+  Use Op;
+  ConstantPlaceHolder(const Type *Ty)
+    : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
+      Op(UndefValue::get(Type::Int32Ty), this) {
+    }
+  };
+}
+
+Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
+                                                    const Type *Ty) {
+  if (Idx >= size()) {
+    // Insert a bunch of null values.
+    Uses.resize(Idx+1);
+    OperandList = &Uses[0];
+    NumOperands = Idx+1;
+  }
+
+  if (Uses[Idx])
+    return cast<Constant>(getOperand(Idx));
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Constant *C = new ConstantPlaceHolder(Ty);
+  Uses[Idx].init(C, this);
+  return C;
+}
+
 
 const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
   // If the TypeID is in range, return it.
@@ -324,6 +357,7 @@
   
   // Read all the records for this value table.
   const Type *CurTy = Type::Int32Ty;
+  unsigned NextCstNo = ValueList.size();
   while (1) {
     unsigned Code = Stream.ReadCode();
     if (Code == bitc::END_BLOCK) {
@@ -341,6 +375,9 @@
         }
       }
       
+      if (NextCstNo != ValueList.size())
+        return Error("Invalid constant reference!");
+      
       return Stream.ReadBlockEnd();
     }
     
@@ -403,9 +440,48 @@
       else
         V = UndefValue::get(CurTy);
       break;
+      
+    case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n, n x value number]
+      if (Record.empty() || Record.size() < Record[0]+1)
+        return Error("Invalid CST_AGGREGATE record");
+      
+      unsigned Size = Record[0];
+      std::vector<Constant*> Elts;
+      
+      if (const StructType *STy = dyn_cast<StructType>(CurTy)) {
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i+1],
+                                                     STy->getElementType(i)));
+        V = ConstantStruct::get(STy, Elts);
+      } else if (const ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) {
+        const Type *EltTy = ATy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy));
+        V = ConstantArray::get(ATy, Elts);
+      } else if (const VectorType *VTy = dyn_cast<VectorType>(CurTy)) {
+        const Type *EltTy = VTy->getElementType();
+        for (unsigned i = 0; i != Size; ++i)
+          Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy));
+        V = ConstantVector::get(Elts);
+      } else {
+        V = UndefValue::get(CurTy);
+      }
+    }
+    }
+    
+    if (NextCstNo == ValueList.size())
+      ValueList.push_back(V);
+    else if (ValueList[NextCstNo] == 0)
+      ValueList.initVal(NextCstNo, V);
+    else {
+      // If there was a forward reference to this constant, 
+      Value *OldV = ValueList[NextCstNo];
+      ValueList.setOperand(NextCstNo, V);
+      OldV->replaceAllUsesWith(V);
+      delete OldV;
     }
     
-    ValueList.push_back(V);
+    ++NextCstNo;
   }
 }
 


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.6 llvm/lib/Bitcode/Reader/BitcodeReader.h:1.7
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.6	Mon Apr 23 22:30:34 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h	Tue Apr 24 00:48:56 2007
@@ -14,21 +14,48 @@
 #ifndef BITCODE_READER_H
 #define BITCODE_READER_H
 
-#include "llvm/Type.h"
 #include "llvm/ModuleProvider.h"
+#include "llvm/Type.h"
+#include "llvm/User.h"
 #include "llvm/Bitcode/LLVMBitCodes.h"
 #include <vector>
 
 namespace llvm {
   class BitstreamReader;
-  class Value;
-  class GlobalVariable;
+  
+class BitcodeReaderValueList : public User {
+  std::vector<Use> Uses;
+public:
+  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) {}
+  
+  // vector compatibility methods
+  unsigned size() const { return getNumOperands(); }
+  void push_back(Value *V) {
+    Uses.push_back(Use(V, this));
+    OperandList = &Uses[0];
+    ++NumOperands;
+  }
+  
+  Value *operator[](unsigned i) const { return getOperand(i); }
+  
+  Value *back() const { return Uses.back(); }
+  void pop_back() { Uses.pop_back(); --NumOperands; }
+  bool empty() const { return NumOperands == 0; }
+  virtual void print(std::ostream&) const {}
+  
+  Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);
+  void initVal(unsigned Idx, Value *V) {
+    assert(Uses[Idx] == 0 && "Cannot init an already init'd Use!");
+    Uses[Idx].init(V, this);
+  }
+};
+  
 
 class BitcodeReader : public ModuleProvider {
   const char *ErrorString;
   
   std::vector<PATypeHolder> TypeList;
-  std::vector<Value*> ValueList;
+  BitcodeReaderValueList ValueList;
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
 public:
   virtual ~BitcodeReader() {}






More information about the llvm-commits mailing list