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

Chris Lattner sabre at nondot.org
Tue May 1 22:47:09 PDT 2007



Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.23 -> 1.24
BitcodeReader.h updated: 1.15 -> 1.16
---
Log message:

add reader logic for terminator instrs.


---
Diffs of the changes:  (+93 -8)

 BitcodeReader.cpp |   97 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 BitcodeReader.h   |    4 ++
 2 files changed, 93 insertions(+), 8 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.23 llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.24
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.23	Wed May  2 00:16:49 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp	Wed May  2 00:46:45 2007
@@ -1090,7 +1090,7 @@
       if (OpTy == 0 || Op == 0)
         return Error("Invalid GEP record");
 
-      SmallVector<Value*, 8> GEPIdx;
+      SmallVector<Value*, 16> GEPIdx;
       for (unsigned i = 1, e = Record.size()/2; i != e; ++i) {
         const Type *IdxTy = getTypeByID(Record[i*2]);
         Value *Idx = getFnValueByID(Record[i*2+1], IdxTy);
@@ -1183,19 +1183,100 @@
         break;
       }
       return Error("Invalid RET record");
-#if 0
-    case bitc::FUNC_CODE_INST_BR:
-      // BR:         [opval, bb#, bb#] or [bb#]
-    case bitc::FUNC_CODE_INST_SWITCH:
-      // SWITCH:     [opty, opval, n, n x ops]
-    case bitc::FUNC_CODE_INST_INVOKE:
-      // INVOKE:     [fnty, op0,op1,op2, ...]
+    case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
+      if (Record.size() != 1 || Record.size() != 3)
+        return Error("Invalid BR record");
+      BasicBlock *TrueDest = getBasicBlock(Record[0]);
+      if (TrueDest == 0)
+        return Error("Invalid BR record");
+
+      if (Record.size() == 1)
+        I = new BranchInst(TrueDest);
+      else {
+        BasicBlock *FalseDest = getBasicBlock(Record[1]);
+        Value *Cond = getFnValueByID(Record[2], Type::Int1Ty);
+        if (FalseDest == 0 || Cond == 0)
+          return Error("Invalid BR record");
+        I = new BranchInst(TrueDest, FalseDest, Cond);
+      }
+      break;
+    }
+    case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, opval, n, n x ops]
+      if (Record.size() < 3 || (Record.size() & 1) == 0)
+        return Error("Invalid SWITCH record");
+      const Type *OpTy = getTypeByID(Record[0]);
+      Value *Cond = getFnValueByID(Record[1], OpTy);
+      BasicBlock *Default = getBasicBlock(Record[2]);
+      if (OpTy == 0 || Cond == 0 || Default == 0)
+        return Error("Invalid SWITCH record");
+      unsigned NumCases = (Record.size()-3)/2;
+      SwitchInst *SI = new SwitchInst(Cond, Default, NumCases);
+      for (unsigned i = 0, e = NumCases; i != e; ++i) {
+        ConstantInt *CaseVal = 
+          dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy));
+        BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
+        if (CaseVal == 0 || DestBB == 0) {
+          delete SI;
+          return Error("Invalid SWITCH record!");
+        }
+        SI->addCase(CaseVal, DestBB);
+      }
+      I = SI;
+      break;
+    }
+      
+    case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [fnty, op0,op1,op2, ...]
+      if (Record.size() < 4)
+        return Error("Invalid INVOKE record");
+      const PointerType *CalleeTy =
+        dyn_cast_or_null<PointerType>(getTypeByID(Record[0]));
+      Value *Callee = getFnValueByID(Record[1], CalleeTy);
+      BasicBlock *NormalBB = getBasicBlock(Record[2]);
+      BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+      if (CalleeTy == 0 || Callee == 0 || NormalBB == 0 || UnwindBB == 0)
+        return Error("Invalid INVOKE record");
+      
+      const FunctionType *FTy =
+        dyn_cast<FunctionType>(CalleeTy->getElementType());
+
+      // Check that the right number of fixed parameters are here.
+      if (FTy == 0 || Record.size() < 4+FTy->getNumParams())
+        return Error("Invalid INVOKE record");
+
+      SmallVector<Value*, 16> Ops;
+      for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
+        Ops.push_back(getFnValueByID(Record[4+i], FTy->getParamType(4+i)));
+        if (Ops.back() == 0)
+          return Error("Invalid INVOKE record");
+      }
+      
+      unsigned FirstVarargParam = 4+FTy->getNumParams();
+      if (FTy->isVarArg()) {
+        // Read type/value pairs for varargs params.
+        if ((Record.size()-FirstVarargParam) & 1)
+          return Error("Invalid INVOKE record");
+        
+        for (unsigned i = FirstVarargParam, e = Record.size(); i != e; i += 2) {
+          const Type *ArgTy = getTypeByID(Record[i]);
+          Ops.push_back(getFnValueByID(Record[i+1], ArgTy));
+          if (Ops.back() == 0 || ArgTy == 0)
+            return Error("Invalid INVOKE record");
+        }
+      } else {
+        if (Record.size() != FirstVarargParam)
+          return Error("Invalid INVOKE record");
+      }
+      
+      I = new InvokeInst(Callee, NormalBB, UnwindBB, &Ops[0], Ops.size());
+      break;
+    }
     case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
       I = new UnwindInst();
       break;
     case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE
       I = new UnreachableInst();
       break;
+#if 0
 
     case bitc::FUNC_CODE_INST_PHI:
       // PHI:        [ty, #ops, val0,bb0, ...]


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.15 llvm/lib/Bitcode/Reader/BitcodeReader.h:1.16
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.15	Tue May  1 02:01:57 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h	Wed May  2 00:46:45 2007
@@ -132,6 +132,10 @@
   Value *getFnValueByID(unsigned ID, const Type *Ty) {
     return ValueList.getValueFwdRef(ID, Ty);
   }
+  BasicBlock *getBasicBlock(unsigned ID) const {
+    if (ID >= FunctionBBs.size()) return 0; // Invalid ID
+    return FunctionBBs[ID];
+  }
   
   bool ParseModule(const std::string &ModuleID);
   bool ParseTypeTable();






More information about the llvm-commits mailing list