[cfe-commits] r129652 - in /cfe/trunk: lib/CodeGen/CGCleanup.cpp lib/CodeGen/CGStmt.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/switch-dce.c
Chris Lattner
sabre at nondot.org
Sat Apr 16 17:54:30 PDT 2011
Author: lattner
Date: Sat Apr 16 19:54:30 2011
New Revision: 129652
URL: http://llvm.org/viewvc/llvm-project?rev=129652&view=rev
Log:
implement rdar://9289524 - case followed immediately by break results in empty IR block,
a -O0 code quality issue.
Modified:
cfe/trunk/lib/CodeGen/CGCleanup.cpp
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/test/CodeGen/switch-dce.c
Modified: cfe/trunk/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCleanup.cpp?rev=129652&r1=129651&r2=129652&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCleanup.cpp Sat Apr 16 19:54:30 2011
@@ -870,6 +870,29 @@
}
}
+/// isObviouslyBranchWithoutCleanups - Return true if a branch to the
+/// specified destination obviously has no cleanups to run. 'false' is always
+/// a conservatively correct answer for this method.
+bool CodeGenFunction::isObviouslyBranchWithoutCleanups(JumpDest Dest) const {
+ assert(Dest.getScopeDepth().encloses(EHStack.stable_begin())
+ && "stale jump destination");
+
+ // Calculate the innermost active normal cleanup.
+ EHScopeStack::stable_iterator TopCleanup =
+ EHStack.getInnermostActiveNormalCleanup();
+
+ // If we're not in an active normal cleanup scope, or if the
+ // destination scope is within the innermost active normal cleanup
+ // scope, we don't need to worry about fixups.
+ if (TopCleanup == EHStack.stable_end() ||
+ TopCleanup.encloses(Dest.getScopeDepth())) // works for invalid
+ return true;
+
+ // Otherwise, we might need some cleanups.
+ return false;
+}
+
+
/// Terminate the current block by emitting a branch which might leave
/// the current cleanup-protected scope. The target scope may not yet
/// be known, in which case this will require a fixup.
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=129652&r1=129651&r2=129652&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Sat Apr 16 19:54:30 2011
@@ -867,11 +867,25 @@
}
void CodeGenFunction::EmitCaseStmt(const CaseStmt &S) {
+ // Handle case ranges.
if (S.getRHS()) {
EmitCaseStmtRange(S);
return;
}
+ // If the body of the case is just a 'break', try to not emit an empty block.
+ if (isa<BreakStmt>(S.getSubStmt())) {
+ JumpDest Block = BreakContinueStack.back().BreakBlock;
+
+ // Only do this optimization if there are no cleanups that need emitting.
+ if (isObviouslyBranchWithoutCleanups(Block)) {
+ llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext());
+ SwitchInsn->addCase(llvm::ConstantInt::get(getLLVMContext(), CaseVal),
+ Block.getBlock());
+ return;
+ }
+ }
+
EmitBlock(createBasicBlock("sw.bb"));
llvm::BasicBlock *CaseDest = Builder.GetInsertBlock();
llvm::APSInt CaseVal = S.getLHS()->EvaluateAsInt(getContext());
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=129652&r1=129651&r2=129652&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Apr 16 19:54:30 2011
@@ -769,6 +769,11 @@
/// block through the normal cleanup handling code (if any) and then
/// on to \arg Dest.
void EmitBranchThroughCleanup(JumpDest Dest);
+
+ /// isObviouslyBranchWithoutCleanups - Return true if a branch to the
+ /// specified destination obviously has no cleanups to run. 'false' is always
+ /// a conservatively correct answer for this method.
+ bool isObviouslyBranchWithoutCleanups(JumpDest Dest) const;
/// EmitBranchThroughEHCleanup - Emit a branch from the current
/// insert block through the EH cleanup handling code (if any) and
Modified: cfe/trunk/test/CodeGen/switch-dce.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/switch-dce.c?rev=129652&r1=129651&r2=129652&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/switch-dce.c (original)
+++ cfe/trunk/test/CodeGen/switch-dce.c Sat Apr 16 19:54:30 2011
@@ -216,3 +216,18 @@
}
}
+
+// rdar://9289524 - Check that the empty cases don't produce an empty block.
+// CHECK: @test13
+// CHECK: switch
+// CHECK: i32 42, label %sw.epilog
+// CHECK: i32 11, label %sw.epilog
+// CHECK: sw.epilog:
+// CHECK: ret void
+void test13(int x) {
+ switch (x) {
+ case 42: break; // No empty block please.
+ case 11: break; // No empty block please.
+ default: test13(42); break;
+ }
+}
More information about the cfe-commits
mailing list