From patchwork Wed Dec 8 20:22:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Pop X-Patchwork-Id: 74777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id CB44DB70A5 for ; Thu, 9 Dec 2010 07:23:15 +1100 (EST) Received: (qmail 29640 invoked by alias); 8 Dec 2010 20:23:01 -0000 Received: (qmail 29612 invoked by uid 22791); 8 Dec 2010 20:22:57 -0000 X-SWARE-Spam-Status: No, hits=-2.2 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_TM, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-gw0-f50.google.com (HELO mail-gw0-f50.google.com) (74.125.83.50) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 08 Dec 2010 20:22:50 +0000 Received: by gwaa18 with SMTP id a18so1251881gwa.9 for ; Wed, 08 Dec 2010 12:22:48 -0800 (PST) Received: by 10.42.241.71 with SMTP id ld7mr250308icb.404.1291839768171; Wed, 08 Dec 2010 12:22:48 -0800 (PST) Received: from napoca ([163.181.251.115]) by mx.google.com with ESMTPS id 34sm842075ibi.20.2010.12.08.12.22.45 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 08 Dec 2010 12:22:47 -0800 (PST) Received: by napoca (sSMTP sendmail emulation); Wed, 08 Dec 2010 14:22:44 -0600 From: Sebastian Pop To: gcc-patches@gcc.gnu.org Cc: rguenther@suse.de, Sebastian Pop Subject: [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp. Date: Wed, 8 Dec 2010 14:22:36 -0600 Message-Id: <1291839756-26718-1-git-send-email-sebpop@gmail.com> In-Reply-To: References: X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, I am testing this patch on amd64-linux. Ok for trunk if that passes? Thanks, Sebastian 2010-12-08 Richard Guenther Sebastian Pop 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. --- gcc/ChangeLog | 14 ++ gcc/sese.c | 17 ++- gcc/testsuite/ChangeLog | 10 ++ gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c | 140 +++++++++++++++++++++ gcc/testsuite/gcc.dg/graphite/id-pr45231.c | 37 ++++++ gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 | 100 +++++++++++++++ gcc/tree-ssa-copy.c | 5 +- 7 files changed, 316 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45231.c create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff52686..95bd5c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-12-08 Richard Guenther + Sebastian Pop + + 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-07 Paul Koning * config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define. diff --git a/gcc/sese.c b/gcc/sese.c index 65f8556..3bf6bea 100644 --- a/gcc/sese.c +++ b/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 GSI_TGT, for the translation REGION, with the original copied 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, sese region, loop_p loop, VEC (tree, heap) *iv_map) { use_operand_p use_p; ssa_op_iter op_iter; + bool changed = false; if (is_gimple_debug (copy)) { @@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt, else gcc_unreachable (); - return; + return false; } 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)) continue; + changed = true; new_expr = get_rename (rename_map, old_name); 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); 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); @@ -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); } + + return changed; } /* 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); } - 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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 96275ed..3cf399d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2010-12-08 Richard Guenther + Sebastian Pop + + 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-07 Sebastian Pop PR tree-optimization/44676 diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c new file mode 100644 index 0000000..ba14fe5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c @@ -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 +#include + +#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); +} diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45231.c b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c new file mode 100644 index 0000000..01e9a67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c @@ -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; + } +} diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 new file mode 100644 index 0000000..94eebd1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 @@ -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 diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index d552c3a..8897275 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val) Use this version when not const/copy propagating values. For example, 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 replace_exp (use_operand_p op_p, tree val)