From: David Majnemer Date: Tue, 5 Jan 2016 07:42:17 +0000 (+0000) Subject: [SimplifyCFG] Further improve our ability to remove redundant catchpads X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=a3d4e67e432577ebca542c8e483ec692956a88c8 [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 --- 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 +}