Message ID | 20100903235742.GS1664@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On Sat, 4 Sep 2010, Jan Hubicka wrote: > > Hi, > the following testcases shows problem with fold_const_aggregate_ref > producing non-gimple &global_trees[TI_VOID_TYPE] (taken from DECL_INITIAL) > and later failing it to use it as known constant. We eventually get the constant > value at cfgexpand time only. > > I am not sure what is the proper way to fold this, so I ended up with using > maybe_fold_offset_to_address. With removal of some code redundancy it is hopefully > not too bad. > > Bootstrapped/regtested x86_64-linux, OK? Ok. Thanks, Richard. > Honza > > /* { dg-do compile } */ > /* { dg-options "-O2 -fdump-tree-optimized" } */ > typedef union tree_node *tree; > enum tree_code > { > OFFSET_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, POINTER_TYPE, FIXED_POINT_TYPE, > }; > struct tree_base > { > unsigned public_flag:1; > }; > struct tree_decl_with_vis > { > unsigned comdat_flag:1; > }; > union tree_node > { > struct tree_base base; > struct tree_decl_with_vis decl_with_vis; > }; > enum tree_index > { > TI_LONG_DOUBLE_PTR_TYPE, TI_INTEGER_PTR_TYPE, TI_VOID_TYPE, TI_PTR_TYPE, > TI_VA_LIST_FPR_COUNTER_FIELD, TI_BOOLEAN_TYPE, TI_FILEPTR_TYPE, > TI_CURRENT_TARGET_PRAGMA, TI_CURRENT_OPTIMIZE_PRAGMA, TI_MAX > }; > extern tree global_trees[TI_MAX]; > emit_support_tinfos (void) > { > static tree *const fundamentals[] = { > &global_trees[TI_VOID_TYPE], &global_trees[TI_BOOLEAN_TYPE], > }; > int ix; > for (ix = 0; fundamentals[ix]; ix++) > { > { > tree tinfo; > { > ((void) (!(((tinfo)->base.public_flag) && !(__extension__ ( > { > __typeof > (tinfo) > __t > = > (tinfo); > __t;} > )->decl_with_vis. > comdat_flag)) ? > fancy_abort ("../../gcc/cp/rtti.c", 1529, > __FUNCTION__), 0 : 0)); > } > } > } > } > /* We should copy loop header to fundamentals[0] and then fold it way into > known value. */ > /* { dg-final { scan-tree-dump-times "fundamental.0" 1 "optimized"} } */ > /* { dg-final { cleanup-tree-dump "optimized" } } */ > * gimple.h (canonicalize_consturctor_val): Declare. > * gimple-fold.c (canonicalize_consturctor_val): New function. > (get_symbol_constant_value):Use it. > * tree-ssa-ccp.c (fold_const_aggregate_ref): Likewise. > Index: gimple.h > =================================================================== > --- gimple.h (revision 163808) > +++ gimple.h (working copy) > @@ -4876,6 +4876,7 @@ tree maybe_fold_offset_to_address (locat > tree maybe_fold_offset_to_reference (location_t, tree, tree, tree); > tree maybe_fold_stmt_addition (location_t, tree, tree, tree); > tree get_symbol_constant_value (tree); > +tree canonicalize_consturctor_val (tree); > bool may_propagate_address_into_dereference (tree, tree); > extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, > enum tree_code, tree, tree); > Index: gimple-fold.c > =================================================================== > --- gimple-fold.c (revision 163808) > +++ gimple-fold.c (working copy) > @@ -31,6 +31,30 @@ along with GCC; see the file COPYING3. > #include "tree-ssa-propagate.h" > #include "target.h" > > +/* CVAL is value taken from DECL_INITIAL of variable. Try to transorm it into > + acceptable form for is_gimple_min_invariant. */ > + > +tree > +canonicalize_consturctor_val (tree cval) > +{ > + STRIP_NOPS (cval); > + if (TREE_CODE (cval) == POINTER_PLUS_EXPR) > + { > + tree t = maybe_fold_offset_to_address (EXPR_LOCATION (cval), > + TREE_OPERAND (cval, 0), > + TREE_OPERAND (cval, 1), > + TREE_TYPE (cval)); > + if (t) > + cval = t; > + } > + if (TREE_CODE (cval) == ADDR_EXPR) > + { > + tree base = get_base_address (TREE_OPERAND (cval, 0)); > + if (base && TREE_CODE (base) == VAR_DECL) > + add_referenced_var (base); > + } > + return cval; > +} > > /* If SYM is a constant variable with known value, return the value. > NULL_TREE is returned otherwise. */ > @@ -45,21 +69,9 @@ get_symbol_constant_value (tree sym) > tree val = DECL_INITIAL (sym); > if (val) > { > - STRIP_NOPS (val); > + val = canonicalize_consturctor_val (val); > if (is_gimple_min_invariant (val)) > - { > - if (TREE_CODE (val) == ADDR_EXPR) > - { > - tree base = get_base_address (TREE_OPERAND (val, 0)); > - if (base && TREE_CODE (base) == VAR_DECL) > - { > - TREE_ADDRESSABLE (base) = 1; > - if (gimple_referenced_vars (cfun)) > - add_referenced_var (base); > - } > - } > - return val; > - } > + return val; > } > /* Variables declared 'const' without an initializer > have zero as the initializer if they may not be > Index: tree-ssa-ccp.c > =================================================================== > --- tree-ssa-ccp.c (revision 163808) > +++ tree-ssa-ccp.c (working copy) > @@ -1413,16 +1417,7 @@ fold_const_aggregate_ref (tree t) > /* Whoo-hoo! I'll fold ya baby. Yeah! */ > FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) > if (tree_int_cst_equal (cfield, idx)) > - { > - STRIP_NOPS (cval); > - if (TREE_CODE (cval) == ADDR_EXPR) > - { > - tree base = get_base_address (TREE_OPERAND (cval, 0)); > - if (base && TREE_CODE (base) == VAR_DECL) > - add_referenced_var (base); > - } > - return cval; > - } > + return canonicalize_consturctor_val (cval); > break; > > case COMPONENT_REF: > @@ -1463,16 +1458,7 @@ fold_const_aggregate_ref (tree t) > if (cfield == field > /* FIXME: Handle bit-fields. */ > && ! DECL_BIT_FIELD (cfield)) > - { > - STRIP_NOPS (cval); > - if (TREE_CODE (cval) == ADDR_EXPR) > - { > - tree base = get_base_address (TREE_OPERAND (cval, 0)); > - if (base && TREE_CODE (base) == VAR_DECL) > - add_referenced_var (base); > - } > - return cval; > - } > + return canonicalize_consturctor_val (cval); > break; > > case REALPART_EXPR: > @@ -1567,13 +1553,7 @@ fold_const_aggregate_ref (tree t) > FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) > if (tree_int_cst_equal (cfield, idx)) > { > - STRIP_NOPS (cval); > - if (TREE_CODE (cval) == ADDR_EXPR) > - { > - tree base = get_base_address (TREE_OPERAND (cval, 0)); > - if (base && TREE_CODE (base) == VAR_DECL) > - add_referenced_var (base); > - } > + cval = canonicalize_consturctor_val (cval); > if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval))) > return cval; > else if (CONSTANT_CLASS_P (cval)) > >
On Fri, Sep 3, 2010 at 4:57 PM, Jan Hubicka <hubicka@ucw.cz> wrote: > > Hi, > the following testcases shows problem with fold_const_aggregate_ref > producing non-gimple &global_trees[TI_VOID_TYPE] (taken from DECL_INITIAL) > and later failing it to use it as known constant. We eventually get the constant > value at cfgexpand time only. > > I am not sure what is the proper way to fold this, so I ended up with using > maybe_fold_offset_to_address. With removal of some code redundancy it is hopefully > not too bad. > > Bootstrapped/regtested x86_64-linux, OK? > Honza > This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45550 H.J.
Index: gimple.h =================================================================== --- gimple.h (revision 163808) +++ gimple.h (working copy) @@ -4876,6 +4876,7 @@ tree maybe_fold_offset_to_address (locat tree maybe_fold_offset_to_reference (location_t, tree, tree, tree); tree maybe_fold_stmt_addition (location_t, tree, tree, tree); tree get_symbol_constant_value (tree); +tree canonicalize_consturctor_val (tree); bool may_propagate_address_into_dereference (tree, tree); extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, enum tree_code, tree, tree); Index: gimple-fold.c =================================================================== --- gimple-fold.c (revision 163808) +++ gimple-fold.c (working copy) @@ -31,6 +31,30 @@ along with GCC; see the file COPYING3. #include "tree-ssa-propagate.h" #include "target.h" +/* CVAL is value taken from DECL_INITIAL of variable. Try to transorm it into + acceptable form for is_gimple_min_invariant. */ + +tree +canonicalize_consturctor_val (tree cval) +{ + STRIP_NOPS (cval); + if (TREE_CODE (cval) == POINTER_PLUS_EXPR) + { + tree t = maybe_fold_offset_to_address (EXPR_LOCATION (cval), + TREE_OPERAND (cval, 0), + TREE_OPERAND (cval, 1), + TREE_TYPE (cval)); + if (t) + cval = t; + } + if (TREE_CODE (cval) == ADDR_EXPR) + { + tree base = get_base_address (TREE_OPERAND (cval, 0)); + if (base && TREE_CODE (base) == VAR_DECL) + add_referenced_var (base); + } + return cval; +} /* If SYM is a constant variable with known value, return the value. NULL_TREE is returned otherwise. */ @@ -45,21 +69,9 @@ get_symbol_constant_value (tree sym) tree val = DECL_INITIAL (sym); if (val) { - STRIP_NOPS (val); + val = canonicalize_consturctor_val (val); if (is_gimple_min_invariant (val)) - { - if (TREE_CODE (val) == ADDR_EXPR) - { - tree base = get_base_address (TREE_OPERAND (val, 0)); - if (base && TREE_CODE (base) == VAR_DECL) - { - TREE_ADDRESSABLE (base) = 1; - if (gimple_referenced_vars (cfun)) - add_referenced_var (base); - } - } - return val; - } + return val; } /* Variables declared 'const' without an initializer have zero as the initializer if they may not be Index: tree-ssa-ccp.c =================================================================== --- tree-ssa-ccp.c (revision 163808) +++ tree-ssa-ccp.c (working copy) @@ -1413,16 +1417,7 @@ fold_const_aggregate_ref (tree t) /* Whoo-hoo! I'll fold ya baby. Yeah! */ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) if (tree_int_cst_equal (cfield, idx)) - { - STRIP_NOPS (cval); - if (TREE_CODE (cval) == ADDR_EXPR) - { - tree base = get_base_address (TREE_OPERAND (cval, 0)); - if (base && TREE_CODE (base) == VAR_DECL) - add_referenced_var (base); - } - return cval; - } + return canonicalize_consturctor_val (cval); break; case COMPONENT_REF: @@ -1463,16 +1458,7 @@ fold_const_aggregate_ref (tree t) if (cfield == field /* FIXME: Handle bit-fields. */ && ! DECL_BIT_FIELD (cfield)) - { - STRIP_NOPS (cval); - if (TREE_CODE (cval) == ADDR_EXPR) - { - tree base = get_base_address (TREE_OPERAND (cval, 0)); - if (base && TREE_CODE (base) == VAR_DECL) - add_referenced_var (base); - } - return cval; - } + return canonicalize_consturctor_val (cval); break; case REALPART_EXPR: @@ -1567,13 +1553,7 @@ fold_const_aggregate_ref (tree t) FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) if (tree_int_cst_equal (cfield, idx)) { - STRIP_NOPS (cval); - if (TREE_CODE (cval) == ADDR_EXPR) - { - tree base = get_base_address (TREE_OPERAND (cval, 0)); - if (base && TREE_CODE (base) == VAR_DECL) - add_referenced_var (base); - } + cval = canonicalize_consturctor_val (cval); if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval))) return cval; else if (CONSTANT_CLASS_P (cval))