[llvm] r261390 - [SimplifyCFG] Merge together cleanuppads
David Majnemer via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 19 17:07:46 PST 2016
Author: majnemer
Date: Fri Feb 19 19:07:45 2016
New Revision: 261390
URL: http://llvm.org/viewvc/llvm-project?rev=261390&view=rev
Log:
[SimplifyCFG] Merge together cleanuppads
Cleanuppads may be merged together if one is the only predecessor of the
other in which case a simple transform can be performed: replace the
a cleanupret with a branch and remove an unnecessary cleanuppad.
Differential Revision: http://reviews.llvm.org/D17459
Added:
llvm/trunk/test/Transforms/SimplifyCFG/merge-cleanuppads.ll
Modified:
llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=261390&r1=261389&r2=261390&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Fri Feb 19 19:07:45 2016
@@ -3371,7 +3371,7 @@ bool SimplifyCFGOpt::SimplifySingleResum
return true;
}
-bool SimplifyCFGOpt::SimplifyCleanupReturn(CleanupReturnInst *RI) {
+static bool removeEmptyCleanup(CleanupReturnInst *RI) {
// If this is a trivial cleanup pad that executes no instructions, it can be
// eliminated. If the cleanup pad continues to the caller, any predecessor
// that is an EH pad will be updated to continue to the caller and any
@@ -3489,6 +3489,49 @@ bool SimplifyCFGOpt::SimplifyCleanupRetu
return true;
}
+// Try to merge two cleanuppads together.
+static bool mergeCleanupPad(CleanupReturnInst *RI) {
+ // Skip any cleanuprets which unwind to caller, there is nothing to merge
+ // with.
+ BasicBlock *UnwindDest = RI->getUnwindDest();
+ if (!UnwindDest)
+ return false;
+
+ // This cleanupret isn't the only predecessor of this cleanuppad, it wouldn't
+ // be safe to merge without code duplication.
+ if (UnwindDest->getSinglePredecessor() != RI->getParent())
+ return false;
+
+ // Verify that our cleanuppad's unwind destination is another cleanuppad.
+ auto *SuccessorCleanupPad = dyn_cast<CleanupPadInst>(&UnwindDest->front());
+ if (!SuccessorCleanupPad)
+ return false;
+
+ CleanupPadInst *PredecessorCleanupPad = RI->getCleanupPad();
+ // Replace any uses of the successor cleanupad with the predecessor pad
+ // The only cleanuppad uses should be this cleanupret, it's cleanupret and
+ // funclet bundle operands.
+ SuccessorCleanupPad->replaceAllUsesWith(PredecessorCleanupPad);
+ // Remove the old cleanuppad.
+ SuccessorCleanupPad->eraseFromParent();
+ // Now, we simply replace the cleanupret with a branch to the unwind
+ // destination.
+ BranchInst::Create(UnwindDest, RI->getParent());
+ RI->eraseFromParent();
+
+ return true;
+}
+
+bool SimplifyCFGOpt::SimplifyCleanupReturn(CleanupReturnInst *RI) {
+ if (removeEmptyCleanup(RI))
+ return true;
+
+ if (mergeCleanupPad(RI))
+ return true;
+
+ return false;
+}
+
bool SimplifyCFGOpt::SimplifyReturn(ReturnInst *RI, IRBuilder<> &Builder) {
BasicBlock *BB = RI->getParent();
if (!BB->getFirstNonPHIOrDbg()->isTerminator()) return false;
@@ -4978,7 +5021,7 @@ static bool TryToMergeLandingPad(Landing
if (!BI2 || !BI2->isIdenticalTo(BI))
continue;
- // We've found an identical block. Update our predeccessors to take that
+ // We've found an identical block. Update our predecessors to take that
// path instead and make ourselves dead.
SmallSet<BasicBlock *, 16> Preds;
Preds.insert(pred_begin(BB), pred_end(BB));
Added: llvm/trunk/test/Transforms/SimplifyCFG/merge-cleanuppads.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/merge-cleanuppads.ll?rev=261390&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SimplifyCFG/merge-cleanuppads.ll (added)
+++ llvm/trunk/test/Transforms/SimplifyCFG/merge-cleanuppads.ll Fri Feb 19 19:07:45 2016
@@ -0,0 +1,39 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc18.0.0"
+
+; Function Attrs: uwtable
+define void @test1() #0 personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+ invoke void @may_throw(i32 3)
+ to label %invoke.cont unwind label %ehcleanup
+
+invoke.cont: ; preds = %entry
+ tail call void @may_throw(i32 2) #2
+ tail call void @may_throw(i32 1) #2
+ ret void
+
+ehcleanup: ; preds = %entry
+ %cp = cleanuppad within none []
+ tail call void @may_throw(i32 2) #2 [ "funclet"(token %cp) ]
+ cleanupret from %cp unwind label %ehcleanup2
+
+ehcleanup2:
+ %cp2 = cleanuppad within none []
+ tail call void @may_throw(i32 1) #2 [ "funclet"(token %cp2) ]
+ cleanupret from %cp2 unwind to caller
+}
+
+; CHECK-LABEL: define void @test1(
+; CHECK: %[[cp:.*]] = cleanuppad within none []
+; CHECK: tail call void @may_throw(i32 2) #2 [ "funclet"(token %[[cp]]) ]
+; CHECK: tail call void @may_throw(i32 1) #2 [ "funclet"(token %[[cp]]) ]
+; CHECK: cleanupret from %[[cp]] unwind to caller
+
+declare void @may_throw(i32) #1
+
+declare i32 @__CxxFrameHandler3(...)
+
+attributes #0 = { uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #2 = { nounwind }
More information about the llvm-commits
mailing list