mirror of git://gcc.gnu.org/git/gcc.git
Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp.
2010-12-08 Richard Guenther <rguenther@suse.de> Sebastian Pop <sebastian.pop@amd.com> PR tree-optimization/45230 PR tree-optimization/45231 PR tree-optimization/45370 * sese.c (rename_uses): Returns a bool. Call recompute_tree_invariant_for_addr_expr only on the RHS of a GIMPLE_ASSIGN. (graphite_copy_stmts_from_block): Call fold_stmt_inplace when rename_uses returns true. * tree-ssa-copy.c (replace_exp): Add a comment about calling fold_stmt_inplace after replace_exp. * gcc.dg/graphite/id-pr45230-1.c: New. * gcc.dg/graphite/id-pr45231.c: New. * gfortran.dg/graphite/id-pr45370.f90: New. Co-Authored-By: Sebastian Pop <sebastian.pop@amd.com> From-SVN: r167609
This commit is contained in:
parent
09c2d63aa4
commit
fd66ea1a6f
|
|
@ -1,3 +1,17 @@
|
||||||
|
2010-12-08 Richard Guenther <rguenther@suse.de>
|
||||||
|
Sebastian Pop <sebastian.pop@amd.com>
|
||||||
|
|
||||||
|
PR tree-optimization/45230
|
||||||
|
PR tree-optimization/45231
|
||||||
|
PR tree-optimization/45370
|
||||||
|
* sese.c (rename_uses): Returns a bool. Call
|
||||||
|
recompute_tree_invariant_for_addr_expr only on the RHS of a
|
||||||
|
GIMPLE_ASSIGN.
|
||||||
|
(graphite_copy_stmts_from_block): Call fold_stmt_inplace when
|
||||||
|
rename_uses returns true.
|
||||||
|
* tree-ssa-copy.c (replace_exp): Add a comment about calling
|
||||||
|
fold_stmt_inplace after replace_exp.
|
||||||
|
|
||||||
2010-12-08 Mike Stump <mikestump@comcast.net>
|
2010-12-08 Mike Stump <mikestump@comcast.net>
|
||||||
|
|
||||||
PR debug/46749
|
PR debug/46749
|
||||||
|
|
|
||||||
17
gcc/sese.c
17
gcc/sese.c
|
|
@ -470,14 +470,15 @@ set_rename (htab_t rename_map, tree old_name, tree expr)
|
||||||
substitution map RENAME_MAP, inserting the gimplification code at
|
substitution map RENAME_MAP, inserting the gimplification code at
|
||||||
GSI_TGT, for the translation REGION, with the original copied
|
GSI_TGT, for the translation REGION, with the original copied
|
||||||
statement in LOOP, and using the induction variable renaming map
|
statement in LOOP, and using the induction variable renaming map
|
||||||
IV_MAP. */
|
IV_MAP. Returns true when something has been renamed. */
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||||
sese region, loop_p loop, VEC (tree, heap) *iv_map)
|
sese region, loop_p loop, VEC (tree, heap) *iv_map)
|
||||||
{
|
{
|
||||||
use_operand_p use_p;
|
use_operand_p use_p;
|
||||||
ssa_op_iter op_iter;
|
ssa_op_iter op_iter;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
if (is_gimple_debug (copy))
|
if (is_gimple_debug (copy))
|
||||||
{
|
{
|
||||||
|
|
@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||||
else
|
else
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
|
FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
|
||||||
|
|
@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||||
|| SSA_NAME_IS_DEFAULT_DEF (old_name))
|
|| SSA_NAME_IS_DEFAULT_DEF (old_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
new_expr = get_rename (rename_map, old_name);
|
new_expr = get_rename (rename_map, old_name);
|
||||||
if (new_expr)
|
if (new_expr)
|
||||||
{
|
{
|
||||||
|
|
@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||||
gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
|
gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
|
||||||
replace_exp (use_p, new_expr);
|
replace_exp (use_p, new_expr);
|
||||||
|
|
||||||
|
if (TREE_CODE (new_expr) == INTEGER_CST
|
||||||
if (TREE_CODE (new_expr) == INTEGER_CST)
|
&& is_gimple_assign (copy))
|
||||||
{
|
{
|
||||||
tree rhs = gimple_assign_rhs1 (copy);
|
tree rhs = gimple_assign_rhs1 (copy);
|
||||||
|
|
||||||
|
|
@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||||
|
|
||||||
set_rename (rename_map, old_name, new_expr);
|
set_rename (rename_map, old_name, new_expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Duplicates the statements of basic block BB into basic block NEW_BB
|
/* Duplicates the statements of basic block BB into basic block NEW_BB
|
||||||
|
|
@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
|
||||||
set_rename (rename_map, old_name, new_name);
|
set_rename (rename_map, old_name, new_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map);
|
if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map))
|
||||||
|
fold_stmt_inplace (copy);
|
||||||
|
|
||||||
update_stmt (copy);
|
update_stmt (copy);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
||||||
|
2010-12-08 Richard Guenther <rguenther@suse.de>
|
||||||
|
Sebastian Pop <sebastian.pop@amd.com>
|
||||||
|
|
||||||
|
PR tree-optimization/45230
|
||||||
|
PR tree-optimization/45231
|
||||||
|
PR tree-optimization/45370
|
||||||
|
* gcc.dg/graphite/id-pr45230-1.c: New.
|
||||||
|
* gcc.dg/graphite/id-pr45231.c: New.
|
||||||
|
* gfortran.dg/graphite/id-pr45370.f90: New.
|
||||||
|
|
||||||
2010-12-08 Nathan Froyd <froydnj@codesourcery.com>
|
2010-12-08 Nathan Froyd <froydnj@codesourcery.com>
|
||||||
|
|
||||||
PR c++/45329
|
PR c++/45329
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* Copyright (C) 2002 Free Software Foundation.
|
||||||
|
|
||||||
|
Test strncmp with various combinations of pointer alignments and lengths to
|
||||||
|
make sure any optimizations in the library are correct.
|
||||||
|
|
||||||
|
Written by Michael Meissner, March 9, 2002. */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifndef MAX_OFFSET
|
||||||
|
#define MAX_OFFSET (sizeof (long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_TEST
|
||||||
|
#define MAX_TEST (8 * sizeof (long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_EXTRA
|
||||||
|
#define MAX_EXTRA (sizeof (long long))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
|
||||||
|
|
||||||
|
static union {
|
||||||
|
unsigned char buf[MAX_LENGTH];
|
||||||
|
long long align_int;
|
||||||
|
long double align_fp;
|
||||||
|
} u1, u2;
|
||||||
|
|
||||||
|
void
|
||||||
|
test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
|
||||||
|
{
|
||||||
|
int value = strncmp ((char *) s1, (char *) s2, len);
|
||||||
|
|
||||||
|
if (expected < 0 && value >= 0)
|
||||||
|
__builtin_abort ();
|
||||||
|
else if (expected == 0 && value != 0)
|
||||||
|
__builtin_abort ();
|
||||||
|
else if (expected > 0 && value <= 0)
|
||||||
|
__builtin_abort ();
|
||||||
|
}
|
||||||
|
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
size_t off1, off2, len, i;
|
||||||
|
unsigned char *buf1, *buf2;
|
||||||
|
unsigned char *mod1, *mod2;
|
||||||
|
unsigned char *p1, *p2;
|
||||||
|
|
||||||
|
for (off1 = 0; off1 < MAX_OFFSET; off1++)
|
||||||
|
for (off2 = 0; off2 < MAX_OFFSET; off2++)
|
||||||
|
for (len = 0; len < MAX_TEST; len++)
|
||||||
|
{
|
||||||
|
p1 = u1.buf;
|
||||||
|
for (i = 0; i < off1; i++)
|
||||||
|
*p1++ = '\0';
|
||||||
|
|
||||||
|
buf1 = p1;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
*p1++ = 'a';
|
||||||
|
|
||||||
|
mod1 = p1;
|
||||||
|
for (i = 0; i < MAX_EXTRA; i++)
|
||||||
|
*p1++ = 'x';
|
||||||
|
|
||||||
|
p2 = u2.buf;
|
||||||
|
for (i = 0; i < off2; i++)
|
||||||
|
*p2++ = '\0';
|
||||||
|
|
||||||
|
buf2 = p2;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
*p2++ = 'a';
|
||||||
|
|
||||||
|
mod2 = p2;
|
||||||
|
for (i = 0; i < MAX_EXTRA; i++)
|
||||||
|
*p2++ = 'x';
|
||||||
|
|
||||||
|
mod1[0] = '\0';
|
||||||
|
mod2[0] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, 0);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = 'a';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, +1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = '\0';
|
||||||
|
mod2[0] = 'a';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, -1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = 'b';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = 'c';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, -1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = 'c';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = 'b';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, +1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = 'b';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = (unsigned char)'\251';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, -1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = (unsigned char)'\251';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = 'b';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, +1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = (unsigned char)'\251';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = (unsigned char)'\252';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, -1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
|
||||||
|
mod1[0] = (unsigned char)'\252';
|
||||||
|
mod1[1] = '\0';
|
||||||
|
mod2[0] = (unsigned char)'\251';
|
||||||
|
mod2[1] = '\0';
|
||||||
|
test (buf1, buf2, MAX_LENGTH, +1);
|
||||||
|
test (buf1, buf2, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__builtin_exit (0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
void
|
||||||
|
f (n, ppt, xrot)
|
||||||
|
{
|
||||||
|
int tileWidth;
|
||||||
|
int nlwSrc;
|
||||||
|
int srcx;
|
||||||
|
int v3, v4;
|
||||||
|
register unsigned long ca1, cx1, ca2, cx2;
|
||||||
|
unsigned long *pSrcLine;
|
||||||
|
register unsigned long *pDst;
|
||||||
|
register unsigned long *pSrc;
|
||||||
|
register unsigned long b, tmp;
|
||||||
|
unsigned long tileEndMask;
|
||||||
|
int v1, v2;
|
||||||
|
int tileEndPart;
|
||||||
|
int needFirst;
|
||||||
|
tileEndPart = 0;
|
||||||
|
v1 = tileEndPart << 5;
|
||||||
|
v2 = 32 - v1;
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
if ((srcx = (ppt - xrot) % tileWidth) < 0)
|
||||||
|
if (needFirst)
|
||||||
|
if (nlwSrc == 1)
|
||||||
|
{
|
||||||
|
tmp = b;
|
||||||
|
if (tileEndPart)
|
||||||
|
b = (*pSrc & tileEndMask) | (*pSrcLine >> v1);
|
||||||
|
}
|
||||||
|
if (tileEndPart)
|
||||||
|
b = (tmp << v1) | (b >> v2);
|
||||||
|
if (v4 != 32)
|
||||||
|
*pDst = (*pDst & ((tmp << v3) | (b >> v4) & ca1 ^ cx1)
|
||||||
|
^ (((tmp << v3) | (b >> v4)) & ca2 ^ cx2));
|
||||||
|
*pDst = *pDst & tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
!
|
||||||
|
type :: t
|
||||||
|
real :: r
|
||||||
|
integer :: i
|
||||||
|
character(3) :: chr
|
||||||
|
end type t
|
||||||
|
|
||||||
|
type :: t2
|
||||||
|
real :: r(2, 2)
|
||||||
|
integer :: i
|
||||||
|
character(3) :: chr
|
||||||
|
end type t2
|
||||||
|
|
||||||
|
type :: s
|
||||||
|
type(t), pointer :: t(:)
|
||||||
|
end type s
|
||||||
|
|
||||||
|
integer, parameter :: sh(2) = (/2,2/)
|
||||||
|
real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh)
|
||||||
|
real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh)
|
||||||
|
|
||||||
|
type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/)
|
||||||
|
character(4), target :: tar2(2) = (/"abcd","efgh"/)
|
||||||
|
type(s), target :: tar3
|
||||||
|
character(2), target :: tar4(2) = (/"ab","cd"/)
|
||||||
|
type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/)
|
||||||
|
|
||||||
|
integer, pointer :: ptr(:)
|
||||||
|
character(2), pointer :: ptr2(:)
|
||||||
|
real, pointer :: ptr3(:)
|
||||||
|
|
||||||
|
!_______________component subreference___________
|
||||||
|
ptr => tar1%i
|
||||||
|
ptr = ptr + 1 ! check the scalarizer is OK
|
||||||
|
|
||||||
|
if (any (ptr .ne. (/3, 5/))) call abort ()
|
||||||
|
if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort ()
|
||||||
|
if (any (tar1%i .ne. (/3, 5/))) call abort ()
|
||||||
|
|
||||||
|
! Make sure that the other components are not touched.
|
||||||
|
if (any (tar1%r .ne. (/1.0, 3.0/))) call abort ()
|
||||||
|
if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort ()
|
||||||
|
|
||||||
|
! Check that the pointer is passed correctly as an actual argument.
|
||||||
|
call foo (ptr)
|
||||||
|
if (any (tar1%i .ne. (/2, 4/))) call abort ()
|
||||||
|
|
||||||
|
! And that dummy pointers are OK too.
|
||||||
|
call bar (ptr)
|
||||||
|
if (any (tar1%i .ne. (/101, 103/))) call abort ()
|
||||||
|
|
||||||
|
!_______________substring subreference___________
|
||||||
|
ptr2 => tar2(:)(2:3)
|
||||||
|
ptr2 = ptr2(:)(2:2)//"z" ! again, check the scalarizer
|
||||||
|
|
||||||
|
if (any (ptr2 .ne. (/"cz", "gz"/))) call abort ()
|
||||||
|
if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort ()
|
||||||
|
if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort ()
|
||||||
|
|
||||||
|
!_______________substring component subreference___________
|
||||||
|
ptr2 => tar1(:)%chr(1:2)
|
||||||
|
ptr2 = ptr2(:)(2:2)//"q" ! yet again, check the scalarizer
|
||||||
|
if (any (ptr2 .ne. (/"bq","fq"/))) call abort ()
|
||||||
|
if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort ()
|
||||||
|
|
||||||
|
!_______________trailing array element subreference___________
|
||||||
|
ptr3 => tar5%r(1,2)
|
||||||
|
ptr3 = (/99.0, 999.0/)
|
||||||
|
if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort ()
|
||||||
|
if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort ()
|
||||||
|
|
||||||
|
!_______________forall assignment___________
|
||||||
|
ptr2 => tar2(:)(1:2)
|
||||||
|
forall (i = 1:2) ptr2(i)(1:1) = "z"
|
||||||
|
if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort ()
|
||||||
|
|
||||||
|
!_______________something more complicated___________
|
||||||
|
tar3%t => tar1
|
||||||
|
ptr3 => tar3%t%r
|
||||||
|
ptr3 = cos (ptr3)
|
||||||
|
if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort ()
|
||||||
|
|
||||||
|
ptr2 => tar3%t(:)%chr(2:3)
|
||||||
|
ptr2 = " x"
|
||||||
|
if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort ()
|
||||||
|
|
||||||
|
!_______________check non-subref works still___________
|
||||||
|
ptr2 => tar4
|
||||||
|
if (any (ptr2 .ne. (/"ab","cd"/))) call abort ()
|
||||||
|
|
||||||
|
contains
|
||||||
|
subroutine foo (arg)
|
||||||
|
integer :: arg(:)
|
||||||
|
arg = arg - 1
|
||||||
|
end subroutine
|
||||||
|
subroutine bar (arg)
|
||||||
|
integer, pointer :: arg(:)
|
||||||
|
arg = arg + 99
|
||||||
|
end subroutine
|
||||||
|
end
|
||||||
|
|
@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val)
|
||||||
|
|
||||||
Use this version when not const/copy propagating values. For example,
|
Use this version when not const/copy propagating values. For example,
|
||||||
PRE uses this version when building expressions as they would appear
|
PRE uses this version when building expressions as they would appear
|
||||||
in specific blocks taking into account actions of PHI nodes. */
|
in specific blocks taking into account actions of PHI nodes.
|
||||||
|
|
||||||
|
The statement in which an expression has been replaced should be
|
||||||
|
folded using fold_stmt_inplace. */
|
||||||
|
|
||||||
void
|
void
|
||||||
replace_exp (use_operand_p op_p, tree val)
|
replace_exp (use_operand_p op_p, tree val)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue