summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-10-28 23:59:40 +0000
committerChris Lattner <sabre@nondot.org>2009-10-28 23:59:40 +0000
commit6c4d255bf3d64fd2ecb48334e780c87f060f1280 (patch)
treed89f05cd759ed3e4900f018b4a0e546745eb1f43 /clang/lib/CodeGen/CodeGenFunction.cpp
parent48d9995d2ba86daf86396dbe847235fcf492bbbe (diff)
downloadbcm5719-llvm-6c4d255bf3d64fd2ecb48334e780c87f060f1280.tar.gz
bcm5719-llvm-6c4d255bf3d64fd2ecb48334e780c87f060f1280.zip
Implement clang support for indirect branch and address of label
using the new LLVM support for this. This is temporarily hiding behind horrible and ugly #ifdefs until the time when the optimizer is stable (hopefully a week or so). Until then, lets make it "opt in" :) llvm-svn: 85446
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index c6111fac197..88beadf3314 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -27,7 +27,11 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm)
: BlockFunction(cgm, *this, Builder), CGM(cgm),
Target(CGM.getContext().Target),
Builder(cgm.getModule().getContext()),
+#ifndef USEINDIRECTBRANCH
DebugInfo(0), IndirectGotoSwitch(0),
+#else
+ DebugInfo(0), IndirectBranch(0),
+#endif
SwitchInsn(0), CaseRangeBlock(0), InvokeDest(0),
CXXThisDecl(0) {
LLVMIntTy = ConvertType(getContext().IntTy);
@@ -130,10 +134,33 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
EmitFunctionEpilog(*CurFnInfo, ReturnValue);
+#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();
+ }
+
+
+#endif
// Remove the AllocaInsertPt instruction, which is just a convenience for us.
llvm::Instruction *Ptr = AllocaInsertPt;
AllocaInsertPt = 0;
Ptr->eraseFromParent();
+#ifdef USEINDIRECTBRANCH
+
+ // 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.
+ if (IndirectBranch) {
+ llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
+ if (PN->getNumIncomingValues() == 0) {
+ PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
+ PN->eraseFromParent();
+ }
+ }
+
+#endif
}
void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
@@ -466,13 +493,26 @@ void CodeGenFunction::EmitMemSetToZero(llvm::Value *DestPtr, QualType Ty) {
TypeInfo.second/8));
}
+#ifndef USEINDIRECTBRANCH
unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
// Use LabelIDs.size()+1 as the new ID if one hasn't been assigned.
unsigned &Entry = LabelIDs[L];
if (Entry) return Entry;
+#else
+
+llvm::BlockAddress *CodeGenFunction::GetAddrOfLabel(const LabelStmt *L) {
+ // Make sure that there is a block for the indirect goto.
+ if (IndirectBranch == 0)
+ GetIndirectGotoBlock();
+#endif
+#ifndef USEINDIRECTBRANCH
Entry = LabelIDs.size();
+#else
+ llvm::BasicBlock *BB = getBasicBlockForLabel(L);
+#endif
+#ifndef USEINDIRECTBRANCH
// If this is the first "address taken" of a label and the indirect goto has
// already been seen, add this to it.
if (IndirectGotoSwitch) {
@@ -488,19 +528,42 @@ unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) {
}
return Entry;
+#else
+ // Make sure the indirect branch includes all of the address-taken blocks.
+ IndirectBranch->addDestination(BB);
+ return llvm::BlockAddress::get(CurFn, BB);
+#endif
}
llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
+#ifndef USEINDIRECTBRANCH
// If we already made the switch stmt for indirect goto, return its block.
if (IndirectGotoSwitch) return IndirectGotoSwitch->getParent();
+#else
+ // If we already made the indirect branch for indirect goto, return its block.
+ if (IndirectBranch) return IndirectBranch->getParent();
+#endif
+#ifndef USEINDIRECTBRANCH
EmitBlock(createBasicBlock("indirectgoto"));
+#else
+ CGBuilderTy TmpBuilder(createBasicBlock("indirectgoto"));
+#endif
+#ifndef USEINDIRECTBRANCH
const llvm::IntegerType *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+#else
+ const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
+#endif
// Create the PHI node that indirect gotos will add entries to.
+#ifndef USEINDIRECTBRANCH
llvm::Value *DestVal = Builder.CreatePHI(Int32Ty, "indirect.goto.dest");
+#else
+ llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, "indirect.goto.dest");
+#endif
+#ifndef USEINDIRECTBRANCH
// Create the switch instruction. For now, set the insert block to this block
// which will be fixed as labels are added.
IndirectGotoSwitch = Builder.CreateSwitch(DestVal, Builder.GetInsertBlock());
@@ -540,6 +603,11 @@ llvm::BasicBlock *CodeGenFunction::GetIndirectGotoBlock() {
}
return IndirectGotoSwitch->getParent();
+#else
+ // Create the indirect branch instruction.
+ IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
+ return IndirectBranch->getParent();
+#endif
}
llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) {
OpenPOWER on IntegriCloud