[cfe-commits] r59118 - in /cfe/trunk/lib/CodeGen: CGStmt.cpp CodeGenFunction.h
Daniel Dunbar
daniel at zuster.org
Wed Nov 12 00:21:33 PST 2008
Author: ddunbar
Date: Wed Nov 12 02:21:33 2008
New Revision: 59118
URL: http://llvm.org/viewvc/llvm-project?rev=59118&view=rev
Log:
IRgen improvements on unreachable code:
- Split out "simple" statements which can easily handle IR generation
when there is no insert point. These are generally statements which
start by emitting a new block or are only containers for other
statements.
- This fixes a regression in emitting dummy blocks, notably for case
statements.
- This also fixes spurious emission of a number of debug stoppoint
intrinsic instructions.
Remove unneeded sw.body block, just clear the insertion point.
Lift out CodeGenFunction::EmitStopPoint which calls into the
CGDebugInfo class when generating debug info.
Normalize definitions of Emit{Break,Continue}Stmt and usage of
ErrorUnsupported.
Modified:
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=59118&r1=59117&r2=59118&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Nov 12 02:21:33 2008
@@ -25,9 +25,21 @@
// Statement Emission
//===----------------------------------------------------------------------===//
+void CodeGenFunction::EmitStopPoint(const Stmt *S) {
+ if (CGDebugInfo *DI = CGM.getDebugInfo()) {
+ DI->setLocation(S->getLocStart());
+ DI->EmitStopPoint(CurFn, Builder);
+ }
+}
+
void CodeGenFunction::EmitStmt(const Stmt *S) {
assert(S && "Null statement?");
+ // Check if we can handle this without bothering to generate an
+ // insert point or debug info.
+ if (EmitSimpleStmt(S))
+ return;
+
// If we happen to be at an unreachable point just create a dummy
// basic block to hold the code. We could change parts of irgen to
// simply not generate this code, but this situation is rare and
@@ -35,14 +47,8 @@
// FIXME: Verify previous performance/effort claim.
EnsureInsertPoint();
- // Generate stoppoints if we are emitting debug info.
- // Beginning of a Compound Statement (e.g. an opening '{') does not produce
- // executable code. So do not generate a stoppoint for that.
- CGDebugInfo *DI = CGM.getDebugInfo();
- if (DI && S->getStmtClass() != Stmt::CompoundStmtClass) {
- DI->setLocation(S->getLocStart());
- DI->EmitStopPoint(CurFn, Builder);
- }
+ // Generate a stoppoint if we are emitting debug info.
+ EmitStopPoint(S);
switch (S->getStmtClass()) {
default:
@@ -59,10 +65,6 @@
ErrorUnsupported(S, "statement");
}
break;
- case Stmt::NullStmtClass: break;
- 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;
@@ -73,28 +75,8 @@
case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
case Stmt::DeclStmtClass: EmitDeclStmt(cast<DeclStmt>(*S)); break;
-
- case Stmt::BreakStmtClass:
- // FIXME: Implement break in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
- return;
- }
- EmitBreakStmt();
- break;
-
- case Stmt::ContinueStmtClass:
- // FIXME: Implement continue in @try or @catch blocks.
- if (!ObjCEHStack.empty()) {
- CGM.ErrorUnsupported(S, "continue inside an Obj-C exception block");
- return;
- }
- EmitContinueStmt();
- break;
case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
- case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
- case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break;
case Stmt::AsmStmtClass: EmitAsmStmt(cast<AsmStmt>(*S)); break;
case Stmt::ObjCAtTryStmtClass:
@@ -118,6 +100,22 @@
}
}
+bool CodeGenFunction::EmitSimpleStmt(const Stmt *S) {
+ switch (S->getStmtClass()) {
+ default: return false;
+ case Stmt::NullStmtClass: break;
+ 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::BreakStmtClass: EmitBreakStmt(cast<BreakStmt>(*S)); break;
+ case Stmt::ContinueStmtClass: EmitContinueStmt(cast<ContinueStmt>(*S)); break;
+ case Stmt::DefaultStmtClass: EmitDefaultStmt(cast<DefaultStmt>(*S)); break;
+ case Stmt::CaseStmtClass: EmitCaseStmt(cast<CaseStmt>(*S)); break;
+ }
+
+ return true;
+}
+
/// EmitCompoundStmt - Emit a compound statement {..} node. If GetLast is true,
/// this captures the expression result of the last sub-statement and returns it
/// (for use by the statement expression extension).
@@ -126,6 +124,7 @@
// FIXME: handle vla's etc.
CGDebugInfo *DI = CGM.getDebugInfo();
if (DI) {
+ EnsureInsertPoint();
DI->setLocation(S.getLBracLoc());
DI->EmitRegionStart(CurFn, Builder);
}
@@ -200,6 +199,11 @@
return;
}
+ // If this code is reachable then emit a stop point (if generating
+ // debug info). We have to do this ourselves because we are on the
+ // "simple" statement path.
+ if (HaveInsertPoint())
+ EmitStopPoint(&S);
EmitBranch(getBasicBlockForLabel(S.getLabel()));
}
@@ -485,16 +489,38 @@
EmitDecl(**I);
}
-void CodeGenFunction::EmitBreakStmt() {
+void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
+ // FIXME: Implement break in @try or @catch blocks.
+ if (!ObjCEHStack.empty()) {
+ CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
+ return;
+ }
+
+ // If this code is reachable then emit a stop point (if generating
+ // debug info). We have to do this ourselves because we are on the
+ // "simple" statement path.
+ if (HaveInsertPoint())
+ EmitStopPoint(&S);
llvm::BasicBlock *Block = BreakContinueStack.back().BreakBlock;
EmitBranch(Block);
}
-void CodeGenFunction::EmitContinueStmt() {
+void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
+ // FIXME: Implement continue in @try or @catch blocks.
+ if (!ObjCEHStack.empty()) {
+ CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
+ return;
+ }
+
+ // If this code is reachable then emit a stop point (if generating
+ // debug info). We have to do this ourselves because we are on the
+ // "simple" statement path.
+ if (HaveInsertPoint())
+ EmitStopPoint(&S);
llvm::BasicBlock *Block = BreakContinueStack.back().ContinueBlock;
EmitBranch(Block);
}
@@ -595,8 +621,8 @@
SwitchInsn = Builder.CreateSwitch(CondV, DefaultBlock);
CaseRangeBlock = DefaultBlock;
- // Create basic block for body of switch
- EmitBlock(createBasicBlock("sw.body"));
+ // Clear the insertion point to indicate we are in unreachable code.
+ Builder.ClearInsertionPoint();
// All break statements jump to NextBlock. If BreakContinueStack is non empty
// then reuse last ContinueBlock.
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=59118&r1=59117&r2=59118&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Nov 12 02:21:33 2008
@@ -346,6 +346,10 @@
// Statement Emission
//===--------------------------------------------------------------------===//
+ /// EmitStopPoint - Emit a debug stoppoint if we are emitting debug
+ /// info.
+ void EmitStopPoint(const Stmt *S);
+
/// EmitStmt - Emit the code for the statement \arg S. It is legal
/// to call this function even if there is no current insertion
/// point.
@@ -356,6 +360,14 @@
/// EmitStmt.
void EmitStmt(const Stmt *S);
+ /// EmitSimpleStmt - Try to emit a "simple" statement which does not
+ /// necessarily require an insertion point or debug information;
+ /// typically because the statement amounts to a jump or a container
+ /// of other statements.
+ ///
+ /// \return True if the statement was handled.
+ bool EmitSimpleStmt(const Stmt *S);
+
RValue EmitCompoundStmt(const CompoundStmt &S, bool GetLast = false,
llvm::Value *AggLoc = 0, bool isAggVol = false);
@@ -373,8 +385,8 @@
void EmitForStmt(const ForStmt &S);
void EmitReturnStmt(const ReturnStmt &S);
void EmitDeclStmt(const DeclStmt &S);
- void EmitBreakStmt();
- void EmitContinueStmt();
+ void EmitBreakStmt(const BreakStmt &S);
+ void EmitContinueStmt(const ContinueStmt &S);
void EmitSwitchStmt(const SwitchStmt &S);
void EmitDefaultStmt(const DefaultStmt &S);
void EmitCaseStmt(const CaseStmt &S);
More information about the cfe-commits
mailing list