From a3d4e67e432577ebca542c8e483ec692956a88c8 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 5 Jan 2016 07:42:17 +0000 Subject: [PATCH] [SimplifyCFG] Further improve our ability to remove redundant catchpads In r256814, we managed to remove catchpads which were trivially redudant because they were the same SSA value. We can do better using the same algorithm but with a smarter datastructure by hashing the SSA values within the catchpad and comparing them structurally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256815 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/Local.cpp | 28 +++++++- .../SimplifyCFG/wineh-unreachable.ll | 66 +++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 3845ca2e7e5..3f46c5ebf45 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1324,12 +1324,36 @@ static bool markAliveBlocks(Function &F, } } else if (auto *CatchSwitch = dyn_cast(Terminator)) { // Remove catchpads which cannot be reached. - SmallPtrSet HandlersSeen; + struct CatchPadDenseMapInfo { + static CatchPadInst *getEmptyKey() { + return DenseMapInfo::getEmptyKey(); + } + static CatchPadInst *getTombstoneKey() { + return DenseMapInfo::getTombstoneKey(); + } + static unsigned getHashValue(CatchPadInst *CatchPad) { + return static_cast(hash_combine_range( + CatchPad->value_op_begin(), CatchPad->value_op_end())); + } + static bool isEqual(CatchPadInst *LHS, CatchPadInst *RHS) { + if (LHS == getEmptyKey() || LHS == getTombstoneKey() || + RHS == getEmptyKey() || RHS == getTombstoneKey()) + return LHS == RHS; + return LHS->isIdenticalTo(RHS); + } + }; + + // Set of unique CatchPads. + SmallDenseMap> + HandlerSet; + detail::DenseSetEmpty Empty; for (CatchSwitchInst::handler_iterator I = CatchSwitch->handler_begin(), E = CatchSwitch->handler_end(); I != E; ++I) { BasicBlock *HandlerBB = *I; - if (!HandlersSeen.insert(HandlerBB).second) { + auto *CatchPad = cast(HandlerBB->getFirstNonPHI()); + if (!HandlerSet.insert({CatchPad, Empty}).second) { CatchSwitch->removeHandler(I); --I; --E; diff --git a/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/test/Transforms/SimplifyCFG/wineh-unreachable.ll index d871e17b6b0..c5d6490ba5d 100644 --- a/test/Transforms/SimplifyCFG/wineh-unreachable.ll +++ b/test/Transforms/SimplifyCFG/wineh-unreachable.ll @@ -99,3 +99,69 @@ catch.body: exit: ret void } + +; CHECK-LABEL: define void @test7() +define void @test7() personality i8* bitcast (void ()* @Personality to i8*) { +entry: + invoke void @f() + to label %exit unwind label %catch.pad + +catch.pad: + %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller + ; CHECK: catchswitch within none [label %catch.body] unwind to caller + +catch.body: + %catch = catchpad within %cs1 [i8* null, i32 0, i8* null] + catchret from %catch to label %exit + +catch.body2: + %catch2 = catchpad within %cs1 [i8* null, i32 0, i8* null] + catchret from %catch2 to label %exit + +exit: + ret void +} + +; CHECK-LABEL: define void @test8() +define void @test8() personality i8* bitcast (void ()* @Personality to i8*) { +entry: + invoke void @f() + to label %exit unwind label %catch.pad + +catch.pad: + %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller + ; CHECK: catchswitch within none [label %catch.body] unwind to caller + +catch.body2: + %catch2 = catchpad within %cs1 [i8* null, i32 0, i8* null] + catchret from %catch2 to label %exit + +catch.body: + %catch = catchpad within %cs1 [i8* null, i32 0, i8* null] + catchret from %catch to label %exit + +exit: + ret void +} + +; CHECK-LABEL: define void @test9() +define void @test9() personality i8* bitcast (void ()* @Personality to i8*) { +entry: + invoke void @f() + to label %exit unwind label %catch.pad + +catch.pad: + %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller + ; CHECK: catchswitch within none [label %catch.body, label %catch.body2] unwind to caller + +catch.body: + %catch = catchpad within %cs1 [i8* null, i32 0, i8* null] + catchret from %catch to label %exit + +catch.body2: + %catch2 = catchpad within %cs1 [i8* null, i32 64, i8* null] + catchret from %catch2 to label %exit + +exit: + ret void +} -- 2.34.1