From: Eric Botcazou Date: Thu, 11 Apr 2013 16:15:25 +0000 (+0000) Subject: stor-layout.c (skip_simple_constant_arithmetic): Move to... X-Git-Tag: releases/gcc-4.9.0~6494 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=966b587e0b513fa8075beaf9ab184ed74686ee97;p=thirdparty%2Fgcc.git stor-layout.c (skip_simple_constant_arithmetic): Move to... * stor-layout.c (skip_simple_constant_arithmetic): Move to... * tree.c (skip_simple_constant_arithmetic): ...here and make public. (skip_simple_arithmetic): Tidy up. * tree.h (skip_simple_constant_arithmetic): Declare. ada/ * gcc-interface/decl.c (elaborate_expression_1): Skip only constant arithmetics when looking for a read-only variable in the expression. From-SVN: r197815 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd599e61b94a..26f88ba5a6a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-04-11 Eric Botcazou + + * stor-layout.c (skip_simple_constant_arithmetic): Move to... + * tree.c (skip_simple_constant_arithmetic): ...here and make public. + (skip_simple_arithmetic): Tidy up. + * tree.h (skip_simple_constant_arithmetic): Declare. + 2013-04-11 Naveen H.S * config/aarch64/aarch64.h (REVERSIBLE_CC_MODE): Define. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 53784aa47331..49f89b65a864 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Eric Botcazou + + * gcc-interface/decl.c (elaborate_expression_1): Skip only constant + arithmetics when looking for a read-only variable in the expression. + 2013-04-11 Javier Miranda * check.ads, exp_ch6.adb (Install_Null_Excluding_Check): No check in diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 7342fa3c9ed6..e65701b9a057 100644 --- a/gcc/ada/gcc-interface/decl.c +++ b/gcc/ada/gcc-interface/decl.c @@ -6186,12 +6186,13 @@ elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name, expr_variable_p = false; else { - /* Skip any conversions and simple arithmetics to see if the expression - is based on a read-only variable. + /* Skip any conversions and simple constant arithmetics to see if the + expression is based on a read-only variable. ??? This really should remain read-only, but we have to think about the typing of the tree here. */ - tree inner - = skip_simple_arithmetic (remove_conversions (gnu_expr, true)); + tree inner = remove_conversions (gnu_expr, true); + + inner = skip_simple_constant_arithmetic (inner); if (handled_component_p (inner)) { diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 5b89f749f7a7..67dd9587b995 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -98,32 +98,6 @@ variable_size (tree size) /* An array of functions used for self-referential size computation. */ static GTY(()) vec *size_functions; -/* Look inside EXPR into simple arithmetic operations involving constants. - Return the outermost non-arithmetic or non-constant node. */ - -static tree -skip_simple_constant_arithmetic (tree expr) -{ - while (true) - { - if (UNARY_CLASS_P (expr)) - expr = TREE_OPERAND (expr, 0); - else if (BINARY_CLASS_P (expr)) - { - if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) - expr = TREE_OPERAND (expr, 0); - else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 1); - else - break; - } - else - break; - } - - return expr; -} - /* Similar to copy_tree_r but do not copy component references involving PLACEHOLDER_EXPRs. These nodes are spotted in find_placeholder_in_expr and substituted in substitute_in_expr. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae1fd6de5a6e..21b44e70b735 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Eric Botcazou + + * gnat.dg/array23.adb: New test. + * gnat.dg/array23_pkg[123].ads: New helpers. + 2013-04-11 Jeff Law PR tree-optimization/56900 diff --git a/gcc/testsuite/gnat.dg/array23.adb b/gcc/testsuite/gnat.dg/array23.adb new file mode 100644 index 000000000000..2196ce5964fd --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23.adb @@ -0,0 +1,10 @@ +-- { dg-do link } + +with Array23_Pkg1; +with Array23_Pkg2; + +procedure Array23 is + A : Array23_Pkg1.Arr; +begin + A(Array23_Pkg2.One)(1) := 0; +end; diff --git a/gcc/testsuite/gnat.dg/array23_pkg1.ads b/gcc/testsuite/gnat.dg/array23_pkg1.ads new file mode 100644 index 000000000000..d0bc136f96d4 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg1.ads @@ -0,0 +1,13 @@ +with Array23_Pkg2; + +package Array23_Pkg1 is + + C2 : Natural := Array23_Pkg2.C1; + + subtype Index is Natural range 0 .. C2; + + type Inner is array (Index) of Natural; + + type Arr is array (Array23_Pkg2.Index) of Inner; + +end Array23_Pkg1; diff --git a/gcc/testsuite/gnat.dg/array23_pkg2.ads b/gcc/testsuite/gnat.dg/array23_pkg2.ads new file mode 100644 index 000000000000..8993ffa1e5d8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg2.ads @@ -0,0 +1,11 @@ +with Array23_Pkg3; + +package Array23_Pkg2 is + + C1 : Natural := Array23_Pkg3.C0; + + type Enum is (Zero, One, Two); + + subtype Index is Enum range One .. Enum'val(C1); + +end Array23_Pkg2; diff --git a/gcc/testsuite/gnat.dg/array23_pkg3.ads b/gcc/testsuite/gnat.dg/array23_pkg3.ads new file mode 100644 index 000000000000..1a6afa86f3c7 --- /dev/null +++ b/gcc/testsuite/gnat.dg/array23_pkg3.ads @@ -0,0 +1,5 @@ +package Array23_Pkg3 is + + C0 : Natural := 2; + +end Array23_Pkg3; diff --git a/gcc/tree.c b/gcc/tree.c index ba3dcddaf42c..d8f2424a1ef0 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -2830,14 +2830,12 @@ save_expr (tree expr) return t; } -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ tree skip_simple_arithmetic (tree expr) { - tree inner; - /* We don't care about whether this can be used as an lvalue in this context. */ while (TREE_CODE (expr) == NON_LVALUE_EXPR) @@ -2847,17 +2845,16 @@ skip_simple_arithmetic (tree expr) a constant, it will be more efficient to not make another SAVE_EXPR since it will allow better simplification and GCSE will be able to merge the computations if they actually occur. */ - inner = expr; - while (1) + while (true) { - if (UNARY_CLASS_P (inner)) - inner = TREE_OPERAND (inner, 0); - else if (BINARY_CLASS_P (inner)) + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) { - if (tree_invariant_p (TREE_OPERAND (inner, 1))) - inner = TREE_OPERAND (inner, 0); - else if (tree_invariant_p (TREE_OPERAND (inner, 0))) - inner = TREE_OPERAND (inner, 1); + if (tree_invariant_p (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (tree_invariant_p (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); else break; } @@ -2865,9 +2862,37 @@ skip_simple_arithmetic (tree expr) break; } - return inner; + return expr; } +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +tree +skip_simple_constant_arithmetic (tree expr) +{ + while (TREE_CODE (expr) == NON_LVALUE_EXPR) + expr = TREE_OPERAND (expr, 0); + + while (true) + { + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) + { + if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); + else + break; + } + else + break; + } + + return expr; +} /* Return which tree structure is used by T. */ diff --git a/gcc/tree.h b/gcc/tree.h index aa424c0e5444..be43440783d3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5339,11 +5339,16 @@ extern tree staticp (tree); extern tree save_expr (tree); -/* Look inside EXPR and into any simple arithmetic operations. Return - the innermost non-arithmetic node. */ +/* Look inside EXPR into any simple arithmetic operations. Return the + outermost non-arithmetic or non-invariant node. */ extern tree skip_simple_arithmetic (tree); +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +extern tree skip_simple_constant_arithmetic (tree); + /* Return which tree structure is used by T. */ enum tree_node_structure_enum tree_node_structure (const_tree);