[llvm-commits] [llvm-gcc-4.2] r85513 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h

Bob Wilson bob.wilson at apple.com
Thu Oct 29 10:33:29 PDT 2009


Author: bwilson
Date: Thu Oct 29 12:33:28 2009
New Revision: 85513

URL: http://llvm.org/viewvc/llvm-project?rev=85513&view=rev
Log:
Add front-end support for indirect branch.  This is mostly copied from
the corresponding code that Chris wrote for clang.  For now, this is still
disabled by default; compile with USEINDIRECTBRANCH defined to enable it.

Modified:
    llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
    llvm-gcc-4.2/trunk/gcc/llvm-internal.h

Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=85513&r1=85512&r2=85513&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Oct 29 12:33:28 2009
@@ -181,8 +181,12 @@
   FuncEHSelector = 0;
   FuncEHGetTypeID = 0;
 
+#ifdef USEINDIRECTBRANCH
+  IndirectBranch = 0;
+#else
   NumAddressTakenBlocks = 0;
   IndirectGotoBlock = 0;
+#endif
 
   assert(TheTreeToLLVM == 0 && "Reentering function creation?");
   TheTreeToLLVM = this;
@@ -726,6 +730,22 @@
   EmitPostPads();
   EmitUnwindBlock();
 
+#ifdef USEINDIRECTBRANCH
+  // If someone did an indirect goto, emit the indirect goto block at the end of
+  // the function.
+  if (IndirectBranch) {
+    EmitBlock(IndirectBranch->getParent());
+    Builder.ClearInsertionPoint();
+
+    // If someone took the address of a label but never did an indirect goto,
+    // we made a zero entry PHI node, which is illegal.  Zap it now.
+    PHINode *PN = cast<PHINode>(IndirectBranch->getAddress());
+    if (PN->getNumIncomingValues() == 0) {
+      PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
+      PN->eraseFromParent();
+    }
+  }
+#else
   // If this function takes the address of a label, emit the indirect goto
   // block.
   if (IndirectGotoBlock) {
@@ -737,6 +757,7 @@
     if (SI->getNumSuccessors() > 1)
       SI->setSuccessor(0, SI->getSuccessor(1));
   }
+#endif
 
   // Remove any cached LLVM values that are local to this function.  Such values
   // may be deleted when the optimizers run, so would be dangerous to keep.
@@ -1685,6 +1706,19 @@
 //                ... Address Of Labels Extension Support ...
 //===----------------------------------------------------------------------===//
 
+#ifdef USEINDIRECTBRANCH
+/// getBlockAddress - Create a BlockAddress and add it as a possible
+/// destination of the IndirectBranch.
+BlockAddress *TreeToLLVM::getBlockAddress(BasicBlock *BB) {
+  // Make sure that there is a block for the indirect goto.
+  if (IndirectBranch == 0)
+    getIndirectGotoBlock();
+
+  // Make sure the indirect branch includes all of the address-taken blocks.
+  IndirectBranch->addDestination(BB);
+  return BlockAddress::get(Fn, BB);
+}
+#else
 /// getIndirectGotoBlockNumber - Return the unique ID of the specified basic
 /// block for uses that take the address of it.
 Constant *TreeToLLVM::getIndirectGotoBlockNumber(BasicBlock *BB) {
@@ -1700,10 +1734,26 @@
   cast<SwitchInst>(getIndirectGotoBlock()->getTerminator())->addCase(Val, BB);
   return Val;
 }
+#endif
 
 /// getIndirectGotoBlock - Get (and potentially lazily create) the indirect
 /// goto block.
 BasicBlock *TreeToLLVM::getIndirectGotoBlock() {
+#ifdef USEINDIRECTBRANCH
+  // If we already made the indirect branch for indirect goto, return its block.
+  if (IndirectBranch) return IndirectBranch->getParent();
+
+  BasicBlock *IndirectGotoBlock = BasicBlock::Create(Context, "indirectgoto");
+  LLVMBuilder TmpBuilder(IndirectGotoBlock, *TheFolder);
+  const Type *Int8PtrTy = Type::getInt8PtrTy(Context);
+
+  // Create the PHI node that indirect gotos will add entries to.
+  Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
+
+  // Create the indirect branch instruction.
+  IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
+  return IndirectBranch->getParent();
+#else
   if (IndirectGotoBlock) return IndirectGotoBlock;
 
   // Create a temporary for the value to be switched on.
@@ -1716,6 +1766,7 @@
 
   // Finally, return it.
   return IndirectGotoBlock;
+#endif
 }
 
 
@@ -1739,10 +1790,18 @@
     // Otherwise we have an indirect goto.
     BasicBlock *DestBB = getIndirectGotoBlock();
 
+#ifdef USEINDIRECTBRANCH
+    Value *V = Emit(TREE_OPERAND(exp, 0), 0);
+    V = Builder.CreateBitCast(V, Type::getInt8PtrTy(Context));
+    // The first instruction in the indirect goto block has to be the PHI for
+    // the indirect branch address; add an entry for this branch.
+    cast<PHINode>(DestBB->begin())->addIncoming(V, Builder.GetInsertBlock());
+#else
     // Store the destination block to the GotoValue alloca.
     Value *V = Emit(TREE_OPERAND(exp, 0), 0);
     V = CastToType(Instruction::PtrToInt, V, TD.getIntPtrType(Context));
     Builder.CreateStore(V, IndirectGotoValue);
+#endif
 
     // NOTE: This is HORRIBLY INCORRECT in the presence of exception handlers.
     // There should be one collector block per cleanup level!  Note that
@@ -7994,9 +8053,13 @@
   }
 
   BasicBlock *BB = getLabelDeclBlock(exp);
+#ifdef USEINDIRECTBRANCH
+  Constant *Ptr = TheTreeToLLVM->getBlockAddress(BB);
+  return TheFolder->CreateBitCast(Ptr, Type::getInt8PtrTy(Context));
+#else
   Constant *C = TheTreeToLLVM->getIndirectGotoBlockNumber(BB);
-  return
-       TheFolder->CreateIntToPtr(C, Type::getInt8PtrTy(Context));
+  return TheFolder->CreateIntToPtr(C, Type::getInt8PtrTy(Context));
+#endif
 }
 
 Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) {

Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=85513&r1=85512&r2=85513&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Thu Oct 29 12:33:28 2009
@@ -331,6 +331,13 @@
   /// FuncEHGetTypeID - Function used to return type id for give typeinfo.
   Function *FuncEHGetTypeID;
 
+#ifdef USEINDIRECTBRANCH
+  /// IndirectBranch - The first time an indirect goto is seen we create a
+  /// block with an indirect branch.  Every time we see the address of a label
+  /// taken, we add the label to the indirect goto.  Every subsequent indirect
+  /// goto is codegen'd as a jump to the IndirectBranch's basic block.
+  IndirectBrInst *IndirectBranch;
+#else
   /// NumAddressTakenBlocks - Count the number of labels whose addresses are
   /// taken.
   uint64_t NumAddressTakenBlocks;
@@ -346,6 +353,7 @@
   /// IndirectGotoValue - This is set to be the alloca temporary that the
   /// indirect goto block switches on.
   Value *IndirectGotoValue;
+#endif
   
 public:
   TreeToLLVM(tree_node *fndecl);
@@ -362,9 +370,15 @@
   /// the address of the result.
   LValue EmitLV(tree_node *exp);
 
+#ifdef USEINDIRECTBRANCH
+  /// getBlockAddress - Create a BlockAddress and add it as a possible
+  /// destination of the IndirectBranch.
+  BlockAddress *getBlockAddress(BasicBlock *BB);
+#else
   /// getIndirectGotoBlockNumber - Return the unique ID of the specified basic
   /// block for uses that take the address of it.
   Constant *getIndirectGotoBlockNumber(BasicBlock *BB);
+#endif
   
   /// getIndirectGotoBlock - Get (and potentially lazily create) the indirect
   /// goto block.





More information about the llvm-commits mailing list