aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/utils2.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2021-04-28 09:43:02 +0200
committerEric Botcazou <ebotcazou@adacore.com>2021-04-28 09:46:22 +0200
commit852dd866e2faba95cb407c98d31a48b6aae66677 (patch)
tree5fdf04f62c9004fc0406ef82636e0f496ff35fab /gcc/ada/gcc-interface/utils2.c
parentd91e7eab3a2c3957c2220ad71e62d9fc78cccb9b (diff)
downloadgcc-852dd866e2faba95cb407c98d31a48b6aae66677.zip
gcc-852dd866e2faba95cb407c98d31a48b6aae66677.tar.gz
gcc-852dd866e2faba95cb407c98d31a48b6aae66677.tar.bz2
Fix loss of optimization of array iteration due to inlining
This helps loop-invariant motion to hoist complicated offset computations. gcc/ada/ * gcc-interface/trans.c (language_function): Add comment. (loop_info_d): Add fndecl and invariants fields. (find_loop_for): Test fndecl instead of the context of var. (find_loop): New function. (Regular_Loop_to_gnu): Fold back into... (Loop_Statement_to_gnu): ...this. Emit invariants on entry, if any. (gnat_to_gnu) <N_Selected_Component>: Record nonconstant invariant offset computations in loops when optimization is enabled. * gcc-interface/utils2.c (gnat_invariant_expr): Handle BIT_AND_EXPR. gcc/testsuite/ * gnat.dg/opt93.ads, gnat.dg/opt93.adb: New test.
Diffstat (limited to 'gcc/ada/gcc-interface/utils2.c')
-rw-r--r--gcc/ada/gcc-interface/utils2.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 316033b..83cc794 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -2946,6 +2946,17 @@ gnat_invariant_expr (tree expr)
if (TREE_CONSTANT (expr))
return fold_convert (type, expr);
+ /* Deal with aligning patterns. */
+ if (TREE_CODE (expr) == BIT_AND_EXPR
+ && TREE_CONSTANT (TREE_OPERAND (expr, 1)))
+ {
+ tree op0 = gnat_invariant_expr (TREE_OPERAND (expr, 0));
+ if (op0)
+ return fold_build2 (BIT_AND_EXPR, type, op0, TREE_OPERAND (expr, 1));
+ else
+ return NULL_TREE;
+ }
+
/* Deal with addition or subtraction of constants. */
if (is_simple_additive_expression (expr, &add, &cst, &minus_p))
{