diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-01-05 11:23:40 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-01-05 11:23:40 +0000 |
commit | 5e9fba51b58a9d9dcd28b6ad3992ec4d8640eae2 (patch) | |
tree | e872641afdccd098468de2882c535d6f0cd0cd4e /gcc | |
parent | 75fee9f255425ea84d63dd63dbf6f07af7c036d7 (diff) | |
download | gcc-5e9fba51b58a9d9dcd28b6ad3992ec4d8640eae2.zip gcc-5e9fba51b58a9d9dcd28b6ad3992ec4d8640eae2.tar.gz gcc-5e9fba51b58a9d9dcd28b6ad3992ec4d8640eae2.tar.bz2 |
re PR tree-optimization/47005 (ACATS c62002a is miscompiled at -O2)
PR tree-optimization/47005
* tree-sra.c (struct access): Add 'non_addressable' bit.
(create_access): Set it for a DECL_NONADDRESSABLE_P field.
(decide_one_param_reduction): Return 0 if the parameter is passed by
reference and one of the accesses in the group is non_addressable.
From-SVN: r168508
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt14.adb | 25 | ||||
-rw-r--r-- | gcc/tree-sra.c | 14 |
4 files changed, 50 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 01412bd..d25e30c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-01-05 Eric Botcazou <ebotcazou@adacore.com> + + PR tree-optimization/47005 + * tree-sra.c (struct access): Add 'non_addressable' bit. + (create_access): Set it for a DECL_NONADDRESSABLE_P field. + (decide_one_param_reduction): Return 0 if the parameter is passed by + reference and one of the accesses in the group is non_addressable. + 2011-01-04 Eric Botcazou <ebotcazou@adacore.com> PR tree-optimization/47056 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 208304c..867e6a0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-01-05 Eric Botcazou <ebotcazou@adacore.com> + + * gnat.dg/opt14.adb: New test. + 2011-01-05 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/46017 diff --git a/gcc/testsuite/gnat.dg/opt14.adb b/gcc/testsuite/gnat.dg/opt14.adb new file mode 100644 index 0000000..61bc731 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt14.adb @@ -0,0 +1,25 @@ +-- { dg-do run } +-- { dg-options "-O2" } + +procedure Opt14 is + + type Rec is record + I1, I2, I3 : Integer; + end record; + + type Ptr is access Rec; + + P : Ptr := new Rec'(0,0,0); + + procedure Sub (R : In Out Rec) is + begin + R.I3 := R.I3 - 1; + end; + +begin + P.all := (1,2,3); + Sub (P.all); + if P.all /= (1,2,2) then + raise Program_Error; + end if; +end; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 14fef47..c2ec204 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -173,6 +173,9 @@ struct access entirely? */ unsigned total_scalarization : 1; + /* Is this access an access to a non-addressable field? */ + unsigned non_addressable : 1; + /* Is this access currently in the work queue? */ unsigned grp_queued : 1; @@ -816,6 +819,10 @@ create_access (tree expr, gimple stmt, bool write) access->grp_unscalarizable_region = unscalarizable_region; access->stmt = stmt; + if (TREE_CODE (expr) == COMPONENT_REF + && DECL_NONADDRESSABLE_P (TREE_OPERAND (expr, 1))) + access->non_addressable = 1; + return access; } @@ -3666,13 +3673,18 @@ decide_one_param_reduction (struct access *repr) for (; repr; repr = repr->next_grp) { gcc_assert (parm == repr->base); - new_param_count++; + + /* Taking the address of a non-addressable field is verboten. */ + if (by_ref && repr->non_addressable) + return 0; if (!by_ref || (!repr->grp_maybe_modified && !repr->grp_not_necessarilly_dereferenced)) total_size += repr->size; else total_size += cur_parm_size; + + new_param_count++; } gcc_assert (new_param_count > 0); |