[llvm-commits] [dragonegg] r85525 - in /dragonegg/trunk: llvm-convert.cpp llvm-internal.h

Duncan Sands baldrick at free.fr
Thu Oct 29 13:28:58 PDT 2009


Author: baldrick
Date: Thu Oct 29 15:28:58 2009
New Revision: 85525

URL: http://llvm.org/viewvc/llvm-project?rev=85525&view=rev
Log:
Implement indirect gotos using the new indirect branch instruction.
The previous implementation with a switch in an artificial block
didn't interact properly with phi node generation, so just delete
the old code - now the compiler crashes because indirectbr is not
fully implemented, while before it would crash because of not being
able to find incoming values for phi nodes.  This is progress since
getting it working is now no longer my problem!

Modified:
    dragonegg/trunk/llvm-convert.cpp
    dragonegg/trunk/llvm-internal.h

Modified: dragonegg/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-convert.cpp?rev=85525&r1=85524&r2=85525&view=diff

==============================================================================
--- dragonegg/trunk/llvm-convert.cpp (original)
+++ dragonegg/trunk/llvm-convert.cpp Thu Oct 29 15:28:58 2009
@@ -241,9 +241,6 @@
   FuncEHSelector = 0;
   FuncEHGetTypeID = 0;
 
-  NumAddressTakenBlocks = 0;
-  IndirectGotoBlock = 0;
-
   assert(TheTreeToLLVM == 0 && "Reentering function creation?");
   TheTreeToLLVM = this;
 }
@@ -946,18 +943,6 @@
   EmitPostPads();
   EmitUnwindBlock();
 
-  // If this function takes the address of a label, emit the indirect goto
-  // block.
-  if (IndirectGotoBlock) {
-    EmitBlock(IndirectGotoBlock);
-
-    // Change the default destination to go to one of the other destinations, if
-    // there is any other dest.
-    SwitchInst *SI = cast<SwitchInst>(IndirectGotoBlock->getTerminator());
-    if (SI->getNumSuccessors() > 1)
-      SI->setSuccessor(0, SI->getSuccessor(1));
-  }
-
   // Populate phi nodes with their operands now that all ssa names have been
   // defined and all basic blocks output.
   PopulatePhiNodes();
@@ -1284,8 +1269,7 @@
 
   // Constants.
   case LABEL_DECL: {
-    Value *Ptr = TreeConstantToLLVM::EmitLV_LABEL_DECL(exp);
-    LV = LValue(Ptr, 1);
+    LV = LValue(EmitLV_LABEL_DECL(exp), 1);
     break;
   }
   case COMPLEX_CST: {
@@ -1850,43 +1834,6 @@
   }
 }
 
-//===----------------------------------------------------------------------===//
-//                ... Address Of Labels Extension Support ...
-//===----------------------------------------------------------------------===//
-
-/// getIndirectGotoBlockNumber - Return the unique ID of the specified basic
-/// block for uses that take the address of it.
-Constant *TreeToLLVM::getIndirectGotoBlockNumber(BasicBlock *BB) {
-  ConstantInt *&Val = AddressTakenBBNumbers[BB];
-  if (Val) return Val;
-
-  // Assign the new ID, update AddressTakenBBNumbers to remember it.
-  uint64_t BlockNo = ++NumAddressTakenBlocks;
-  BlockNo &= ~0ULL >> (64-TD.getPointerSizeInBits());
-  Val = ConstantInt::get(TD.getIntPtrType(Context), BlockNo);
-
-  // Add it to the switch statement in the indirect goto block.
-  cast<SwitchInst>(getIndirectGotoBlock()->getTerminator())->addCase(Val, BB);
-  return Val;
-}
-
-/// getIndirectGotoBlock - Get (and potentially lazily create) the indirect
-/// goto block.
-BasicBlock *TreeToLLVM::getIndirectGotoBlock() {
-  if (IndirectGotoBlock) return IndirectGotoBlock;
-
-  // Create a temporary for the value to be switched on.
-  IndirectGotoValue = CreateTemporary(TD.getIntPtrType(Context));
-
-  // Create the block, emit a load, and emit the switch in the block.
-  IndirectGotoBlock = BasicBlock::Create(Context, "indirectgoto");
-  Value *Ld = new LoadInst(IndirectGotoValue, "gotodest", IndirectGotoBlock);
-  SwitchInst::Create(Ld, IndirectGotoBlock, 0, IndirectGotoBlock);
-
-  // Finally, return it.
-  return IndirectGotoBlock;
-}
-
 
 //===----------------------------------------------------------------------===//
 //                           ... Control Flow ...
@@ -6362,6 +6309,12 @@
   return LValue(Temp, 1);
 }
 
+Constant *TreeToLLVM::EmitLV_LABEL_DECL(tree exp) {
+  // GCC kindly diverts labels for unreachable basic blocks to reachable blocks,
+  // so we are not obliged to output unreachable blocks even if the original
+  // code took the address of one.
+  return BlockAddress::get(Fn, getLabelDeclBlock(exp));
+}
 
 //===----------------------------------------------------------------------===//
 //                      ... Convert GIMPLE to LLVM ...
@@ -6861,16 +6814,16 @@
     return;
   }
 
-  // Otherwise we have an indirect goto.
-  BasicBlock *DestBB = getIndirectGotoBlock();
+  // Indirect branch.
+  basic_block source = gimple_bb(stmt);
+  IndirectBrInst *Br = Builder.CreateIndirectBr(EmitGimpleReg(dest),
+                                                EDGE_COUNT(source->succs));
 
-  // Store the destination block to the GotoValue alloca.
-  Value *V = Builder.CreatePtrToInt(Emit(dest, 0), TD.getIntPtrType(Context));
-  Builder.CreateStore(V, IndirectGotoValue);
-
-  // FIXME: This is HORRIBLY INCORRECT in the presence of exception handlers.
-  // There should be one collector block per cleanup level!
-  Builder.CreateBr(DestBB);
+  // Add the list of possible destinations.
+  edge e;
+  edge_iterator ei;
+  FOR_EACH_EDGE (e, ei, source->succs)
+    Br->addDestination(getBasicBlock(e->dest));
 }
 
 void TreeToLLVM::RenderGIMPLE_RESX(gimple stmt) {
@@ -8071,10 +8024,7 @@
            "Taking the address of a label that isn't in the current fn!?");
   }
 
-  BasicBlock *BB = TheTreeToLLVM->getLabelDeclBlock(exp);
-  Constant *C = TheTreeToLLVM->getIndirectGotoBlockNumber(BB);
-  return
-       TheFolder->CreateIntToPtr(C, Type::getInt8PtrTy(Context));
+  return TheTreeToLLVM->EmitLV_LABEL_DECL(exp);
 }
 
 Constant *TreeConstantToLLVM::EmitLV_COMPLEX_CST(tree exp) {

Modified: dragonegg/trunk/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-internal.h?rev=85525&r1=85524&r2=85525&view=diff

==============================================================================
--- dragonegg/trunk/llvm-internal.h (original)
+++ dragonegg/trunk/llvm-internal.h Thu Oct 29 15:28:58 2009
@@ -413,22 +413,6 @@
   /// FuncEHGetTypeID - Function used to return type id for give typeinfo.
   Function *FuncEHGetTypeID;
 
-  /// NumAddressTakenBlocks - Count the number of labels whose addresses are
-  /// taken.
-  uint64_t NumAddressTakenBlocks;
-
-  /// AddressTakenBBNumbers - For each label with its address taken, we keep 
-  /// track of its unique ID.
-  std::map<BasicBlock*, ConstantInt*> AddressTakenBBNumbers;
-  
-  /// IndirectGotoBlock - If non-null, the block that indirect goto's in this
-  /// function branch to.
-  BasicBlock *IndirectGotoBlock;
-  
-  /// IndirectGotoValue - This is set to be the alloca temporary that the
-  /// indirect goto block switches on.
-  Value *IndirectGotoValue;
-  
 public:
   TreeToLLVM(tree_node *fndecl);
   ~TreeToLLVM();
@@ -447,14 +431,6 @@
   /// the address of the result.
   LValue EmitLV(tree_node *exp);
 
-  /// getIndirectGotoBlockNumber - Return the unique ID of the specified basic
-  /// block for uses that take the address of it.
-  Constant *getIndirectGotoBlockNumber(BasicBlock *BB);
-  
-  /// getIndirectGotoBlock - Get (and potentially lazily create) the indirect
-  /// goto block.
-  BasicBlock *getIndirectGotoBlock();
-  
   void TODO(tree_node *exp = 0);
 
   /// CastToAnyType - Cast the specified value to the specified type regardless
@@ -504,12 +480,10 @@
   /// getBasicBlock - Find or create the LLVM basic block corresponding to BB.
   BasicBlock *getBasicBlock(basic_block bb);
 
-public:
   /// getLabelDeclBlock - Lazily get and create a basic block for the specified
   /// label.
   BasicBlock *getLabelDeclBlock(tree_node *LabelDecl);
 
-private:
   /// EmitSSA_NAME - Return the defining value of the given SSA_NAME.
   /// Only creates code in the entry block.
   Value *EmitSSA_NAME(tree_node *reg);
@@ -734,6 +708,10 @@
                             Value *&Result,
                             const Type *ResultType,
                             std::vector<Value*> &Ops);
+
+public:
+  // Helper for taking the address of a label.
+  Constant *EmitLV_LABEL_DECL(tree_node *exp);
 };
 
 /// TreeConstantToLLVM - An instance of this class is created and used to 





More information about the llvm-commits mailing list