Commit 17f39a39 by Jan Hubicka Committed by Jan Hubicka

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
parent 5f7ae6b6
2010-09-04 Jan Hubicka <jh@suse.cz> 2010-09-04 Jan Hubicka <jh@suse.cz>
* 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 <jh@suse.cz>
* tree-switch-conversion.c (build_one_array): Set constructor to be * tree-switch-conversion.c (build_one_array): Set constructor to be
static. static.
* varpool.c (varpool_finalize_decl): Compute const_value_known. * varpool.c (varpool_finalize_decl): Compute const_value_known.
......
...@@ -31,6 +31,30 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,6 +31,30 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
#include "target.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. /* If SYM is a constant variable with known value, return the value.
NULL_TREE is returned otherwise. */ NULL_TREE is returned otherwise. */
...@@ -45,22 +69,10 @@ get_symbol_constant_value (tree sym) ...@@ -45,22 +69,10 @@ get_symbol_constant_value (tree sym)
tree val = DECL_INITIAL (sym); tree val = DECL_INITIAL (sym);
if (val) if (val)
{ {
STRIP_NOPS (val); val = canonicalize_constructor_val (val);
if (is_gimple_min_invariant (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 /* Variables declared 'const' without an initializer
have zero as the initializer if they may not be have zero as the initializer if they may not be
overridden at link or run time. */ overridden at link or run time. */
...@@ -462,14 +474,11 @@ static tree ...@@ -462,14 +474,11 @@ static tree
maybe_fold_reference (tree expr, bool is_lhs) maybe_fold_reference (tree expr, bool is_lhs)
{ {
tree *t = &expr; tree *t = &expr;
tree result;
if (TREE_CODE (expr) == ARRAY_REF if (!is_lhs
&& !is_lhs) && (result = fold_const_aggregate_ref (expr)))
{ return result;
tree tem = fold_read_from_constant_string (expr);
if (tem)
return tem;
}
/* ??? We might want to open-code the relevant remaining cases /* ??? We might want to open-code the relevant remaining cases
to avoid using the generic fold. */ to avoid using the generic fold. */
......
...@@ -4876,6 +4876,7 @@ tree maybe_fold_offset_to_address (location_t, tree, tree, tree); ...@@ -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_offset_to_reference (location_t, tree, tree, tree);
tree maybe_fold_stmt_addition (location_t, tree, tree, tree); tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
tree get_symbol_constant_value (tree); tree get_symbol_constant_value (tree);
tree canonicalize_constructor_val (tree);
bool may_propagate_address_into_dereference (tree, tree); bool may_propagate_address_into_dereference (tree, tree);
extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree,
enum tree_code, tree, tree); enum tree_code, tree, tree);
......
2010-09-04 Jan Hubicka <jh@suse.cz> 2010-09-04 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/foldconst-2.c: New testcase.
* gcc.dg/tree-ssa/foldconst-3.c: New testcase.
2010-09-04 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/foldconst-1.c: New testcase. * gcc.dg/tree-ssa/foldconst-1.c: New testcase.
2010-09-04 Janus Weil <janus@gcc.gnu.org> 2010-09-04 Janus Weil <janus@gcc.gnu.org>
......
/* { 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" } } */
/* { 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" } } */
...@@ -1325,6 +1325,10 @@ fold_const_aggregate_ref (tree t) ...@@ -1325,6 +1325,10 @@ fold_const_aggregate_ref (tree t)
if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration) if (TREE_CODE_CLASS (TREE_CODE (t)) == tcc_declaration)
return get_symbol_constant_value (t); return get_symbol_constant_value (t);
tem = fold_read_from_constant_string (t);
if (tem)
return tem;
switch (TREE_CODE (t)) switch (TREE_CODE (t))
{ {
case ARRAY_REF: case ARRAY_REF:
...@@ -1413,16 +1417,7 @@ fold_const_aggregate_ref (tree t) ...@@ -1413,16 +1417,7 @@ fold_const_aggregate_ref (tree t)
/* Whoo-hoo! I'll fold ya baby. Yeah! */ /* Whoo-hoo! I'll fold ya baby. Yeah! */
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
if (tree_int_cst_equal (cfield, idx)) if (tree_int_cst_equal (cfield, idx))
{ return canonicalize_constructor_val (cval);
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;
}
break; break;
case COMPONENT_REF: case COMPONENT_REF:
...@@ -1463,16 +1458,7 @@ fold_const_aggregate_ref (tree t) ...@@ -1463,16 +1458,7 @@ fold_const_aggregate_ref (tree t)
if (cfield == field if (cfield == field
/* FIXME: Handle bit-fields. */ /* FIXME: Handle bit-fields. */
&& ! DECL_BIT_FIELD (cfield)) && ! DECL_BIT_FIELD (cfield))
{ return canonicalize_constructor_val (cval);
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;
}
break; break;
case REALPART_EXPR: case REALPART_EXPR:
...@@ -1567,13 +1553,7 @@ fold_const_aggregate_ref (tree t) ...@@ -1567,13 +1553,7 @@ fold_const_aggregate_ref (tree t)
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval) FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
if (tree_int_cst_equal (cfield, idx)) if (tree_int_cst_equal (cfield, idx))
{ {
STRIP_NOPS (cval); cval = canonicalize_constructor_val (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);
}
if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval))) if (useless_type_conversion_p (TREE_TYPE (t), TREE_TYPE (cval)))
return cval; return cval;
else if (CONSTANT_CLASS_P (cval)) else if (CONSTANT_CLASS_P (cval))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment