On Wed, Aug 21, 2024 at 11:19 AM Georg-Johann Lay <a...@gjlay.de> 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 > > > >