aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmt.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/CGStmt.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/CGStmt.cpp')
-rw-r--r--lib/CodeGen/CGStmt.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 9743c7cadf..a5cf946ea6 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -62,6 +62,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
case Stmt::CompoundStmtClass: EmitCompoundStmt(cast<CompoundStmt>(*S)); break;
case Stmt::LabelStmtClass: EmitLabelStmt(cast<LabelStmt>(*S)); break;
case Stmt::GotoStmtClass: EmitGotoStmt(cast<GotoStmt>(*S)); break;
+ case Stmt::IndirectGotoStmtClass:
+ EmitIndirectGotoStmt(cast<IndirectGotoStmt>(*S)); break;
case Stmt::IfStmtClass: EmitIfStmt(cast<IfStmt>(*S)); break;
case Stmt::WhileStmtClass: EmitWhileStmt(cast<WhileStmt>(*S)); break;
@@ -157,7 +159,25 @@ void CodeGenFunction::EmitGotoStmt(const GotoStmt &S) {
Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
}
+void CodeGenFunction::EmitIndirectGotoStmt(const IndirectGotoStmt &S) {
+ // Emit initial switch which will be patched up later by
+ // EmitIndirectSwitches(). We need a default dest, so we use the
+ // current BB, but this is overwritten.
+ llvm::Value *V = Builder.CreatePtrToInt(EmitScalarExpr(S.getTarget()),
+ llvm::Type::Int32Ty,
+ "addr");
+ llvm::SwitchInst *I = Builder.CreateSwitch(V, Builder.GetInsertBlock());
+ IndirectSwitches.push_back(I);
+
+ // Emit a block after the branch so that dead code after a goto has some place
+ // to go.
+ Builder.SetInsertPoint(llvm::BasicBlock::Create("", CurFn));
+}
+
void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
+ // FIXME: It would probably be nice for us to skip emission of if
+ // (0) code here.
+
// C99 6.8.4.1: The first substatement is executed if the expression compares
// unequal to 0. The condition must be a scalar type.
llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());