summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-19 18:06:12 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-19 18:06:12 +0000
commitdf8d3e8981a99e264b49876f0f5064bdb30ac981 (patch)
tree1d4237222ae0ad0d8207eb6ee9f94b244ffae6e5 /gcc/expr.c
parenta90c63ff18562cb1fd4da12b68d74d9f5592f414 (diff)
downloadgcc-df8d3e8981a99e264b49876f0f5064bdb30ac981.tar.gz
* cgraph.h (const_value_known_p): Replace by ...
(ctor_for_folding): .. this one. * cgraphunit.c (process_function_and_variable_attributes): Use it. * lto-cgraph.c (compute_ltrans_boundary): Use ctor_for_folding. * expr.c (expand_expr_real_1): Likewise. (string_constant): Likewise. * tree-ssa-loop-ivcanon.c (constant_after_peeling): Likewise. * ipa.c (process_references): Likewise. (symtab_remove_unreachable_nodes): Likewise. * ipa-inline-analysis.c (param_change_prob): Likewise. * gimple-fold.c (canonicalize_constructor_val): Likewise. (get_base_constructor): Likwise. * varpool.c (varpool_remove_node): Likewise. (varpool_remove_initializer): LIkewise. (dump_varpool_node): LIkwise. (const_value_known_p): Rewrite to ... (ctor_for_folding): ... this one. * lto-partition.c (add_references_to_partition): Use ctor_for_folding. * gcc.dg/tree-ssa/attr-alias-2.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200211 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c132
1 files changed, 65 insertions, 67 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 2a7824b62a2..bce96c9c227 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9698,6 +9698,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
tree array = treeop0;
tree index = treeop1;
+ tree init;
/* Fold an expression like: "foo"[2].
This is not done in fold so it won't happen inside &.
@@ -9744,76 +9745,72 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
&& modifier != EXPAND_INITIALIZER
&& modifier != EXPAND_MEMORY
&& TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
- && TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
- && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK
- && const_value_known_p (array))
+ && TREE_CODE (index) == INTEGER_CST
+ && (TREE_CODE (array) == VAR_DECL
+ || TREE_CODE (array) == CONST_DECL)
+ && (init = ctor_for_folding (array)) != error_mark_node)
{
- if (TREE_CODE (index) == INTEGER_CST)
+ if (TREE_CODE (init) == CONSTRUCTOR)
{
- tree init = DECL_INITIAL (array);
+ unsigned HOST_WIDE_INT ix;
+ tree field, value;
- if (TREE_CODE (init) == CONSTRUCTOR)
- {
- unsigned HOST_WIDE_INT ix;
- tree field, value;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
+ field, value)
+ if (tree_int_cst_equal (field, index))
+ {
+ if (TREE_SIDE_EFFECTS (value))
+ break;
- FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
- field, value)
- if (tree_int_cst_equal (field, index))
+ if (TREE_CODE (value) == CONSTRUCTOR)
{
- if (TREE_SIDE_EFFECTS (value))
+ /* If VALUE is a CONSTRUCTOR, this
+ optimization is only useful if
+ this doesn't store the CONSTRUCTOR
+ into memory. If it does, it is more
+ efficient to just load the data from
+ the array directly. */
+ rtx ret = expand_constructor (value, target,
+ modifier, true);
+ if (ret == NULL_RTX)
break;
-
- if (TREE_CODE (value) == CONSTRUCTOR)
- {
- /* If VALUE is a CONSTRUCTOR, this
- optimization is only useful if
- this doesn't store the CONSTRUCTOR
- into memory. If it does, it is more
- efficient to just load the data from
- the array directly. */
- rtx ret = expand_constructor (value, target,
- modifier, true);
- if (ret == NULL_RTX)
- break;
- }
-
- return expand_expr (fold (value), target, tmode,
- modifier);
}
- }
- else if(TREE_CODE (init) == STRING_CST)
+
+ return expand_expr (fold (value), target, tmode,
+ modifier);
+ }
+ }
+ else if(TREE_CODE (init) == STRING_CST)
+ {
+ tree index1 = index;
+ tree low_bound = array_ref_low_bound (exp);
+ index1 = fold_convert_loc (loc, sizetype,
+ treeop1);
+
+ /* Optimize the special-case of a zero lower bound.
+
+ We convert the low_bound to sizetype to avoid some problems
+ with constant folding. (E.g. suppose the lower bound is 1,
+ and its mode is QI. Without the conversion,l (ARRAY
+ +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
+ +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
+
+ if (! integer_zerop (low_bound))
+ index1 = size_diffop_loc (loc, index1,
+ fold_convert_loc (loc, sizetype,
+ low_bound));
+
+ if (0 > compare_tree_int (index1,
+ TREE_STRING_LENGTH (init)))
{
- tree index1 = index;
- tree low_bound = array_ref_low_bound (exp);
- index1 = fold_convert_loc (loc, sizetype,
- treeop1);
-
- /* Optimize the special-case of a zero lower bound.
-
- We convert the low_bound to sizetype to avoid some problems
- with constant folding. (E.g. suppose the lower bound is 1,
- and its mode is QI. Without the conversion,l (ARRAY
- +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
- +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
-
- if (! integer_zerop (low_bound))
- index1 = size_diffop_loc (loc, index1,
- fold_convert_loc (loc, sizetype,
- low_bound));
-
- if (0 > compare_tree_int (index1,
- TREE_STRING_LENGTH (init)))
- {
- tree type = TREE_TYPE (TREE_TYPE (init));
- enum machine_mode mode = TYPE_MODE (type);
-
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) == 1)
- return gen_int_mode (TREE_STRING_POINTER (init)
- [TREE_INT_CST_LOW (index1)],
- mode);
- }
+ tree type = TREE_TYPE (TREE_TYPE (init));
+ enum machine_mode mode = TYPE_MODE (type);
+
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) == 1)
+ return gen_int_mode (TREE_STRING_POINTER (init)
+ [TREE_INT_CST_LOW (index1)],
+ mode);
}
}
}
@@ -10676,17 +10673,18 @@ string_constant (tree arg, tree *ptr_offset)
|| TREE_CODE (array) == CONST_DECL)
{
int length;
+ tree init = ctor_for_folding (array);
/* Variables initialized to string literals can be handled too. */
- if (!const_value_known_p (array)
- || !DECL_INITIAL (array)
- || TREE_CODE (DECL_INITIAL (array)) != STRING_CST)
+ if (init == error_mark_node
+ || !init
+ || TREE_CODE (init) != STRING_CST)
return 0;
/* Avoid const char foo[4] = "abcde"; */
if (DECL_SIZE_UNIT (array) == NULL_TREE
|| TREE_CODE (DECL_SIZE_UNIT (array)) != INTEGER_CST
- || (length = TREE_STRING_LENGTH (DECL_INITIAL (array))) <= 0
+ || (length = TREE_STRING_LENGTH (init)) <= 0
|| compare_tree_int (DECL_SIZE_UNIT (array), length) < 0)
return 0;
@@ -10699,7 +10697,7 @@ string_constant (tree arg, tree *ptr_offset)
return 0;
*ptr_offset = offset;
- return DECL_INITIAL (array);
+ return init;
}
return 0;