public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Loop optimization bug with Ada front end on PPC (and probably Alpha)
@ 2001-11-13  5:20 Corey Minyard
  2001-11-13  6:05 ` David Edelsohn
                   ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Corey Minyard @ 2001-11-13  5:20 UTC (permalink / raw)
  To: gcc

[-- Attachment #1: Type: text/plain, Size: 894 bytes --]

I've found a bug in the doloop optimization that has to do with how the
Ada front end generates code.  This occurs on PowerPC and Alpha, it
doesn't seem to happen on x86 because this particular optimiation never
seems to get hit.

The problem is that the Ada front end generates code for "for" loops like:

     for I in 1 .. Len loop
         a[i] := b[i];
     end loop;

The output RTL (in pseudocode) is something like:

     I := 1;
     goto loopstart
loopcont:
     i := i + 1;
loopstart:
     a[i] := b[i];
     if (i /= Len) then
         goto loopcont;
     end if;

The doloop optimization doesn't handle this case correctly because the
loop variable is incremented after the loop comparison, not before, so
doloop optimization will execute the loop one too few times.  I've
attached a cheap hack that fixes the bug, but it's a cheap hack.  How
should this really be fixed?

-Corey


[-- Attachment #2: loopfix.diff --]
[-- Type: text/plain, Size: 3998 bytes --]

Index: basic-block.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v
retrieving revision 1.128
diff -u -r1.128 basic-block.h
--- basic-block.h	2001/11/15 07:55:45	1.128
+++ basic-block.h	2001/11/22 05:56:32
@@ -409,6 +409,9 @@
   /* Non-zero if the loop has a NOTE_INSN_LOOP_VTOP.  */
   rtx vtop;
 
+  /* Non-zero if the loop has a NOTE_INSN_LOOP_SKIPINCR. */
+  rtx skip_incr;
+
   /* Non-zero if the loop has a NOTE_INSN_LOOP_CONT.
      A continue statement will generate a branch to NEXT_INSN (cont).  */
   rtx cont;
Index: doloop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doloop.c,v
retrieving revision 1.12
diff -u -r1.12 doloop.c
--- doloop.c	2001/11/16 02:26:38	1.12
+++ doloop.c	2001/11/22 05:56:36
@@ -596,6 +596,15 @@
 			      copy_rtx (neg_inc ? final_value : initial_value),
 			      NULL_RTX, unsigned_p, OPTAB_LIB_WIDEN);
 
+  if (loop->skip_incr && ! loop->vtop)
+    {
+      /* If skip_incr is set, then the increment for the loop is done
+	 after the test, so we need to iterate one more time. */
+      diff = expand_simple_binop (GET_MODE (diff), PLUS,
+				  diff, GEN_INT(1),
+				  NULL_RTX, 1, OPTAB_LIB_WIDEN);
+    }
+
   if (abs_inc * loop_info->unroll_number != 1)
     {
       int shift_count;
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.222
diff -u -r1.222 final.c
--- final.c	2001/11/15 14:58:19	1.222
+++ final.c	2001/11/22 05:56:49
@@ -2115,6 +2115,7 @@
 	case NOTE_INSN_LOOP_END:
 	case NOTE_INSN_LOOP_CONT:
 	case NOTE_INSN_LOOP_VTOP:
+	case NOTE_INSN_LOOP_SKIPINCR:
 	case NOTE_INSN_FUNCTION_END:
 	case NOTE_INSN_REPEATED_LINE_NUMBER:
 	case NOTE_INSN_RANGE_BEG:
Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.369
diff -u -r1.369 loop.c
--- loop.c	2001/11/15 23:44:56	1.369
+++ loop.c	2001/11/22 05:57:26
@@ -2519,6 +2519,10 @@
 	    current_loop->vtop = insn;
 	    break;
 
+	  case NOTE_INSN_LOOP_SKIPINCR:
+	    current_loop->skip_incr = insn;
+	    break;
+
 	  case NOTE_INSN_LOOP_END:
 	    if (! current_loop)
 	      abort ();
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.c,v
retrieving revision 1.103
diff -u -r1.103 rtl.c
--- rtl.c	2001/11/03 16:28:33	1.103
+++ rtl.c	2001/11/22 05:57:29
@@ -263,6 +263,7 @@
   "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
   "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
   "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
+  "NOTE_INSN_LOOP_SKIPINCR",
   "NOTE_INSN_FUNCTION_END",
   "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
   "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.314
diff -u -r1.314 rtl.h
--- rtl.h	2001/11/15 23:44:55	1.314
+++ rtl.h	2001/11/22 05:57:39
@@ -674,6 +674,9 @@
   NOTE_INSN_LOOP_CONT,
   /* Generated at the start of a duplicated exit test.  */
   NOTE_INSN_LOOP_VTOP,
+  /* Generated at the start of an increment that is skipped the
+     first time in the loop. */
+  NOTE_INSN_LOOP_SKIPINCR,
 
   /* This kind of note is generated at the end of the function body,
      just before the return insn or return label.  In an optimizing
Index: ada/trans.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ada/trans.c,v
retrieving revision 1.5
diff -u -r1.5 trans.c
--- trans.c	2001/11/15 23:34:17	1.5
+++ trans.c	2001/11/22 05:59:10
@@ -2374,6 +2374,8 @@
 					convert (TREE_TYPE (gnu_loop_var),
 						 integer_one_node));
 	    set_lineno (gnat_iter_scheme, 1);
+	    if (gnu_bottom_condition != integer_one_node)
+	      emit_note (NULL, NOTE_INSN_LOOP_SKIPINCR);
 	    expand_expr_stmt (gnu_expr);
 	  }
 


^ permalink raw reply	[flat|nested] 58+ messages in thread
* Re: Loop optimization bug with Ada front end on PPC (and probably Alpha)
@ 2001-11-15 18:47 Richard Kenner
  2001-11-25 15:13 ` Richard Kenner
  0 siblings, 1 reply; 58+ messages in thread
From: Richard Kenner @ 2001-11-15 18:47 UTC (permalink / raw)
  To: minyard; +Cc: gcc

    procedure Ada.Tster (S   : in out String;
                         Len : in out Integer) is

You shouldn't use "Ada.".  Just "Tster" is fine.

    Unfortunately, it's not simple to reproduce this, since you have to
    build an Ada cross compiler, and you have to compile this code as part
    of the compiler (since you can't compile anything else easily without
    having gnatlib compiled and installed) 

The latter is not totally true.  Just do "make gnatlib" and let it get as
far as the symlinks.  It doesn't matter if the compiles blow up (as they will
if you have a cross-compiler with no assembler).

Then, in the object directory, you can just do ./gnat1 -Iada/rts followed by
the location of the test program.

^ permalink raw reply	[flat|nested] 58+ messages in thread
* Re: Loop optimization bug with Ada front end on PPC (and probably Alpha)
@ 2001-11-15 19:05 dewar
  2001-11-25 15:20 ` dewar
  0 siblings, 1 reply; 58+ messages in thread
From: dewar @ 2001-11-15 19:05 UTC (permalink / raw)
  To: kenner, minyard; +Cc: gcc

    procedure Ada.Tster (S   : in out String;
                         Len : in out Integer) is

There is in fact a specific rule in the Ada RM that prevents a user program
from compiling children of Ada. Now you can use -gnatg to allow this (that's
how we compile the runtime), but that is unusual usage :-)

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2001-11-28  3:57 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-13  5:20 Loop optimization bug with Ada front end on PPC (and probably Alpha) Corey Minyard
2001-11-13  6:05 ` David Edelsohn
2001-11-14  8:05   ` Corey Minyard
2001-11-13  8:02 ` guerby
2001-11-13  9:48   ` Corey Minyard
2001-11-16 22:19     ` David Edelsohn
2001-11-26  7:39       ` David Edelsohn
2001-11-15  0:48 ` Richard Henderson
2001-11-15 14:19   ` Andreas Schwab
2001-11-15 16:20     ` Richard Henderson
2001-11-25 12:23       ` Richard Henderson
2001-11-18  9:18     ` Richard Henderson
2001-11-27  0:02       ` Richard Henderson
2001-11-25  8:57     ` Andreas Schwab
2001-11-15 18:02   ` Corey Minyard
2001-11-15 19:37     ` Richard Henderson
2001-11-25 15:52       ` Richard Henderson
2001-11-16  3:13     ` Richard Henderson
2001-11-16  3:42       ` Corey Minyard
2001-11-16  8:54         ` Bryce McKinlay
2001-11-26  0:47           ` Bryce McKinlay
2001-11-25 20:27         ` Corey Minyard
2001-11-17  1:33       ` Corey Minyard
2001-11-17  6:09         ` Corey Minyard
2001-11-26 10:22           ` Corey Minyard
2001-11-17 11:51         ` Richard Henderson
2001-11-17 15:20           ` Corey Minyard
2001-11-26 14:45             ` Corey Minyard
2001-11-18  5:15           ` Corey Minyard
2001-11-18  8:59             ` Richard Henderson
2001-11-19  2:58               ` Corey Minyard
2001-11-19  3:11                 ` Richard Henderson
2001-11-19  5:36                   ` Corey Minyard
2001-11-19  7:48                     ` Richard Henderson
2001-11-19  7:58                       ` Corey Minyard
2001-11-19  9:43                         ` Richard Henderson
2001-11-19 12:44                           ` Corey Minyard
2001-11-19 13:53                             ` Richard Henderson
2001-11-20 11:20                               ` Corey Minyard
2001-11-27 19:57                                 ` Corey Minyard
2001-11-27 15:31                               ` Richard Henderson
2001-11-27 15:04                             ` Corey Minyard
2001-11-27 14:27                           ` Richard Henderson
2001-11-27 13:25                         ` Corey Minyard
2001-11-27 12:58                       ` Richard Henderson
2001-11-27 11:51                     ` Corey Minyard
2001-11-27 10:29                   ` Richard Henderson
2001-11-27 10:08                 ` Corey Minyard
2001-11-26 23:18               ` Richard Henderson
2001-11-26 17:15             ` Corey Minyard
2001-11-26 13:49           ` Richard Henderson
2001-11-26  8:58         ` Corey Minyard
2001-11-25 17:58       ` Richard Henderson
2001-11-25 15:06     ` Corey Minyard
2001-11-15 18:47 Richard Kenner
2001-11-25 15:13 ` Richard Kenner
2001-11-15 19:05 dewar
2001-11-25 15:20 ` dewar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).