This patch tries to merge duplicate landing pads when they branch to a common shared target.
Given IR that looks like this:
lpad1:
%exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 cleanup br label %shared_resume
lpad2:
%exn2 = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 cleanup br label %shared_resume
shared_resume:
call void @fn() ret void
}
We can rewrite the users of both landing pad blocks to use one of them. This will generally allow the shared_resume block to be merged with the common landing pad as well.
Without this change, tail duplication would likely kick in - creating N (2 in this case) copies of the shared_resume basic block.
There are two subtitles with the choice of blocks to merge. From the comments:
/ We specifically choose to not worry about merging non-empty blocks
/ here. That is a PRE/scheduling problem and is best solved elsewhere. In
/ practice, the optimizer produces empty landing pad blocks quite frequently
/ when dealing with exception dense code. (see: instcombine, gvn, if-else
/ sinking in this file)
/
/ This is primarily a code size optimization. We need to avoid performing
/ any transform which might inhibit optimization (such as our ability to
/ specialize a particular handler via tail commoning). We do this by not
/ merging any blocks which require us to introduce a phi. Since the same
/ values are flowing through both blocks, we don't loose any ability to
/ specialize. If anything, we make such specialization more likely.