diff options
author | Richard Henderson <rth@redhat.com> | 2005-11-19 21:37:08 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-11-19 21:37:08 -0800 |
commit | 688e936d4666ef4f439810756d094a61b6f22186 (patch) | |
tree | 122db954d6114e9b5e9bf6c18c520145c59570fa | |
parent | 7ab1122a479d64423c6ad069793f41666f9fd3aa (diff) | |
download | gcc-688e936d4666ef4f439810756d094a61b6f22186.zip gcc-688e936d4666ef4f439810756d094a61b6f22186.tar.gz gcc-688e936d4666ef4f439810756d094a61b6f22186.tar.bz2 |
re PR tree-optimization/24665 (internal compiler error: get_indirect_ref_operands)
PR tree-opt/24665
* tree-gimple.c (is_gimple_id): Export.
* tree-gimple.h (is_gimple_id): Declare.
* tree-ssa-ccp.c (ccp_decl_initial_min_invariant): New.
(get_default_value): Use it.
(maybe_fold_stmt_indirect): Likewise.
From-SVN: r107244
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr24665.C | 29 | ||||
-rw-r--r-- | gcc/tree-gimple.c | 4 | ||||
-rw-r--r-- | gcc/tree-gimple.h | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 30 |
5 files changed, 69 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7cc5281..991b883 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-11-19 Richard Henderson <rth@redhat.com> + + PR tree-opt/24665 + * tree-gimple.c (is_gimple_id): Export. + * tree-gimple.h (is_gimple_id): Declare. + * tree-ssa-ccp.c (ccp_decl_initial_min_invariant): New. + (get_default_value): Use it. + (maybe_fold_stmt_indirect): Likewise. + 2005-11-19 James A. Morrison <phython@gcc.gnu.org> * tree-vrp.c (compare_ranges): Return false for EQ_EXPR if VR0 is less diff --git a/gcc/testsuite/g++.dg/opt/pr24665.C b/gcc/testsuite/g++.dg/opt/pr24665.C new file mode 100644 index 0000000..646642c --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr24665.C @@ -0,0 +1,29 @@ +// { dg-do compile } +// { dg-options "-O2" } + +typedef unsigned long T; +typedef volatile T* const hwreg_t; +struct RegisterLayout +{ + T intmask; +}; +struct Controller_t +{ + Controller_t(); + inline void + disableInterrupt() + { + *mpMaskRegister = 0; + }; + static hwreg_t mpMaskRegister; +}; + +extern char SimulatedRegisters[]; + +hwreg_t Controller_t::mpMaskRegister + = &(reinterpret_cast<volatile RegisterLayout*>(SimulatedRegisters))->intmask; + +Controller_t::Controller_t() +{ + disableInterrupt(); +} diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c index 284f577..82bbf7a 100644 --- a/gcc/tree-gimple.c +++ b/gcc/tree-gimple.c @@ -35,8 +35,6 @@ Boston, MA 02110-1301, USA. */ /* For the definitive definition of GIMPLE, see doc/tree-ssa.texi. */ -static inline bool is_gimple_id (tree); - /* Validation of GIMPLE expressions. */ /* Return true if T is a GIMPLE RHS for an assignment to a temporary. */ @@ -244,7 +242,7 @@ is_gimple_variable (tree t) /* Return true if T is a GIMPLE identifier (something with an address). */ -static inline bool +bool is_gimple_id (tree t) { return (is_gimple_variable (t) diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h index 5f7724b..83c17fb 100644 --- a/gcc/tree-gimple.h +++ b/gcc/tree-gimple.h @@ -53,6 +53,8 @@ extern bool is_gimple_formal_tmp_var (tree); extern bool is_gimple_formal_tmp_reg (tree); /* Returns true iff T is any sort of variable. */ extern bool is_gimple_variable (tree); +/* Returns true iff T is any sort of symbol. */ +extern bool is_gimple_id (tree); /* Returns true iff T is a variable or an INDIRECT_REF (of a variable). */ extern bool is_gimple_min_lval (tree); /* Returns true iff T is something whose address can be taken. */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index e9e1c0b..cd446ee 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -273,6 +273,32 @@ debug_lattice_value (prop_value_t val) } +/* The regular is_gimple_min_invariant does a shallow test of the object. + It assumes that full gimplification has happened, or will happen on the + object. For a value coming from DECL_INITIAL, this is not true, so we + have to be more strict outselves. */ + +static bool +ccp_decl_initial_min_invariant (tree t) +{ + if (!is_gimple_min_invariant (t)) + return false; + if (TREE_CODE (t) == ADDR_EXPR) + { + /* Inline and unroll is_gimple_addressable. */ + while (1) + { + t = TREE_OPERAND (t, 0); + if (is_gimple_id (t)) + return true; + if (!handled_component_p (t)) + return false; + } + } + return true; +} + + /* Compute a default value for variable VAR and store it in the CONST_VAL array. The following rules are used to get default values: @@ -317,7 +343,7 @@ get_default_value (tree var) else if (TREE_STATIC (sym) && TREE_READONLY (sym) && DECL_INITIAL (sym) - && is_gimple_min_invariant (DECL_INITIAL (sym))) + && ccp_decl_initial_min_invariant (DECL_INITIAL (sym))) { /* Globals and static variables declared 'const' take their initial value. */ @@ -1712,7 +1738,7 @@ maybe_fold_stmt_indirect (tree expr, tree base, tree offset) /* Fold away CONST_DECL to its value, if the type is scalar. */ if (TREE_CODE (base) == CONST_DECL - && is_gimple_min_invariant (DECL_INITIAL (base))) + && ccp_decl_initial_min_invariant (DECL_INITIAL (base))) return DECL_INITIAL (base); /* Try folding *(&B+O) to B[X]. */ |