diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b134c9419f2..3948f3cab79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,10 +1,23 @@ +2007-07-11 Eric Botcazou + + PR tree-optimization/32589 + * doc/tree-ssa.texi (Rough GIMPLE Grammar): Add missing rule. + * tree-gimple.c (is_gimple_min_invariant): Clarify head comment. + * tree-ssa-propagate.c (valid_gimple_expression_p): New + predicate, extracted from... + (set_rhs): ...here. Call it for the expression on entry. + * tree-ssa-propagate.h (valid_gimple_expression_p): Declare. + * tree-ssa-sccvn.c: Include tree-ssa-propagate.h. + (simplify_binary_expression): Use valid_gimple_expression_p + to validate the simplification. + * Makefile.in (tree-ssa-sccvn.o): Depends on tree-ssa-propagate.h. + 2007-07-11 Danny Smith * config/i386/cygming.h (PREFERRED_DEBUGGING_TYPE): Define to DWARF2_DEBUG on 32 bit target too. (DWARF2_UNWIND_INFO): Reorganize 64-bit vs 32-bit definition. - 2007-07-11 Nick Clifton * config/m32r/m32r.h (INITIALIZE_TRAMPOLINE): Provide alternative diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c084f0a838b..3b490c04e37 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2042,7 +2042,7 @@ tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \ alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(HASHTAB_H) $(TREE_GIMPLE_H) \ - $(TREE_INLINE_H) tree-iterator.h tree-ssa-sccvn.h + $(TREE_INLINE_H) tree-iterator.h tree-ssa-propagate.h tree-ssa-sccvn.h tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \ $(TREE_H) $(TREE_FLOW_H) $(HASHTAB_H) langhooks.h tree-pass.h \ $(TREE_DUMP_H) $(DIAGNOSTIC_H) tree-ssa-sccvn.h diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi index 1322875df14..fcbee88fbe3 100644 --- a/gcc/doc/tree-ssa.texi +++ b/gcc/doc/tree-ssa.texi @@ -1,4 +1,4 @@ -@c Copyright (c) 2004, 2005 Free Software Foundation, Inc. +@c Copyright (c) 2004, 2005, 2007 Free Software Foundation, Inc. @c Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -680,7 +680,7 @@ void f() bitfieldref : BIT_FIELD_REF op0 -> inner-compref op1 -> CONST - op2 -> var + op2 -> val compref : inner-compref | TARGET_MEM_REF @@ -718,6 +718,8 @@ void f() op1 -> val val : ID + | invariant ADDR_EXPR + op0 -> addr-expr-arg | CONST rhs : lhs diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6eda430f559..00456185681 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-07-11 Eric Botcazou + + * gnat.dg/invariant_index.ad[sb]: New test. + 2007-07-11 Paolo Carlini PR c++/32560 diff --git a/gcc/testsuite/gnat.dg/invariant_index.adb b/gcc/testsuite/gnat.dg/invariant_index.adb new file mode 100644 index 00000000000..69ad47ac192 --- /dev/null +++ b/gcc/testsuite/gnat.dg/invariant_index.adb @@ -0,0 +1,14 @@ +-- { dg-do compile } +-- { dg-options "-O -gnatp" } + +package body Invariant_Index is + + procedure Proc (S : String) is + N : constant Integer := S'Length; + begin + Name_Buffer (1 + N .. Name_Len + N) := Name_Buffer (1 .. Name_Len); + Name_Buffer (1 .. N) := S; + Name_Len := Name_Len + N; + end; + +end Invariant_Index; diff --git a/gcc/testsuite/gnat.dg/invariant_index.ads b/gcc/testsuite/gnat.dg/invariant_index.ads new file mode 100644 index 00000000000..77c46fc39e8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/invariant_index.ads @@ -0,0 +1,8 @@ +package Invariant_Index is + + Name_Buffer : String (1 .. 100); + Name_Len : Natural; + + procedure Proc (S : String); + +end Invariant_Index; diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 16caf0ad573..8f88f1d9866 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -166,7 +166,7 @@ is_gimple_addressable (tree t) || INDIRECT_REF_P (t)); } -/* Return true if T is function invariant. Or rather a restricted +/* Return true if T is a GIMPLE minimal invariant. It's a restricted form of function invariant. */ bool diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index df31e25f8ff..096664d90d1 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -573,24 +573,17 @@ get_rhs (tree stmt) } -/* Set the main expression of *STMT_P to EXPR. If EXPR is not a valid - GIMPLE expression no changes are done and the function returns - false. */ +/* Return true if EXPR is a valid GIMPLE expression. */ bool -set_rhs (tree *stmt_p, tree expr) +valid_gimple_expression_p (tree expr) { - tree stmt = *stmt_p, op; enum tree_code code = TREE_CODE (expr); - stmt_ann_t ann; - tree var; - ssa_op_iter iter; - /* Verify the constant folded result is valid gimple. */ switch (TREE_CODE_CLASS (code)) { case tcc_declaration: - if (!is_gimple_variable(expr)) + if (!is_gimple_variable (expr)) return false; break; @@ -665,6 +658,25 @@ set_rhs (tree *stmt_p, tree expr) return false; } + return true; +} + + +/* Set the main expression of *STMT_P to EXPR. If EXPR is not a valid + GIMPLE expression no changes are done and the function returns + false. */ + +bool +set_rhs (tree *stmt_p, tree expr) +{ + tree stmt = *stmt_p, op; + stmt_ann_t ann; + tree var; + ssa_op_iter iter; + + if (!valid_gimple_expression_p (expr)) + return false; + if (EXPR_HAS_LOCATION (stmt) && (EXPR_P (expr) || GIMPLE_STMT_P (expr)) diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h index 0994c8ac576..94a052624a8 100644 --- a/gcc/tree-ssa-propagate.h +++ b/gcc/tree-ssa-propagate.h @@ -114,6 +114,7 @@ typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (tree); /* In tree-ssa-propagate.c */ void ssa_propagate (ssa_prop_visit_stmt_fn, ssa_prop_visit_phi_fn); tree get_rhs (tree); +bool valid_gimple_expression_p (tree expr); bool set_rhs (tree *, tree); tree first_vdef (tree); bool stmt_makes_single_load (tree); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 755fb1d31e8..5c3acb2a6a7 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -43,6 +43,7 @@ Boston, MA 02110-1301, USA. */ #include "bitmap.h" #include "langhooks.h" #include "cfgloop.h" +#include "tree-ssa-propagate.h" #include "tree-ssa-sccvn.h" /* This algorithm is based on the SCC algorithm presented by Keith @@ -1397,42 +1398,16 @@ simplify_binary_expression (tree rhs) else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1) op1 = VN_INFO (op1)->valnum; } + result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1); /* Make sure result is not a complex expression consisting of operators of operators (IE (a + b) + (a + c)) Otherwise, we will end up with unbounded expressions if fold does anything at all. */ - if (result) - { - if (is_gimple_min_invariant (result)) - return result; - else if (SSA_VAR_P (result)) - return result; - else if (EXPR_P (result)) - { - switch (TREE_CODE_CLASS (TREE_CODE (result))) - { - case tcc_unary: - { - tree op0 = TREE_OPERAND (result, 0); - if (!EXPR_P (op0)) - return result; - } - break; - case tcc_binary: - { - tree op0 = TREE_OPERAND (result, 0); - tree op1 = TREE_OPERAND (result, 1); - if (!EXPR_P (op0) && !EXPR_P (op1)) - return result; - } - break; - default: - break; - } - } - } + if (result && valid_gimple_expression_p (result)) + return result; + return NULL_TREE; }