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]

[rtlopt] peeling heuristics tweak


Hello,

some of the regressions of new peeling pass were caused by increased
number of misspredicted branches. This patch forbids simple peeling (and
unrolling) of loops that contain branches in hope (supported by some
measuring) that it will improve the situation.

Zdenek

Changelog:
	* cfgloopanal.c (simple_loop_p): Count desc->n_branches.
	* cfgloop.h (struct loop_desc): Add n_branches field.
	* loop-unroll.c (decide_peel_simple, decide_unroll_stupid): Do not
	unroll/peel loops containing branches.

Index: cfgloopanal.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloopanal.c,v
retrieving revision 1.1.4.5
diff -c -3 -p -r1.1.4.5 cfgloopanal.c
*** cfgloopanal.c	9 Nov 2002 17:52:10 -0000	1.1.4.5
--- cfgloopanal.c	29 Nov 2002 13:08:10 -0000
*************** simple_loop_p (loops, loop, desc)
*** 740,745 ****
--- 740,746 ----
    regset invariant_regs;
    regset_head invariant_regs_head;
    rtx *single_set_regs;
+   int n_branches;
    
    body = get_loop_body (loop);
  
*************** simple_loop_p (loops, loop, desc)
*** 749,754 ****
--- 750,756 ----
    blocks_invariant_registers (body, loop->num_nodes, invariant_regs);
    blocks_single_set_registers (body, loop->num_nodes, single_set_regs);
  
+   n_branches = 0;
    for (i = 0; i < loop->num_nodes; i++)
      {
        for (e = body[i]->succ; e; e = e->succ_next)
*************** simple_loop_p (loops, loop, desc)
*** 764,770 ****
--- 766,776 ----
  	      continue;
  	    *desc = act;
  	  }
+ 
+       if (body[i]->succ && body[i]->succ->succ_next)
+ 	n_branches++;
      }
+   desc->n_branches = n_branches;
  
    if (rtl_dump_file && any)
      {
*************** simple_loop_p (loops, loop, desc)
*** 797,802 ****
--- 803,812 ----
        if (desc->neg)
  	fprintf (rtl_dump_file, "(negated)");
        fprintf (rtl_dump_file, "%s\n", GET_RTX_NAME (desc->cond));
+ 
+       fprintf (rtl_dump_file, ";  Number of branches:");
+       fprintf (rtl_dump_file, "%d\n", desc->n_branches);
+ 
        fputc ('\n', rtl_dump_file);
      }
  
Index: cfgloop.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/cfgloop.h,v
retrieving revision 1.1.2.4
diff -c -3 -p -r1.1.2.4 cfgloop.h
*** cfgloop.h	9 Nov 2002 17:52:11 -0000	1.1.2.4
--- cfgloop.h	29 Nov 2002 13:08:10 -0000
*************** struct loop_desc
*** 53,58 ****
--- 53,59 ----
    int neg;		/* Set to 1 if loop ends when condition is satisfied.  */
    edge out_edge;	/* The exit edge.  */
    edge in_edge;		/* And the other one.  */
+   int n_branches;	/* Number of branches inside the loop.  */
  };
  
  /* Structure to hold information for each natural loop.  */
Index: loop-unroll.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/loop-unroll.c,v
retrieving revision 1.1.2.13
diff -c -3 -p -r1.1.2.13 loop-unroll.c
*** loop-unroll.c	10 Nov 2002 13:49:32 -0000	1.1.2.13
--- loop-unroll.c	29 Nov 2002 13:08:10 -0000
*************** decide_peel_simple (loops, loop, flags)
*** 901,913 ****
      loop->simple = simple_loop_p (loops, loop, &loop->desc);
  
    /* Check number of iterations.  */
!   if (loop->simple &&loop->desc.const_iter)
      {
        if (rtl_dump_file)
  	fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
        return;
      }
  
    /* If we have profile feedback, check whether the loop rolls.  */
    if (loop->histogram)
      {
--- 901,922 ----
      loop->simple = simple_loop_p (loops, loop, &loop->desc);
  
    /* Check number of iterations.  */
!   if (loop->simple && loop->desc.const_iter)
      {
        if (rtl_dump_file)
  	fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
        return;
      }
  
+   /* Do not simply peel loops with branches inside -- it increases number
+      of mispredicts.  */
+   if (loop->desc.n_branches > 1)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Not peeling, contains branches\n");
+       return;
+     }
+ 
    /* If we have profile feedback, check whether the loop rolls.  */
    if (loop->histogram)
      {
*************** decide_unroll_stupid (loops, loop, flags
*** 1034,1039 ****
--- 1043,1057 ----
      {
        if (rtl_dump_file)
  	fprintf (rtl_dump_file, ";; The loop is simple\n");
+       return;
+     }
+ 
+   /* Do not unroll loops with branches inside -- it increases number
+      of mispredicts.  */
+   if (loop->desc.n_branches > 1)
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, ";; Not unrolling, contains branches\n");
        return;
      }
  


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