[llvm-commits] [llvm] r85376 - in /llvm/trunk: include/llvm/Bitcode/LLVMBitCodes.h lib/Bitcode/Writer/BitcodeWriter.cpp lib/Bitcode/Writer/ValueEnumerator.cpp lib/Bitcode/Writer/ValueEnumerator.h

Chris Lattner sabre at nondot.org
Tue Oct 27 22:24:48 PDT 2009


Author: lattner
Date: Wed Oct 28 00:24:40 2009
New Revision: 85376

URL: http://llvm.org/viewvc/llvm-project?rev=85376&view=rev
Log:
bitcode writer support for blockaddress.

Modified:
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
    llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=85376&r1=85375&r2=85376&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Wed Oct 28 00:24:40 2009
@@ -138,7 +138,8 @@
     CST_CODE_CE_CMP        = 17,  // CE_CMP:        [opty, opval, opval, pred]
     CST_CODE_INLINEASM     = 18,  // INLINEASM:     [sideeffect,asmstr,conststr]
     CST_CODE_CE_SHUFVEC_EX = 19,  // SHUFVEC_EX:    [opty, opval, opval, opval]
-    CST_CODE_CE_INBOUNDS_GEP = 20 // INBOUNDS_GEP:  [n x operands]
+    CST_CODE_CE_INBOUNDS_GEP = 20,// INBOUNDS_GEP:  [n x operands]
+    CST_CODE_BLOCKADDRESS  = 21   // CST_CODE_BLOCKADDRESS [fnty, fnval, bb#]
   };
 
   /// CastOpcodes - These are values used in the bitcode files to encode which

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=85376&r1=85375&r2=85376&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Wed Oct 28 00:24:40 2009
@@ -853,6 +853,13 @@
         Record.push_back(CE->getPredicate());
         break;
       }
+    } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
+      assert(BA->getFunction() == BA->getBasicBlock()->getParent() &&
+             "Malformed blockaddress");
+      Code = bitc::CST_CODE_BLOCKADDRESS;
+      Record.push_back(VE.getTypeID(BA->getFunction()->getType()));
+      Record.push_back(VE.getValueID(BA->getFunction()));
+      Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock()));
     } else {
       llvm_unreachable("Unknown constant!");
     }

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=85376&r1=85375&r2=85376&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Wed Oct 28 00:24:40 2009
@@ -223,7 +223,9 @@
         EnumerateType(Type::getVoidTy(MD->getContext()));
     }
     return;
-  } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(MD)) {
+  }
+  
+  if (const NamedMDNode *N = dyn_cast<NamedMDNode>(MD)) {
     for(NamedMDNode::const_elem_iterator I = N->elem_begin(),
           E = N->elem_end(); I != E; ++I) {
       MetadataBase *M = *I;
@@ -274,7 +276,8 @@
       // graph that don't go through a global variable.
       for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
            I != E; ++I)
-        EnumerateValue(*I);
+        if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress.
+          EnumerateValue(*I);
 
       // Finally, add the value.  Doing this could make the ValueID reference be
       // dangling, don't reuse it.
@@ -320,15 +323,20 @@
 
     // This constant may have operands, make sure to enumerate the types in
     // them.
-    for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
-      EnumerateOperandType(C->getOperand(i));
+    for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+      const User *Op = C->getOperand(i);
+      
+      // Don't enumerate basic blocks here, this happens as operands to
+      // blockaddress.
+      if (isa<BasicBlock>(Op)) continue;
+      
+      EnumerateOperandType(cast<Constant>(Op));
+    }
 
     if (const MDNode *N = dyn_cast<MDNode>(V)) {
-      for (unsigned i = 0, e = N->getNumElements(); i != e; ++i) {
-        Value *Elem = N->getElement(i);
-        if (Elem)
+      for (unsigned i = 0, e = N->getNumElements(); i != e; ++i)
+        if (Value *Elem = N->getElement(i))
           EnumerateOperandType(Elem);
-      }
     }
   } else if (isa<MDString>(V) || isa<MDNode>(V))
     EnumerateValue(V);
@@ -397,3 +405,23 @@
   Values.resize(NumModuleValues);
   BasicBlocks.clear();
 }
+
+static void IncorporateFunctionInfoGlobalBBIDs(const Function *F,
+                                 DenseMap<const BasicBlock*, unsigned> &IDMap) {
+  unsigned Counter = 0;
+  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+    IDMap[BB] = ++Counter;
+}
+
+/// getGlobalBasicBlockID - This returns the function-specific ID for the
+/// specified basic block.  This is relatively expensive information, so it
+/// should only be used by rare constructs such as address-of-label.
+unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const {
+  unsigned &Idx = GlobalBasicBlockIDs[BB];
+  if (Idx != 0)
+    return Idx-1;
+
+  IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs);
+  return getGlobalBasicBlockID(BB);
+}
+

Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h?rev=85376&r1=85375&r2=85376&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h (original)
+++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.h Wed Oct 28 00:24:40 2009
@@ -53,6 +53,10 @@
   AttributeMapType AttributeMap;
   std::vector<AttrListPtr> Attributes;
   
+  /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by
+  /// the "getGlobalBasicBlockID" method.
+  mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs;
+  
   typedef DenseMap<const Instruction*, unsigned> InstructionMapType;
   InstructionMapType InstructionMap;
   unsigned InstructionCount;
@@ -106,6 +110,11 @@
   const std::vector<AttrListPtr> &getAttributes() const {
     return Attributes;
   }
+  
+  /// getGlobalBasicBlockID - This returns the function-specific ID for the
+  /// specified basic block.  This is relatively expensive information, so it
+  /// should only be used by rare constructs such as address-of-label.
+  unsigned getGlobalBasicBlockID(const BasicBlock *BB) const;
 
   /// incorporateFunction/purgeFunction - If you'd like to deal with a function,
   /// use these two methods to get its data into the ValueEnumerator!





More information about the llvm-commits mailing list