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

Chris Lattner lattner at cs.uiuc.edu
Sat Oct 16 11:18:24 PDT 2004



Changes in directory llvm/lib/Bytecode/Reader:

Reader.cpp updated: 1.133 -> 1.134
Reader.h updated: 1.14 -> 1.15
---
Log message:

Add support for undef, unreachable, and function flags


---
Diffs of the changes:  (+82 -22)

Index: llvm/lib/Bytecode/Reader/Reader.cpp
diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.133 llvm/lib/Bytecode/Reader/Reader.cpp:1.134
--- llvm/lib/Bytecode/Reader/Reader.cpp:1.133	Wed Oct 13 20:39:18 2004
+++ llvm/lib/Bytecode/Reader/Reader.cpp	Sat Oct 16 13:18:13 2004
@@ -68,7 +68,8 @@
 /// Throw an error if we've read past the end of the current block
 inline void BytecodeReader::checkPastBlockEnd(const char * block_name) {
   if (At > BlockEnd)
-    error(std::string("Attempt to read past the end of ") + block_name + " block.");
+    error(std::string("Attempt to read past the end of ") + block_name +
+          " block.");
 }
 
 /// Align the buffer position to a 32 bit boundary
@@ -347,7 +348,8 @@
   }
 
   // Check the function level types first...
-  TypeListTy::iterator I = std::find(FunctionTypes.begin(), FunctionTypes.end(), Ty);
+  TypeListTy::iterator I = std::find(FunctionTypes.begin(),
+                                     FunctionTypes.end(), Ty);
 
   if (I != FunctionTypes.end())
     return Type::FirstDerivedTyID + ModuleTypes.size() + 
@@ -628,6 +630,15 @@
   // Declare the resulting instruction we'll build.
   Instruction *Result = 0;
 
+  // If this is a bytecode format that did not include the unreachable
+  // instruction, bump up all opcodes numbers to make space.
+  if (hasNoUnreachableInst) {
+    if (Opcode >= Instruction::Unreachable &&
+        Opcode < 62) {
+      ++Opcode;
+    }
+  }
+
   // Handle binary operators
   if (Opcode >= Instruction::BinaryOpsBegin &&
       Opcode <  Instruction::BinaryOpsEnd  && Oprnds.size() == 2)
@@ -895,10 +906,13 @@
     break;
   }
   case Instruction::Unwind:
-    if (Oprnds.size() != 0) 
-      error("Invalid unwind instruction!");
+    if (Oprnds.size() != 0) error("Invalid unwind instruction!");
     Result = new UnwindInst();
     break;
+  case Instruction::Unreachable:
+    if (Oprnds.size() != 0) error("Invalid unreachable instruction!");
+    Result = new UnreachableInst();
+    break;
   }  // end switch(Opcode) 
 
   unsigned TypeSlot;
@@ -1268,12 +1282,20 @@
   // 
   // 0 if not expr; numArgs if is expr
   unsigned isExprNumArgs = read_vbr_uint();
-  
+
   if (isExprNumArgs) {
+    // 'undef' is encoded with 'exprnumargs' == 1.
+    if (!hasNoUndefValue)
+      if (--isExprNumArgs == 0)
+        return UndefValue::get(getType(TypeID));
+  
     // FIXME: Encoding of constant exprs could be much more compact!
     std::vector<Constant*> ArgVec;
     ArgVec.reserve(isExprNumArgs);
     unsigned Opcode = read_vbr_uint();
+
+    // Bytecode files before LLVM 1.4 need have a missing terminator inst.
+    if (hasNoUnreachableInst) Opcode++;
     
     // Read the slot number and types of each of the arguments
     for (unsigned i = 0; i != isExprNumArgs; ++i) {
@@ -1834,36 +1856,42 @@
   }
 
   // Read the function objects for all of the functions that are coming
-  unsigned FnSignature = 0;
-  if (read_typeid(FnSignature))
-    error("Invalid function type (type type) found");
+  unsigned FnSignature = read_vbr_uint();
+
+  if (hasNoFlagsForFunctions)
+    FnSignature = (FnSignature << 5) + 1;
 
-  while (FnSignature != Type::VoidTyID) { // List is terminated by Void
-    const Type *Ty = getType(FnSignature);
+  // List is terminated by VoidTy.
+  while ((FnSignature >> 5) != Type::VoidTyID) {
+    const Type *Ty = getType(FnSignature >> 5);
     if (!isa<PointerType>(Ty) ||
         !isa<FunctionType>(cast<PointerType>(Ty)->getElementType())) {
       error("Function not a pointer to function type! Ty = " + 
             Ty->getDescription());
-      // FIXME: what should Ty be if handler continues?
     }
 
     // We create functions by passing the underlying FunctionType to create...
     const FunctionType* FTy = 
       cast<FunctionType>(cast<PointerType>(Ty)->getElementType());
 
+
     // Insert the place hodler
     Function* Func = new Function(FTy, GlobalValue::InternalLinkage, 
                                   "", TheModule);
-    insertValue(Func, FnSignature, ModuleValues);
+    insertValue(Func, FnSignature >> 5, ModuleValues);
+
+    // Flags are not used yet.
+    //unsigned Flags = FnSignature & 31;
 
     // Save this for later so we know type of lazily instantiated functions
     FunctionSignatureList.push_back(Func);
 
     if (Handler) Handler->handleFunctionDeclaration(Func);
 
-    // Get Next function signature
-    if (read_typeid(FnSignature))
-      error("Invalid function type (type type) found");
+    // Get the next function signature.
+    FnSignature = read_vbr_uint();
+    if (hasNoFlagsForFunctions)
+      FnSignature = (FnSignature << 5) + 1;
   }
 
   // Now that the function signature list is set up, reverse it so that we can 
@@ -1929,6 +1957,9 @@
   hasInconsistentBBSlotNums = false;
   hasVBRByteTypes = false;
   hasUnnecessaryModuleBlockId = false;
+  hasNoUndefValue = false;
+  hasNoFlagsForFunctions = false;
+  hasNoUnreachableInst = false;
 
   switch (RevisionNum) {
   case 0:               //  LLVM 1.0, 1.1 (Released)
@@ -1990,24 +2021,41 @@
     // FALL THROUGH
     
   case 4:               // 1.3.1 (Not Released)
-    // In version 4, basic blocks have a minimum index of 0 whereas all the 
+    // In version 4, we did not support the 'undef' constant.
+    hasNoUndefValue = true;
+
+    // In version 4 and above, we did not include space for flags for functions
+    // in the module info block.
+    hasNoFlagsForFunctions = true;
+
+    // In version 4 and above, we did not include the 'unreachable' instruction
+    // in the opcode numbering in the bytecode file.
+    hasNoUnreachableInst = true;
+
+    // FALL THROUGH
+
+  case 5:               // 1.x.x (Not Released)
+    // FIXME: NONE of this is implemented yet!
+    break;
+
+    // In version 5, basic blocks have a minimum index of 0 whereas all the 
     // other primitives have a minimum index of 1 (because 0 is the "null" 
     // value. In version 5, we made this consistent.
     hasInconsistentBBSlotNums = true;
 
-    // In version 4, the types SByte and UByte were encoded as vbr_uint so that
+    // In version 5, the types SByte and UByte were encoded as vbr_uint so that
     // signed values > 63 and unsigned values >127 would be encoded as two
     // bytes. In version 5, they are encoded directly in a single byte.
     hasVBRByteTypes = true;
 
-    // In version 4, modules begin with a "Module Block" which encodes a 4-byte
+    // In version 5, modules begin with a "Module Block" which encodes a 4-byte
     // integer value 0x01 to identify the module block. This is unnecessary and
     // removed in version 5.
     hasUnnecessaryModuleBlockId = true;
 
     // FALL THROUGH
 
-  case 5:              // LLVM 1.4 (Released)
+  case 6:              // LLVM 1.4 (Released)
     break;
   default:
     error("Unknown bytecode version number: " + itostr(RevisionNum));


Index: llvm/lib/Bytecode/Reader/Reader.h
diff -u llvm/lib/Bytecode/Reader/Reader.h:1.14 llvm/lib/Bytecode/Reader/Reader.h:1.15
--- llvm/lib/Bytecode/Reader/Reader.h:1.14	Wed Oct 13 20:49:34 2004
+++ llvm/lib/Bytecode/Reader/Reader.h	Sat Oct 16 13:18:13 2004
@@ -298,17 +298,29 @@
   /// alignment of bytecode fields was done away with completely.
   bool hasAlignment;
 
-  // In version 4, basic blocks have a minimum index of 0 whereas all the 
+  // In version 4 and earlier, the bytecode format did not support the 'undef'
+  // constant.
+  bool hasNoUndefValue;
+
+  // In version 4 and earlier, the bytecode format did not save space for flags
+  // in the global info block for functions.
+  bool hasNoFlagsForFunctions;
+
+  // In version 4 and earlier, there was no opcode space reserved for the
+  // unreachable instruction.
+  bool hasNoUnreachableInst;
+
+  // In version 5, basic blocks have a minimum index of 0 whereas all the 
   // other primitives have a minimum index of 1 (because 0 is the "null" 
   // value. In version 5, we made this consistent.
   bool hasInconsistentBBSlotNums;
 
-  // In version 4, the types SByte and UByte were encoded as vbr_uint so that
+  // In version 5, the types SByte and UByte were encoded as vbr_uint so that
   // signed values > 63 and unsigned values >127 would be encoded as two
   // bytes. In version 5, they are encoded directly in a single byte.
   bool hasVBRByteTypes;
 
-  // In version 4, modules begin with a "Module Block" which encodes a 4-byte
+  // In version 5, modules begin with a "Module Block" which encodes a 4-byte
   // integer value 0x01 to identify the module block. This is unnecessary and
   // removed in version 5.
   bool hasUnnecessaryModuleBlockId;






More information about the llvm-commits mailing list