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: treat sibling calls as non-const


For the reason explained in the comment. The testcase demonstrates the problem
on ppc, and probably on other machines that pass args in registers.
Bootstrapped and tested on Darwin to the extent currently possible
(no diffs before & after).


2003-09-11 Dale Johannesen <dalej@apple.com>

* loop.c (prescan_loop): Treat sibling calls as non-const.

Index: loop.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/loop.c,v
retrieving revision 1.470
diff -u -d -b -w -c -3 -p -r1.470 loop.c
*** loop.c      7 Sep 2003 05:21:35 -0000       1.470
--- loop.c      11 Sep 2003 19:48:20 -0000
*************** prescan_loop (struct loop *loop)
*** 2511,2522 ****
          break;

        case CALL_INSN:
          if (! CONST_OR_PURE_CALL_P (insn))
            {
              loop_info->unknown_address_altered = 1;
              loop_info->has_nonconst_call = 1;
            }
!         else if (pure_call_p (insn))
            loop_info->has_nonconst_call = 1;
          loop_info->has_call = 1;
          if (can_throw_internal (insn))
--- 2511,2539 ----
          break;

        case CALL_INSN:
+           /* The loop optimizer attempts to hoist invariant stores
+            out of the loop.  Stores into memory locations that are
+            actual parameters for a call within the loop
+            can be invariant, and can be hoisted; however,
+            they then appear dead and are removed, as the call
+            insn doesn't have any info about memory parameters
+            attached.  So we don't want to do this.  This is
+            prevented in the case of non-const calls by not
+            hoisting any stores, and in the case of const non-sibcalls
+            by enclosing the parameters in LIBCALL...RETVAL notes,
+            which prevents individual stores from being considered
+            separately.  To fix the remaining case, const sibcalls,
+            we treat them as non-const.
+            FIXME:  A better, but much more invasive, way to fix this
+              is to establish a connection between the call and the
+              parameters, so hoisted stores don't get deleted.  There
+              is no good reason they shouldn't get hoisted.  */
          if (! CONST_OR_PURE_CALL_P (insn))
            {
              loop_info->unknown_address_altered = 1;
              loop_info->has_nonconst_call = 1;
            }
!         else if (pure_call_p (insn) || SIBLING_CALL_P (insn))
            loop_info->has_nonconst_call = 1;
          loop_info->has_call = 1;
          if (can_throw_internal (insn))


/* { dg-do run } */ /* { dg-options "-O2" } */

static int a (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10)
{ return i10; }


int b (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10)
{
for(;;)
if (i1)
return a (i1, i2, i3, i4, i5, i6, i7, i8, i9, i10 + 1);
}


main() {
  int val = b(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  if (val != 11)
    {
      printf ("failure: got %d, expected 11\n", val);
      abort() ;
    }
  else
    printf ("O.K.\n");
  exit(0);
}


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