On Wed, Aug 21, 2024 at 1:46 PM Georg-Johann Lay <[email protected]> wrote:
>
> Am 21.08.24 um 11:31 schrieb Richard Biener:
> > 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).
>
> Thanks, that's what I am looking for. Is there some means to get the
> edge associated to a branch? Currently I an just using find_edge()
> with the respective BBs.
That's good enough, otherwise FOR_EACH_EDGE on the BB
successor edges and looking at EDGE_{TRUE,FALSE}_VALUE
works to get the edge corresponding to the true/false branch.
Richard.
> Johann
>
> the current bb