This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Minor improvement to commit_edge_insertion
- To: gcc-patches at gcc dot gnu dot org
- Subject: Minor improvement to commit_edge_insertion
- From: law at redhat dot com
- Date: Tue, 14 Aug 2001 17:30:49 -0600
- Reply-to: law at redhat dot com
While analyzing some performance issues with our SSA pass I've found an
interesting issue with commit_edge_insertions.
The translation back to normal form may require insertion of copy
instructions in edges in the CFG to eliminate PHI nodes.
If the destination has one predecessor, then we'll insert the copy in
the destination. Similarly if the source has one successor, then we'll
insert the copy in the source [ otherwise we split the edge ].
Consider the case where we insert into the source block. We'll be inserting
the copy just before the unconditional jump which terminates the source
block. So, if the end of the source block looks like this:
NOTE_INSN_LOOP_BEG
unconditional jump to target block (which contains the loop test)
We'll make it look like:
NOTE_INSN_LOOP_BEG
Copies from PHI nodes
unconditional jump to target block (which contains the loop test)
Having one or more insns between the LOOP_BEG note and the jump to the
loop test will confuse the loop optimizer. The net result being the
loop optimizer will simply ignore the loop. Not good.
This situation occurs with or without SSA -- SSA just makes it more likely
to occur.
Luckily this problem is trivial to fix. We simply insert the copy before
the LOOP_BEG note.
I've bootstrapped this change on both ia64-linux and hppa-hpux. Installed
in the mainline sources.
* flow.c (commit_one_edge_insertion): Don't separate a LOOP_BEG
note from its associated jump.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/flow.c,v
retrieving revision 1.462
diff -c -3 -p -r1.462 flow.c
*** flow.c 2001/08/10 16:19:07 1.462
--- flow.c 2001/08/14 23:25:52
*************** commit_one_edge_insertion (e)
*** 2405,2410 ****
--- 2405,2413 ----
if (GET_CODE (bb->end) == JUMP_INSN)
{
before = bb->end;
+ while (GET_CODE (PREV_INSN (before)) == NOTE
+ && NOTE_LINE_NUMBER (PREV_INSN (before)) == NOTE_INSN_LOOP_BEG)
+ before = PREV_INSN (before);
}
else
{