aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-08-04 16:51:22 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-08-04 16:51:22 +0000
commit0ffb125996336fc7602b162c0a9e392f1a93060f (patch)
tree69ebef4f15bf86bc743f22e598ae9d6a9b87cd39 /lib/CodeGen/CodeGenFunction.cpp
parentc63a1f276f7b324fd9a4be82098b1c8f7bf30733 (diff)
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
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp35
1 files changed, 34 insertions, 1 deletions
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<llvm::SwitchInst*>::iterator i = IndirectSwitches.begin(),
+ e = IndirectSwitches.end(); i != e; ++i) {
+ llvm::SwitchInst *I = *i;
+
+ I->setSuccessor(0, Default);
+ for (std::map<const LabelStmt*,unsigned>::iterator LI = LabelIDs.begin(),
+ LE = LabelIDs.end(); LI != LE; ++LI) {
+ I->addCase(llvm::ConstantInt::get(llvm::Type::Int32Ty,
+ LI->second),
+ getBasicBlockForLabel(LI->first));
+ }
+ }
+}