This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Try to update dominance info in tree-call-cdce.c
- From: Richard Sandiford <richard dot sandiford at arm dot com>
- To: Steven Bosscher <stevenb dot gcc at gmail dot com>
- Cc: Richard Biener <richard dot guenther at gmail dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 02 Nov 2015 15:53:21 +0000
- Subject: Re: Try to update dominance info in tree-call-cdce.c
- Authentication-results: sourceware.org; auth=none
- References: <87a8r0wqoe dot fsf at e105548-lin dot cambridge dot arm dot com> <CAFiYyc1483DY3Uq+zmkcfraLrwMCuxAsb_J5jv1jvWJizeNBnw at mail dot gmail dot com> <871tccwo2g dot fsf at e105548-lin dot cambridge dot arm dot com> <CAFiYyc0LFwwtO-GkGc+xGjpYxi239tT5rbxMht4O35yBF6Q-2Q at mail dot gmail dot com> <87si4sv6uw dot fsf at e105548-lin dot cambridge dot arm dot com> <CABu31nNvPvZ1j1Mx_nDd3b9G-fHwNoEFTQ68a=Y_LMk3VNVQCQ at mail dot gmail dot com>
Steven Bosscher <stevenb.gcc@gmail.com> writes:
> On Fri, Oct 30, 2015 at 2:11 PM, Richard Sandiford
> <richard.sandiford@arm.com> wrote:
>> Is the split_block change really so bad?
>
> IMHO: Yes.
Fair enough :-)
> split_block just splits some basic block B into two blocks B1/B2
> somewhere in the middle of B. The dominance relations between B1 and
> B2 are obvious and intuitive. The new flag to split_block is not. The
> dominance info is not updated but the loops are? Confusing, if you ask
> me...
>
> Your situation, where a pass knows the dominance relations will
> change, is unusual. The extra work to fix up the ET tree twice should
> be negligible anyway.
I just thought that the cfg was in practice never going to stay in the
state that it is on return from split_block. The caller is bound to
add (at least) another edge somewhere.
Here's a version that works with split_block rather than against it.
Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu.
OK to install?
Thanks,
Richard
gcc/
* tree-call-cdce.c (shrink_wrap_one_built_in_call): Try to update
the dominance info; free it if we can't.
(pass_call_cdce::execute): Don't free the dominance info here.
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index ffc1c4e..a5f38ce 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -731,6 +731,32 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
if (nconds == 0)
return false;
+ /* The cfg we want to create looks like this:
+
+ [guard n-1] <- guard_bb (old block)
+ | \
+ | [guard n-2] }
+ | / \ }
+ | / ... } new blocks
+ | / [guard 0] }
+ | / / | }
+ [ call ] | <- bi_call_bb }
+ | \ |
+ | \ |
+ | [ join ] <- join_tgt_bb (old iff call must end bb)
+ |
+ possible EH edges (only if [join] is old)
+
+ When [join] is new, the immediate dominators for these blocks are:
+
+ 1. [guard n-1]: unchanged
+ 2. [call]: [guard n-1]
+ 3. [guard m]: [guard m+1] for 0 <= m <= n-2
+ 4. [join]: [guard n-1]
+
+ We punt for the more complex case case of [join] being old and
+ simply free the dominance info. We also punt on postdominators,
+ which aren't expected to be available at this point anyway. */
bi_call_bb = gimple_bb (bi_call);
/* Now find the join target bb -- split bi_call_bb if needed. */
@@ -741,6 +767,7 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs);
if (join_tgt_in_edge_from_call == NULL)
return false;
+ free_dominance_info (CDI_DOMINATORS);
}
else
join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
@@ -820,6 +847,15 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
guard_bb_in_edge->count = guard_bb->count - bi_call_in_edge->count;
}
+ if (dom_info_available_p (CDI_DOMINATORS))
+ {
+ /* The split_blocks leave [guard 0] as the immediate dominator
+ of [call] and [call] as the immediate dominator of [join].
+ Fix them up. */
+ set_immediate_dominator (CDI_DOMINATORS, bi_call_bb, guard_bb);
+ set_immediate_dominator (CDI_DOMINATORS, join_tgt_bb, guard_bb);
+ }
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
location_t loc;
@@ -927,7 +963,6 @@ pass_call_cdce::execute (function *fun)
if (something_changed)
{
- free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
/* As we introduced new control-flow we need to insert PHI-nodes
for the call-clobbers of the remaining call. */