From 17f39a395648213a0c6014e84ff34f3ff565a10b Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 4 Sep 2010 19:36:49 +0200 Subject: [PATCH] foldconst-2.c: New testcase. * gcc.dg/tree-ssa/foldconst-2.c: New testcase. * gcc.dg/tree-ssa/foldconst-3.c: New testcase. * gimple-fold.c (maybe_fold_reference): Use fold_const_aggregate_ref. * tree-ssa-ccp.c (fold_const_aggregate_ref): Use fold_read_from_constant_string. * gimple.h (canonicalize_constructor_val): Declare. * gimple-fold.c (canonicalize_constructor_val): New function. (get_symbol_constant_value):Use it. * tree-ssa-ccp.c (fold_const_aggregate_ref): Likewise. From-SVN: r163861 --- gcc/ChangeLog | 11 +++ gcc/gimple-fold.c | 51 ++++++++------ gcc/gimple.h | 1 + gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/tree-ssa/foldconst-2.c | 58 ++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/foldconst-3.c | 76 +++++++++++++++++++++ gcc/tree-ssa-ccp.c | 34 ++------- 7 files changed, 188 insertions(+), 48 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/foldconst-2.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/foldconst-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index feece9ea969..e5fe0a2365b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2010-09-04 Jan Hubicka + + * gimple-fold.c (maybe_fold_reference): Use fold_const_aggregate_ref. + * tree-ssa-ccp.c (fold_const_aggregate_ref): Use + fold_read_from_constant_string. + + * gimple.h (canonicalize_constructor_val): Declare. + * gimple-fold.c (canonicalize_constructor_val): New function. + (get_symbol_constant_value):Use it. + * tree-ssa-ccp.c (fold_const_aggregate_ref): Likewise. + 2010-09-04 Jan Hubicka * tree-switch-conversion.c (build_one_array): Set constructor to be diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 033023a9fa7..2b40ee6909e 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -31,6 +31,30 @@ along with GCC; see the file COPYING3. If not see #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_constructor_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_constructor_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 @@ -462,14 +474,11 @@ static tree maybe_fold_reference (tree expr, bool is_lhs) { tree *t = &expr; + tree result; - if (TREE_CODE (expr) == ARRAY_REF - && !is_lhs) - { - tree tem = fold_read_from_constant_string (expr); - if (tem) - return tem; - } + if (!is_lhs + && (result = fold_const_aggregate_ref (expr))) + return result; /* ??? We might want to open-code the relevant remaining cases to avoid using the generic fold. */ diff --git a/gcc/gimple.h b/gcc/gimple.h index 545b271d83a..ee693189068 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -4876,6 +4876,7 @@ tree maybe_fold_offset_to_address (location_t, tree, tree, tree); 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_constructor_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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e3da032554..f5306a92ac2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-09-04 Jan Hubicka + + * gcc.dg/tree-ssa/foldconst-2.c: New testcase. + * gcc.dg/tree-ssa/foldconst-3.c: New testcase. + 2010-09-04 Jan Hubicka * gcc.dg/tree-ssa/foldconst-1.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/foldconst-2.c b/gcc/testsuite/gcc.dg/tree-ssa/foldconst-2.c new file mode 100644 index 00000000000..8fdad906a80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/foldconst-2.c @@ -0,0 +1,58 @@ +/* { 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-not "fundamentals.0" "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/foldconst-3.c b/gcc/testsuite/gcc.dg/tree-ssa/foldconst-3.c new file mode 100644 index 00000000000..61323620714 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/foldconst-3.c @@ -0,0 +1,76 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +typedef const union tree_node *const_tree; +typedef struct +{ +} +double_int; +double_int double_int_zext (double_int, unsigned); +enum tree_code +{ ERROR_MARK, IDENTIFIER_NODE, TREE_LIST, BLOCK, ENUMERAL_TYPE, BOOLEAN_TYPE, + INTEGER_TYPE, ARRAY_TYPE, INTEGER_CST, VAR_DECL, PARM_DECL, RESULT_DECL, + }; +enum tree_code_class +{ tcc_exceptional, tcc_constant, tcc_type, tcc_declaration, tcc_reference, }; +struct tree_base +{ + __extension__ enum tree_code code:16; + unsigned unsigned_flag:1; +}; +struct tree_type +{ + unsigned int precision:10; + union tree_type_symtab + { + } symtab; +}; +union tree_node +{ + struct tree_base base; + struct tree_type type; +}; +const enum tree_code_class tree_code_type[] = +{ tcc_exceptional, 1, 0, 0, 0, 0, 2, }; + +int_fits_type_p (const_tree c, const_tree type) +{ + double_int dc, dd; + { + if (((enum tree_code) (type)->base.code) == INTEGER_TYPE && (( + { + __typeof + (type) __t + = (type); + if + (tree_code_type + [(int) + (((enum + tree_code) + (__t)-> + base. + code))] + != + (tcc_type)) + tree_class_check_failed + (__t, + __FUNCTION__); + __t;})-> + base. + unsigned_flag)) + dd = double_int_zext (dd, (( + { + __typeof (type) __t = (type); + if (tree_code_type + [(int) + (((enum tree_code) (__t)->base. + code))] != + (tcc_type)) + tree_class_check_failed (__t, + __FUNCTION__); + __t;} + )->type.precision)); +} +} +/* The switch should be switch converted and later constant propagated. */ +/* { dg-final { scan-tree-dump-not "tree_code_type" "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 8c42a633665..32fde458f13 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1325,6 +1325,10 @@ fold_const_aggregate_ref (tree t) if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration) return get_symbol_constant_value (t); + tem = fold_read_from_constant_string (t); + if (tem) + return tem; + switch (TREE_CODE (t)) { case ARRAY_REF: @@ -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_constructor_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_constructor_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_constructor_val (cval); if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval))) return cval; else if (CONSTANT_CLASS_P (cval)) -- 2.30.2