Skip to content

Commit

Permalink
[SimplifyCFG] Further improve our ability to remove redundant catchpads
Browse files Browse the repository at this point in the history
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
  • Loading branch information
majnemer committed Jan 5, 2016
1 parent a482477 commit a3d4e67
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 2 deletions.
28 changes: 26 additions & 2 deletions lib/Transforms/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,12 +1324,36 @@ static bool markAliveBlocks(Function &F,
}
} else if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Terminator)) {
// Remove catchpads which cannot be reached.
SmallPtrSet<BasicBlock *, 4> HandlersSeen;
struct CatchPadDenseMapInfo {
static CatchPadInst *getEmptyKey() {
return DenseMapInfo<CatchPadInst *>::getEmptyKey();
}
static CatchPadInst *getTombstoneKey() {
return DenseMapInfo<CatchPadInst *>::getTombstoneKey();
}
static unsigned getHashValue(CatchPadInst *CatchPad) {
return static_cast<unsigned>(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<CatchPadInst *, detail::DenseSetEmpty, 4,
CatchPadDenseMapInfo, detail::DenseSetPair<CatchPadInst *>>
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<CatchPadInst>(HandlerBB->getFirstNonPHI());
if (!HandlerSet.insert({CatchPad, Empty}).second) {
CatchSwitch->removeHandler(I);
--I;
--E;
Expand Down
66 changes: 66 additions & 0 deletions test/Transforms/SimplifyCFG/wineh-unreachable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit a3d4e67

Please sign in to comment.