From 0ffb125996336fc7602b162c0a9e392f1a93060f Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 4 Aug 2008 16:51:22 +0000 Subject: Add CodeGen support for indirect goto. - Follows emission scheme used by llvm-gcc, i.e. invent an id for each label whose address is taken and replace each indirect goto by a switch to each possible target. - Currently we emit a switch for each indirect goto instead of merging them as llvm-gcc does. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54318 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenFunction.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/CodeGenFunction.cpp') diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index e153ad9fd8..9814ae7137 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -68,7 +68,10 @@ bool CodeGenFunction::hasAggregateLLVMType(QualType T) { void CodeGenFunction::GenerateFunction(const Stmt *Body) { // Emit the function body. EmitStmt(Body); - + + // Finish emission of indirect switches. + EmitIndirectSwitches(); + // Emit debug descriptor for function end. CGDebugInfo *DI = CGM.getDebugInfo(); if (DI) { @@ -179,3 +182,33 @@ void CodeGenFunction::WarnUnsupported(const Stmt *S, const char *Type) { CGM.WarnUnsupported(S, Type); } +unsigned CodeGenFunction::GetIDForAddrOfLabel(const LabelStmt *L) { + // Use LabelIDs.size() as the new ID if one hasn't been assigned. + return LabelIDs.insert(std::make_pair(L, LabelIDs.size())).first->second; +} + +void CodeGenFunction::EmitIndirectSwitches() { + llvm::BasicBlock *Default; + + if (!LabelIDs.empty()) { + Default = getBasicBlockForLabel(LabelIDs.begin()->first); + } else { + // No possible targets for indirect goto, just emit an infinite + // loop. + Default = llvm::BasicBlock::Create("indirectgoto.loop", CurFn); + llvm::BranchInst::Create(Default, Default); + } + + for (std::vector::iterator i = IndirectSwitches.begin(), + e = IndirectSwitches.end(); i != e; ++i) { + llvm::SwitchInst *I = *i; + + I->setSuccessor(0, Default); + for (std::map::iterator LI = LabelIDs.begin(), + LE = LabelIDs.end(); LI != LE; ++LI) { + I->addCase(llvm::ConstantInt::get(llvm::Type::Int32Ty, + LI->second), + getBasicBlockForLabel(LI->first)); + } + } +} -- cgit v1.2.3-18-g5258