[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