Commit b1896e61 by Mark Mitchell Committed by Mark Mitchell

re PR rtl-optimization/5120 (tail recursion incorrect using -O2)

	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.

From-SVN: r51969
parent b0148884
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> 2002-04-06 Jason Merrill <jason@redhat.com>
* toplev.c (flag_no_inline, flag_really_no_inline): Default to 2. * toplev.c (flag_no_inline, flag_really_no_inline): Default to 2.
......
...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h" #include "basic-block.h"
#include "output.h" #include "output.h"
#include "except.h" #include "except.h"
#include "tree.h"
/* In case alternate_exit_block contains copy from pseudo, to return value, /* 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 record the pseudo here. In such case the pseudo must be set to function
...@@ -730,6 +731,7 @@ optimize_sibling_and_tail_recursive_calls () ...@@ -730,6 +731,7 @@ optimize_sibling_and_tail_recursive_calls ()
if (successful_sibling_call) if (successful_sibling_call)
{ {
rtx insn; rtx insn;
tree arg;
/* A sibling call sequence invalidates any REG_EQUIV notes made for /* A sibling call sequence invalidates any REG_EQUIV notes made for
this function's incoming arguments. this function's incoming arguments.
...@@ -754,6 +756,16 @@ optimize_sibling_and_tail_recursive_calls () ...@@ -754,6 +756,16 @@ optimize_sibling_and_tail_recursive_calls ()
if (INSN_P (insn)) if (INSN_P (insn))
purge_mem_unchanging_flag (PATTERN (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 /* There may have been NOTE_INSN_BLOCK_{BEGIN,END} notes in the
......
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> 2002-04-04 David S. Miller <davem@redhat.com>
* gcc.c-torture/execute/20020404-1.c: New test. * gcc.c-torture/execute/20020404-1.c: New test.
......
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment