https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127847
--- Comment #3 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
Some updates (from the patch review)
On v1: Jeff suggested doing this in prune_expressions due to concerns about
edge insertions and pruning in pruning/abornal edges.
- Hoisting doesn't use edges, it inserts at the end of dominating block.
- asm goto doesn't entail abnormal edges for both the out-edges.
As an experiment, prune_expressions approach also works for this case.
+ if (pre_p)
+ return;
+
+ /* Hoisting inserts an expression at the end of the target block, before
+ its final jump. If that jump modifies one of the expression's operands,
+ ... Make such expressions neither anticipatable nor transparent in the
+ jump's successors, so that they are not very busy at its block. */
+
+ auto_sbitmap jump_kills (expr_hash_table.n_elems);
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ rtx_insn *jump = BB_END (bb);
+ if (!JUMP_P (jump))
+ continue;
+ /* A plain jump only sets the pc. */
+ rtx pat = PATTERN (jump);
+ if (GET_CODE (pat) == SET && SET_DEST (pat) == pc_rtx)
+ continue;
+ ...for each expr: if (modified_in_p (expr->expr, jump)) set bit in
jump_kills...
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
+ {
+ bitmap_and_compl (antloc[idx], antloc[idx], jump_kills);
+ bitmap_and_compl (transp[idx], transp[idx], jump_kills);
+ }
+ }
However it is more conservative: if the successor has other predecessors, it
would block hoisting into those as well.