On Wed, Aug 21, 2024 at 11:19 AM Georg-Johann Lay <[email protected]> wrote:
>
> Hi, in an RTL optimization pass I would like to
> perform a transformation like from old code:
>
> [bb 1]
> if (condA) ;; insn1
> goto label_1;
>
> [bb 2]
> if (cond_B) ;; insn2
> goto label_2;
>
> to new code:
>
> [bb 1]
> if (cond1) ;; branch1
> goto label_2;
>
> [bb 2]
> if (cond2) ;; branch 2
> goto label_1;
>
> but I am having trouble finding the correct code
> to accomplish the transformation. Notice that the
> goto targets have been swapped.
>
> The current code WIP looks something like below, where insn1 and
> insn2 are the old conditional branches:
>
> rtx_jump_insn *branch1 = emit_jump_insn_after (cond1, insn1);
> rtx_jump_insn *branch2 = emit_jump_insn_after (cond2, insn2);
> JUMP_LABEL (branch1) = label_2;
> JUMP_LABEL (branch2) = label_1;
> ++LABEL_NUSES (label_2);
> ++LABEL_NUSES (label_1);
>
> delete_insn (insn1);
> delete_insn (insn2);
>
> Then, in a later pass, some code and label that are not dead are removed.
> Trying to maintain the new edges by hand, like in
>
> delete_insn_and_edges (insn1);
> delete_insn_and_edges (insn2);
> make_edge (bb 1, bb (label_2));
> make_edge (bb 2, bb (label_1));
>
> runs into ICE in verify_flow_info. Maybe someone can explain how
> to do it properly or where I can find examples (internals don't
> help much, and I couldn't find examples in the sources).
You want to look at cfghooks.{h,cc} and try to express the transform
in terms of that API, likely redirect_edge_and_branch[_force] on both
branch edges - that should adjust the jump insn as well (just the
target of course, not the comparison).
> FYI, the current code is here:
> https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/config/avr/avr.cc;h=c520b98a178d2266189879239f76a928dfd989cf;hb=HEAD#l1024
> This works fine as it doesn't change the control flow and only
> changes the comparisons. This is necessary because passes like
> compare-elim won't do such optimizations.
>
> Thanks in advance,
>
> Johann
>
>
>
>