PR opt/5120
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Apr 2002 19:42:22 +0000 (19:42 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Apr 2002 19:42:22 +0000 (19:42 +0000)
* sibcall.c (optimize_sibling_and_tail_recursive_call): Clear
RTX_UNCHANGING_P for the functions arguments when a tail call
is made.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@51969 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/sibcall.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20020406-1.c [new file with mode: 0644]

index 6c451f9..548caa9 100644 (file)
@@ -1,3 +1,10 @@
+2002-04-06  Mark Mitchell  <mark@codesourcery.com>
+
+       PR opt/5120
+       * sibcall.c (optimize_sibling_and_tail_recursive_call): Clear
+       RTX_UNCHANGING_P for the functions arguments when a tail call
+       is made.
+
 2002-04-06  Jason Merrill  <jason@redhat.com>
 
        * toplev.c (flag_no_inline, flag_really_no_inline): Default to 2.
index 5a7997c..6e753fa 100644 (file)
@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "basic-block.h"
 #include "output.h"
 #include "except.h"
+#include "tree.h"
 
 /* In case alternate_exit_block contains copy from pseudo, to return value,
    record the pseudo here.  In such case the pseudo must be set to function
@@ -730,6 +731,7 @@ optimize_sibling_and_tail_recursive_calls ()
   if (successful_sibling_call)
     {
       rtx insn;
+      tree arg;
 
       /* A sibling call sequence invalidates any REG_EQUIV notes made for
         this function's incoming arguments. 
@@ -754,6 +756,16 @@ optimize_sibling_and_tail_recursive_calls ()
          if (INSN_P (insn))
            purge_mem_unchanging_flag (PATTERN (insn));
        }
+
+      /* Similarly, invalidate RTX_UNCHANGING_P for any incoming
+        arguments passed in registers. */
+      for (arg = DECL_ARGUMENTS (current_function_decl); 
+          arg; 
+          arg = TREE_CHAIN (arg))
+       {
+         if (REG_P (DECL_RTL (arg)))
+           RTX_UNCHANGING_P (DECL_RTL (arg)) = false;
+       }
     }
 
   /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the 
index 7b92bce..ddd75d4 100644 (file)
@@ -1,3 +1,8 @@
+2002-04-06  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c/5120
+       * gcc.dg/20020406-1.c: New test.
+
 2002-04-04  David S. Miller  <davem@redhat.com>
 
        * gcc.c-torture/execute/20020404-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20020406-1.c b/gcc/testsuite/gcc.c-torture/execute/20020406-1.c
new file mode 100644 (file)
index 0000000..6d4967e
--- /dev/null
@@ -0,0 +1,123 @@
+// Origin: abbott@dima.unige.it
+// PR c/5120
+
+typedef unsigned int FFelem;
+
+FFelem FFmul(const FFelem x, const FFelem y)
+{
+  return x;
+}
+
+
+struct DUPFFstruct
+{
+  int maxdeg;
+  int deg;
+  FFelem *coeffs;
+};
+
+typedef struct DUPFFstruct *DUPFF;
+
+
+int DUPFFdeg(const DUPFF f)
+{
+  return f->deg;
+}
+
+
+DUPFF DUPFFnew(const int maxdeg)
+{
+  DUPFF ans = (DUPFF)malloc(sizeof(struct DUPFFstruct));
+  ans->coeffs = 0;
+  if (maxdeg >= 0) ans->coeffs = (FFelem*)malloc((maxdeg+1)*sizeof(FFelem));
+  ans->maxdeg = maxdeg;
+  ans->deg = -1;
+  return ans;
+}
+
+void DUPFFfree(DUPFF x)
+{
+}
+
+void DUPFFswap(DUPFF x, DUPFF y)
+{
+}
+
+
+DUPFF DUPFFcopy(const DUPFF x)
+{
+  return x;
+}
+
+
+void DUPFFshift_add(DUPFF f, const DUPFF g, int deg, const FFelem coeff)
+{
+}
+
+
+DUPFF DUPFFexgcd(DUPFF *fcofac, DUPFF *gcofac, const DUPFF f, const DUPFF g)
+{
+  DUPFF u, v, uf, ug, vf, vg;
+  FFelem q, lcu, lcvrecip, p;
+  int df, dg, du, dv;
+
+  printf("DUPFFexgcd called on degrees %d and %d\n", DUPFFdeg(f), DUPFFdeg(g));
+  if (DUPFFdeg(f) < DUPFFdeg(g)) return DUPFFexgcd(gcofac, fcofac, g, f);  /*** BUG IN THIS LINE ***/
+  if (DUPFFdeg(f) != 2 || DUPFFdeg(g) != 1) abort();
+  if (f->coeffs[0] == 0) return f;
+  /****** NEVER REACH HERE IN THE EXAMPLE ******/
+  p = 2;
+
+  df = DUPFFdeg(f);  if (df < 0) df = 0; /* both inputs are zero */
+  dg = DUPFFdeg(g);  if (dg < 0) dg = 0; /* one input is zero */
+  u = DUPFFcopy(f);
+  v = DUPFFcopy(g);
+
+  uf = DUPFFnew(dg); uf->coeffs[0] = 1; uf->deg = 0;
+  ug = DUPFFnew(df);
+  vf = DUPFFnew(dg);
+  vg = DUPFFnew(df); vg->coeffs[0] = 1; vg->deg = 0;
+
+  while (DUPFFdeg(v) > 0)
+  {
+    dv = DUPFFdeg(v);
+    lcvrecip = FFmul(1, v->coeffs[dv]);
+    while (DUPFFdeg(u) >= dv)
+    {
+      du = DUPFFdeg(u);
+      lcu = u->coeffs[du];
+      q = FFmul(lcu, lcvrecip);
+      DUPFFshift_add(u, v, du-dv, p-q);
+      DUPFFshift_add(uf, vf, du-dv, p-q);
+      DUPFFshift_add(ug, vg, du-dv, p-q);
+    }
+    DUPFFswap(u, v);
+    DUPFFswap(uf, vf);
+    DUPFFswap(ug, vg);
+  }
+  if (DUPFFdeg(v) == 0)
+  {
+    DUPFFswap(u, v);
+    DUPFFswap(uf, vf);
+    DUPFFswap(ug, vg);
+  }
+  DUPFFfree(vf);
+  DUPFFfree(vg);
+  DUPFFfree(v);
+  *fcofac = uf;
+  *gcofac = ug;
+  return u;
+}
+
+
+
+int main()
+{
+  DUPFF f, g, cf, cg, h;
+  f = DUPFFnew(1); f->coeffs[1] = 1; f->deg = 1;
+  g = DUPFFnew(2); g->coeffs[2] = 1; g->deg = 2;
+
+  printf("calling DUPFFexgcd on degrees %d and %d\n", DUPFFdeg(f), DUPFFdeg(g)) ;
+  h = DUPFFexgcd(&cf, &cg, f, g);
+  return 0;
+}