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).

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




Reply via email to