diff options
author | Chris Lattner <sabre@nondot.org> | 2009-10-28 23:59:40 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-10-28 23:59:40 +0000 |
commit | 6c4d255bf3d64fd2ecb48334e780c87f060f1280 (patch) | |
tree | d89f05cd759ed3e4900f018b4a0e546745eb1f43 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 48d9995d2ba86daf86396dbe847235fcf492bbbe (diff) | |
download | bcm5719-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.cpp | 68 |
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) { |