This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] cfgloopmanip.c: Speed up create_preheader.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 08 Dec 2004 08:21:18 -0500 (EST)
- Subject: [patch] cfgloopmanip.c: Speed up create_preheader.
Hi,
Attached is a patch to speed up create_preheader by "unrolling" and
simplifying FOR_EACH_EDGE.
Each of the two hunks below contains an instance of FOR_EACH_EDGE like
this.
FOR_EACH_EDGE (e, ei, loop->header->preds)
if (e->src != loop->latch)
break;
Note that a loop header has at least two incoming edges, one back edge
and another one to enter the loop. Note also that edges in any edge
vector are unique. Let me list out all possible outcomes after the
FOR_EACH_EDGE.
EDGE_PRED (loop->header, 0)->src == loop->latch
In this case, we have e == EDGE_PRED (loop->header, 1)->src.
EDGE_PRED (loop->header, 0)->src != loop->latch
In this case, we have e == EDGE_PRED (loop->header, 0)->src.
So we can easily replace FOR_EACH_EDGE with code like so:
e = EDGE_PRED (loop->header,
EDGE_PRED (loop->header, 0)->src == loop->latch);
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2004-12-08 Kazu Hirata <kazu@cs.umass.edu>
* cfgloopmanip.c (create_preheader): Speed up by "unrolling"
and simplifying FOR_EACH_EDGE.
Index: cfgloopmanip.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgloopmanip.c,v
retrieving revision 1.38
diff -c -d -p -r1.38 cfgloopmanip.c
*** cfgloopmanip.c 22 Nov 2004 17:13:59 -0000 1.38
--- cfgloopmanip.c 8 Dec 2004 06:43:13 -0000
*************** create_preheader (struct loop *loop, int
*** 1156,1164 ****
gcc_assert (nentry);
if (nentry == 1)
{
! FOR_EACH_EDGE (e, ei, loop->header->preds)
! if (e->src != loop->latch)
! break;
if (!(flags & CP_SIMPLE_PREHEADERS) || EDGE_COUNT (e->src->succs) == 1)
return NULL;
--- 1156,1165 ----
gcc_assert (nentry);
if (nentry == 1)
{
! /* Get an edge that is different from the one from loop->latch
! to loop->header. */
! e = EDGE_PRED (loop->header,
! EDGE_PRED (loop->header, 0)->src == loop->latch);
if (!(flags & CP_SIMPLE_PREHEADERS) || EDGE_COUNT (e->src->succs) == 1)
return NULL;
*************** create_preheader (struct loop *loop, int
*** 1178,1186 ****
/* Reorganize blocks so that the preheader is not stuck in the middle of the
loop. */
! FOR_EACH_EDGE (e, ei, dummy->preds)
! if (e->src != loop->latch)
! break;
move_block_after (dummy, e->src);
loop->header->loop_father = loop;
--- 1179,1188 ----
/* Reorganize blocks so that the preheader is not stuck in the middle of the
loop. */
!
! /* Get an edge that is different from the one from loop->latch to
! dummy. */
! e = EDGE_PRED (dummy, EDGE_PRED (dummy, 0)->src == loop->latch);
move_block_after (dummy, e->src);
loop->header->loop_father = loop;