This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]