[llvm-commits] [llvm] r85377 - in /llvm/trunk: lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Reader/BitcodeReader.h test/Feature/terminators.ll

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


Author: lattner
Date: Wed Oct 28 00:53:48 2009
New Revision: 85377

URL: http://llvm.org/viewvc/llvm-project?rev=85377&view=rev
Log:
add bitcode reader support for blockaddress.  We can now fully
round trip blockaddress through .ll and .bc files, so add a testcase.

There are still a bunch of places in the optimizer and other places
that need to be updated to work with these constructs, but at least
the basics are in now.

Modified:
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h
    llvm/trunk/test/Feature/terminators.ll

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

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Wed Oct 28 00:53:48 2009
@@ -1192,6 +1192,22 @@
                          AsmStr, ConstrStr, HasSideEffects, IsAlignStack);
       break;
     }
+    case bitc::CST_CODE_BLOCKADDRESS:{
+      if (Record.size() < 3) return Error("Invalid CE_BLOCKADDRESS record");
+      const Type *FnTy = getTypeByID(Record[0]);
+      if (FnTy == 0) return Error("Invalid CE_BLOCKADDRESS record");
+      Function *Fn =
+        dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy));
+      if (Fn == 0) return Error("Invalid CE_BLOCKADDRESS record");
+      
+      GlobalVariable *FwdRef = new GlobalVariable(*Fn->getParent(),
+                                                  Type::getInt8Ty(Context),
+                                            false, GlobalValue::InternalLinkage,
+                                                  0, "");
+      BlockAddrFwdRefs[Fn].push_back(std::make_pair(Record[2], FwdRef));
+      V = FwdRef;
+      break;
+    }  
     }
 
     ValueList.AssignValue(V, NextCstNo);
@@ -2248,6 +2264,27 @@
     }
   }
 
+  // See if anything took the address of blocks in this function.  If so,
+  // resolve them now.
+  /// BlockAddrFwdRefs - These are blockaddr references to basic blocks.  These
+  /// are resolved lazily when functions are loaded.
+  DenseMap<Function*, std::vector<BlockAddrRefTy> >::iterator BAFRI =
+    BlockAddrFwdRefs.find(F);
+  if (BAFRI != BlockAddrFwdRefs.end()) {
+    std::vector<BlockAddrRefTy> &RefList = BAFRI->second;
+    for (unsigned i = 0, e = RefList.size(); i != e; ++i) {
+      unsigned BlockIdx = RefList[i].first;
+      if (BlockIdx >= FunctionBBs.size())
+        return Error("Invalid blockaddress block #");
+    
+      GlobalVariable *FwdRef = RefList[i].second;
+      FwdRef->replaceAllUsesWith(BlockAddress::get(F, FunctionBBs[BlockIdx]));
+      FwdRef->eraseFromParent();
+    }
+    
+    BlockAddrFwdRefs.erase(BAFRI);
+  }
+  
   // Trim the value list down to the size it was before we parsed this function.
   ValueList.shrinkTo(ModuleValueListSize);
   std::vector<BasicBlock*>().swap(FunctionBBs);

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

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Wed Oct 28 00:53:48 2009
@@ -94,7 +94,7 @@
 class BitcodeReaderMDValueList {
   std::vector<WeakVH> MDValuePtrs;
   
-  LLVMContext& Context;
+  LLVMContext &Context;
 public:
   BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {}
 
@@ -122,7 +122,7 @@
 };
 
 class BitcodeReader : public ModuleProvider {
-  LLVMContext& Context;
+  LLVMContext &Context;
   MemoryBuffer *Buffer;
   BitstreamReader StreamFile;
   BitstreamCursor Stream;
@@ -163,6 +163,12 @@
   /// map contains info about where to find deferred function body (in the
   /// stream) and what linkage the original function had.
   DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo;
+  
+  /// BlockAddrFwdRefs - These are blockaddr references to basic blocks.  These
+  /// are resolved lazily when functions are loaded.
+  typedef std::pair<unsigned, GlobalVariable*> BlockAddrRefTy;
+  DenseMap<Function*, std::vector<BlockAddrRefTy> > BlockAddrFwdRefs;
+  
 public:
   explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext& C)
     : Context(C), Buffer(buffer), ErrorString(0), ValueList(C), MDValueList(C) {

Modified: llvm/trunk/test/Feature/terminators.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/terminators.ll?rev=85377&r1=85376&r2=85377&view=diff

==============================================================================
--- llvm/trunk/test/Feature/terminators.ll (original)
+++ llvm/trunk/test/Feature/terminators.ll Wed Oct 28 00:53:48 2009
@@ -25,13 +25,19 @@
 }
 
 
+ at Addr = global i8* blockaddress(@indbrtest, %BB1)
+ at Addr3 = global i8* blockaddress(@squared, %Case1)
+
 
 define i32 @indbrtest(i8* %P, i32* %Q) {
   indirectbr i8* %P, [label %BB1, label %BB2, label %BB3]
 BB1:
   indirectbr i32* %Q, []
 BB2:
-  indirectbr i32* %Q, [label %BB1, label %BB2]
+  %R = bitcast i8* blockaddress(@indbrtest, %BB3) to i8*
+  indirectbr i8* %R, [label %BB1, label %BB2, label %BB3]
 BB3:
   ret i32 2
 }
+
+





More information about the llvm-commits mailing list