Commit 848a392a by Martin Jambor Committed by Martin Jambor

[PR 70646] Store size to inlining predicate conditions

2016-05-18  Martin Jambor  <mjambor@suse.cz>

	PR ipa/70646
	* ipa-inline.h (condition): New field size.
	* ipa-inline-analysis.c (add_condition): New parameter SIZE, use it
	for comaprison and store it into the new condition.
	(evaluate_conditions_for_known_args): Use condition size to check
	access sizes for all but CHANGED conditions.
	(unmodified_parm_1): New parameter size_p, store access size into it.
	(unmodified_parm): Likewise.
	(unmodified_parm_or_parm_agg_item): Likewise.
	(eliminated_by_inlining_prob): Pass NULL to unmodified_parm as size_p.
	(set_cond_stmt_execution_predicate): Extract access sizes and store
	them to conditions.
	(set_switch_stmt_execution_predicate): Likewise.
	(will_be_nonconstant_expr_predicate): Likewise.
	(will_be_nonconstant_predicate): Likewise.
	(inline_read_section): Stream condition size.
	(inline_write_summary): Likewise.

testsuite/
	* gcc.dg/ipa/pr70646.c: New test.

From-SVN: r236389
parent 1f2ab776
2016-05-18 Martin Jambor <mjambor@suse.cz>
PR ipa/70646
* ipa-inline.h (condition): New field size.
* ipa-inline-analysis.c (add_condition): New parameter SIZE, use it
for comaprison and store it into the new condition.
(evaluate_conditions_for_known_args): Use condition size to check
access sizes for all but CHANGED conditions.
(unmodified_parm_1): New parameter size_p, store access size into it.
(unmodified_parm): Likewise.
(unmodified_parm_or_parm_agg_item): Likewise.
(eliminated_by_inlining_prob): Pass NULL to unmodified_parm as size_p.
(set_cond_stmt_execution_predicate): Extract access sizes and store
them to conditions.
(set_switch_stmt_execution_predicate): Likewise.
(will_be_nonconstant_expr_predicate): Likewise.
(will_be_nonconstant_predicate): Likewise.
(inline_read_section): Stream condition size.
(inline_write_summary): Likewise.
2016-05-18 Richard Biener <rguenther@suse.de> 2016-05-18 Richard Biener <rguenther@suse.de>
* tree-ssa-loop-im.c (determine_max_movement): Properly add * tree-ssa-loop-im.c (determine_max_movement): Properly add
......
...@@ -216,13 +216,14 @@ struct agg_position_info ...@@ -216,13 +216,14 @@ struct agg_position_info
bool by_ref; bool by_ref;
}; };
/* Add condition to condition list CONDS. AGGPOS describes whether the used /* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL
oprand is loaded from an aggregate and where in the aggregate it is. It can correspond to fields of condition structure. AGGPOS describes whether the
be NULL, which means this not a load from an aggregate. */ used operand is loaded from an aggregate and where in the aggregate it is.
It can be NULL, which means this not a load from an aggregate. */
static struct predicate static struct predicate
add_condition (struct inline_summary *summary, int operand_num, add_condition (struct inline_summary *summary, int operand_num,
struct agg_position_info *aggpos, HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val) enum tree_code code, tree val)
{ {
int i; int i;
...@@ -248,6 +249,7 @@ add_condition (struct inline_summary *summary, int operand_num, ...@@ -248,6 +249,7 @@ add_condition (struct inline_summary *summary, int operand_num,
for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++) for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
{ {
if (c->operand_num == operand_num if (c->operand_num == operand_num
&& c->size == size
&& c->code == code && c->code == code
&& c->val == val && c->val == val
&& c->agg_contents == agg_contents && c->agg_contents == agg_contents
...@@ -264,6 +266,7 @@ add_condition (struct inline_summary *summary, int operand_num, ...@@ -264,6 +266,7 @@ add_condition (struct inline_summary *summary, int operand_num,
new_cond.agg_contents = agg_contents; new_cond.agg_contents = agg_contents;
new_cond.by_ref = by_ref; new_cond.by_ref = by_ref;
new_cond.offset = offset; new_cond.offset = offset;
new_cond.size = size;
vec_safe_push (summary->conds, new_cond); vec_safe_push (summary->conds, new_cond);
return single_cond_predicate (i + predicate_first_dynamic_condition); return single_cond_predicate (i + predicate_first_dynamic_condition);
} }
...@@ -867,21 +870,25 @@ evaluate_conditions_for_known_args (struct cgraph_node *node, ...@@ -867,21 +870,25 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
clause |= 1 << (i + predicate_first_dynamic_condition); clause |= 1 << (i + predicate_first_dynamic_condition);
continue; continue;
} }
if (c->code == IS_NOT_CONSTANT || c->code == CHANGED) if (c->code == CHANGED)
continue; continue;
if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)), if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
TYPE_SIZE (TREE_TYPE (val)), 0))
{ {
val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val); clause |= 1 << (i + predicate_first_dynamic_condition);
continue;
}
if (c->code == IS_NOT_CONSTANT)
continue;
res = val val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val);
? fold_binary_to_constant (c->code, boolean_type_node, val, c->val) res = val
: NULL; ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
: NULL;
if (res && integer_zerop (res))
continue;
if (res && integer_zerop (res))
continue;
}
clause |= 1 << (i + predicate_first_dynamic_condition); clause |= 1 << (i + predicate_first_dynamic_condition);
} }
return clause; return clause;
...@@ -1522,16 +1529,21 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED, ...@@ -1522,16 +1529,21 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
} }
/* If OP refers to value of function parameter, return the corresponding /* If OP refers to value of function parameter, return the corresponding
parameter. */ parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
PARM_DECL) will be stored to *SIZE_P in that case too. */
static tree static tree
unmodified_parm_1 (gimple *stmt, tree op) unmodified_parm_1 (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
{ {
/* SSA_NAME referring to parm default def? */ /* SSA_NAME referring to parm default def? */
if (TREE_CODE (op) == SSA_NAME if (TREE_CODE (op) == SSA_NAME
&& SSA_NAME_IS_DEFAULT_DEF (op) && SSA_NAME_IS_DEFAULT_DEF (op)
&& TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL) && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
return SSA_NAME_VAR (op); {
if (size_p)
*size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
return SSA_NAME_VAR (op);
}
/* Non-SSA parm reference? */ /* Non-SSA parm reference? */
if (TREE_CODE (op) == PARM_DECL) if (TREE_CODE (op) == PARM_DECL)
{ {
...@@ -1542,18 +1554,24 @@ unmodified_parm_1 (gimple *stmt, tree op) ...@@ -1542,18 +1554,24 @@ unmodified_parm_1 (gimple *stmt, tree op)
walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified, walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
NULL); NULL);
if (!modified) if (!modified)
return op; {
if (size_p)
*size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
return op;
}
} }
return NULL_TREE; return NULL_TREE;
} }
/* If OP refers to value of function parameter, return the corresponding /* If OP refers to value of function parameter, return the corresponding
parameter. Also traverse chains of SSA register assignments. */ parameter. Also traverse chains of SSA register assignments. If non-NULL,
the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
stored to *SIZE_P in that case too. */
static tree static tree
unmodified_parm (gimple *stmt, tree op) unmodified_parm (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
{ {
tree res = unmodified_parm_1 (stmt, op); tree res = unmodified_parm_1 (stmt, op, size_p);
if (res) if (res)
return res; return res;
...@@ -1561,23 +1579,25 @@ unmodified_parm (gimple *stmt, tree op) ...@@ -1561,23 +1579,25 @@ unmodified_parm (gimple *stmt, tree op)
&& !SSA_NAME_IS_DEFAULT_DEF (op) && !SSA_NAME_IS_DEFAULT_DEF (op)
&& gimple_assign_single_p (SSA_NAME_DEF_STMT (op))) && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
return unmodified_parm (SSA_NAME_DEF_STMT (op), return unmodified_parm (SSA_NAME_DEF_STMT (op),
gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op))); gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
size_p);
return NULL_TREE; return NULL_TREE;
} }
/* If OP refers to a value of a function parameter or value loaded from an /* If OP refers to a value of a function parameter or value loaded from an
aggregate passed to a parameter (either by value or reference), return TRUE aggregate passed to a parameter (either by value or reference), return TRUE
and store the number of the parameter to *INDEX_P and information whether and store the number of the parameter to *INDEX_P, the access size into
and how it has been loaded from an aggregate into *AGGPOS. INFO describes *SIZE_P, and information whether and how it has been loaded from an
the function parameters, STMT is the statement in which OP is used or aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
loaded. */ statement in which OP is used or loaded. */
static bool static bool
unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi, unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
gimple *stmt, tree op, int *index_p, gimple *stmt, tree op, int *index_p,
HOST_WIDE_INT *size_p,
struct agg_position_info *aggpos) struct agg_position_info *aggpos)
{ {
tree res = unmodified_parm_1 (stmt, op); tree res = unmodified_parm_1 (stmt, op, size_p);
gcc_checking_assert (aggpos); gcc_checking_assert (aggpos);
if (res) if (res)
...@@ -1598,14 +1618,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi, ...@@ -1598,14 +1618,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
stmt = SSA_NAME_DEF_STMT (op); stmt = SSA_NAME_DEF_STMT (op);
op = gimple_assign_rhs1 (stmt); op = gimple_assign_rhs1 (stmt);
if (!REFERENCE_CLASS_P (op)) if (!REFERENCE_CLASS_P (op))
return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
aggpos); aggpos);
} }
aggpos->agg_contents = true; aggpos->agg_contents = true;
return ipa_load_from_parm_agg (fbi, fbi->info->descriptors, return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
stmt, op, index_p, &aggpos->offset, stmt, op, index_p, &aggpos->offset,
NULL, &aggpos->by_ref); size_p, &aggpos->by_ref);
} }
/* See if statement might disappear after inlining. /* See if statement might disappear after inlining.
...@@ -1656,7 +1676,7 @@ eliminated_by_inlining_prob (gimple *stmt) ...@@ -1656,7 +1676,7 @@ eliminated_by_inlining_prob (gimple *stmt)
inner_lhs = lhs; inner_lhs = lhs;
/* Reads of parameter are expected to be free. */ /* Reads of parameter are expected to be free. */
if (unmodified_parm (stmt, inner_rhs)) if (unmodified_parm (stmt, inner_rhs, NULL))
rhs_free = true; rhs_free = true;
/* Match expressions of form &this->field. Those will most likely /* Match expressions of form &this->field. Those will most likely
combine with something upstream after inlining. */ combine with something upstream after inlining. */
...@@ -1666,7 +1686,7 @@ eliminated_by_inlining_prob (gimple *stmt) ...@@ -1666,7 +1686,7 @@ eliminated_by_inlining_prob (gimple *stmt)
if (TREE_CODE (op) == PARM_DECL) if (TREE_CODE (op) == PARM_DECL)
rhs_free = true; rhs_free = true;
else if (TREE_CODE (op) == MEM_REF else if (TREE_CODE (op) == MEM_REF
&& unmodified_parm (stmt, TREE_OPERAND (op, 0))) && unmodified_parm (stmt, TREE_OPERAND (op, 0), NULL))
rhs_free = true; rhs_free = true;
} }
...@@ -1679,7 +1699,7 @@ eliminated_by_inlining_prob (gimple *stmt) ...@@ -1679,7 +1699,7 @@ eliminated_by_inlining_prob (gimple *stmt)
/* Reads of parameters passed by reference /* Reads of parameters passed by reference
expected to be free (i.e. optimized out after inlining). */ expected to be free (i.e. optimized out after inlining). */
if (TREE_CODE (inner_rhs) == MEM_REF if (TREE_CODE (inner_rhs) == MEM_REF
&& unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0))) && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0), NULL))
rhs_free = true; rhs_free = true;
/* Copying parameter passed by reference into gimple register is /* Copying parameter passed by reference into gimple register is
...@@ -1720,7 +1740,7 @@ eliminated_by_inlining_prob (gimple *stmt) ...@@ -1720,7 +1740,7 @@ eliminated_by_inlining_prob (gimple *stmt)
if (TREE_CODE (inner_lhs) == PARM_DECL if (TREE_CODE (inner_lhs) == PARM_DECL
|| TREE_CODE (inner_lhs) == RESULT_DECL || TREE_CODE (inner_lhs) == RESULT_DECL
|| (TREE_CODE (inner_lhs) == MEM_REF || (TREE_CODE (inner_lhs) == MEM_REF
&& (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0)) && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0), NULL)
|| (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
&& SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0)) && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
&& TREE_CODE (SSA_NAME_VAR (TREE_OPERAND && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
...@@ -1751,6 +1771,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1751,6 +1771,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *last; gimple *last;
tree op; tree op;
int index; int index;
HOST_WIDE_INT size;
struct agg_position_info aggpos; struct agg_position_info aggpos;
enum tree_code code, inverted_code; enum tree_code code, inverted_code;
edge e; edge e;
...@@ -1767,7 +1788,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1767,7 +1788,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
/* TODO: handle conditionals like /* TODO: handle conditionals like
var = op0 < 4; var = op0 < 4;
if (var != 0). */ if (var != 0). */
if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
{ {
code = gimple_cond_code (last); code = gimple_cond_code (last);
inverted_code = invert_tree_comparison (code, HONOR_NANS (op)); inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
...@@ -1781,9 +1802,10 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1781,9 +1802,10 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
unordered one. Be sure it is not confused with NON_CONSTANT. */ unordered one. Be sure it is not confused with NON_CONSTANT. */
if (this_code != ERROR_MARK) if (this_code != ERROR_MARK)
{ {
struct predicate p = add_condition struct predicate p
(summary, index, &aggpos, this_code, = add_condition (summary, index, size, &aggpos, this_code,
unshare_expr_without_location (gimple_cond_rhs (last))); unshare_expr_without_location
(gimple_cond_rhs (last)));
e->aux = edge_predicate_pool.allocate (); e->aux = edge_predicate_pool.allocate ();
*(struct predicate *) e->aux = p; *(struct predicate *) e->aux = p;
} }
...@@ -1810,11 +1832,12 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1810,11 +1832,12 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|| gimple_call_num_args (set_stmt) != 1) || gimple_call_num_args (set_stmt) != 1)
return; return;
op2 = gimple_call_arg (set_stmt, 0); op2 = gimple_call_arg (set_stmt, 0);
if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos)) if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size,
&aggpos))
return; return;
FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE) FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
{ {
struct predicate p = add_condition (summary, index, &aggpos, struct predicate p = add_condition (summary, index, size, &aggpos,
IS_NOT_CONSTANT, NULL_TREE); IS_NOT_CONSTANT, NULL_TREE);
e->aux = edge_predicate_pool.allocate (); e->aux = edge_predicate_pool.allocate ();
*(struct predicate *) e->aux = p; *(struct predicate *) e->aux = p;
...@@ -1833,6 +1856,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1833,6 +1856,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *lastg; gimple *lastg;
tree op; tree op;
int index; int index;
HOST_WIDE_INT size;
struct agg_position_info aggpos; struct agg_position_info aggpos;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
...@@ -1844,7 +1868,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1844,7 +1868,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
return; return;
gswitch *last = as_a <gswitch *> (lastg); gswitch *last = as_a <gswitch *> (lastg);
op = gimple_switch_index (last); op = gimple_switch_index (last);
if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos)) if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
return; return;
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
...@@ -1869,14 +1893,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi, ...@@ -1869,14 +1893,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
if (!min && !max) if (!min && !max)
p = true_predicate (); p = true_predicate ();
else if (!max) else if (!max)
p = add_condition (summary, index, &aggpos, EQ_EXPR, p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
unshare_expr_without_location (min)); unshare_expr_without_location (min));
else else
{ {
struct predicate p1, p2; struct predicate p1, p2;
p1 = add_condition (summary, index, &aggpos, GE_EXPR, p1 = add_condition (summary, index, size, &aggpos, GE_EXPR,
unshare_expr_without_location (min)); unshare_expr_without_location (min));
p2 = add_condition (summary, index, &aggpos, LE_EXPR, p2 = add_condition (summary, index, size, &aggpos, LE_EXPR,
unshare_expr_without_location (max)); unshare_expr_without_location (max));
p = and_predicates (summary->conds, &p1, &p2); p = and_predicates (summary->conds, &p1, &p2);
} }
...@@ -1977,13 +2001,14 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info, ...@@ -1977,13 +2001,14 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
{ {
tree parm; tree parm;
int index; int index;
HOST_WIDE_INT size;
while (UNARY_CLASS_P (expr)) while (UNARY_CLASS_P (expr))
expr = TREE_OPERAND (expr, 0); expr = TREE_OPERAND (expr, 0);
parm = unmodified_parm (NULL, expr); parm = unmodified_parm (NULL, expr, &size);
if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0) if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
return add_condition (summary, index, NULL, CHANGED, NULL_TREE); return add_condition (summary, index, size, NULL, CHANGED, NULL_TREE);
if (is_gimple_min_invariant (expr)) if (is_gimple_min_invariant (expr))
return false_predicate (); return false_predicate ();
if (TREE_CODE (expr) == SSA_NAME) if (TREE_CODE (expr) == SSA_NAME)
...@@ -2044,6 +2069,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, ...@@ -2044,6 +2069,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
struct predicate op_non_const; struct predicate op_non_const;
bool is_load; bool is_load;
int base_index; int base_index;
HOST_WIDE_INT size;
struct agg_position_info aggpos; struct agg_position_info aggpos;
/* What statments might be optimized away /* What statments might be optimized away
...@@ -2067,7 +2093,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, ...@@ -2067,7 +2093,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
tree op; tree op;
gcc_assert (gimple_assign_single_p (stmt)); gcc_assert (gimple_assign_single_p (stmt));
op = gimple_assign_rhs1 (stmt); op = gimple_assign_rhs1 (stmt);
if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size,
&aggpos)) &aggpos))
return p; return p;
} }
...@@ -2078,7 +2104,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, ...@@ -2078,7 +2104,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
adding conditionals. */ adding conditionals. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{ {
tree parm = unmodified_parm (stmt, use); tree parm = unmodified_parm (stmt, use, NULL);
/* For arguments we can build a condition. */ /* For arguments we can build a condition. */
if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0) if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
continue; continue;
...@@ -2093,18 +2119,19 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi, ...@@ -2093,18 +2119,19 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
if (is_load) if (is_load)
op_non_const = op_non_const =
add_condition (summary, base_index, &aggpos, CHANGED, NULL); add_condition (summary, base_index, size, &aggpos, CHANGED, NULL);
else else
op_non_const = false_predicate (); op_non_const = false_predicate ();
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{ {
tree parm = unmodified_parm (stmt, use); HOST_WIDE_INT size;
tree parm = unmodified_parm (stmt, use, &size);
int index; int index;
if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0) if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
{ {
if (index != base_index) if (index != base_index)
p = add_condition (summary, index, NULL, CHANGED, NULL_TREE); p = add_condition (summary, index, size, NULL, CHANGED, NULL_TREE);
else else
continue; continue;
} }
...@@ -3415,7 +3442,8 @@ remap_predicate (struct inline_summary *info, ...@@ -3415,7 +3442,8 @@ remap_predicate (struct inline_summary *info,
ap.by_ref = c->by_ref; ap.by_ref = c->by_ref;
cond_predicate = add_condition (info, cond_predicate = add_condition (info,
operand_map[c->operand_num], operand_map[c->operand_num],
&ap, c->code, c->val); c->size, &ap, c->code,
c->val);
} }
} }
/* Fixed conditions remains same, construct single /* Fixed conditions remains same, construct single
...@@ -4269,6 +4297,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, ...@@ -4269,6 +4297,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
{ {
struct condition c; struct condition c;
c.operand_num = streamer_read_uhwi (&ib); c.operand_num = streamer_read_uhwi (&ib);
c.size = streamer_read_uhwi (&ib);
c.code = (enum tree_code) streamer_read_uhwi (&ib); c.code = (enum tree_code) streamer_read_uhwi (&ib);
c.val = stream_read_tree (&ib, data_in); c.val = stream_read_tree (&ib, data_in);
bp = streamer_read_bitpack (&ib); bp = streamer_read_bitpack (&ib);
...@@ -4434,6 +4463,7 @@ inline_write_summary (void) ...@@ -4434,6 +4463,7 @@ inline_write_summary (void)
for (i = 0; vec_safe_iterate (info->conds, i, &c); i++) for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
{ {
streamer_write_uhwi (ob, c->operand_num); streamer_write_uhwi (ob, c->operand_num);
streamer_write_uhwi (ob, c->size);
streamer_write_uhwi (ob, c->code); streamer_write_uhwi (ob, c->code);
stream_write_tree (ob, c->val, true); stream_write_tree (ob, c->val, true);
bp = bitpack_create (ob->main_stream); bp = bitpack_create (ob->main_stream);
......
...@@ -34,6 +34,8 @@ struct GTY(()) condition ...@@ -34,6 +34,8 @@ struct GTY(()) condition
/* If agg_contents is set, this is the offset from which the used data was /* If agg_contents is set, this is the offset from which the used data was
loaded. */ loaded. */
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
/* Size of the access reading the data (or the PARM_DECL SSA_NAME). */
HOST_WIDE_INT size;
tree val; tree val;
int operand_num; int operand_num;
ENUM_BITFIELD(tree_code) code : 16; ENUM_BITFIELD(tree_code) code : 16;
......
2016-05-18 Martin Jambor <mjambor@suse.cz>
PR ipa/70646
* gcc.dg/ipa/pr70646.c: New test.
2016-05-18 Christophe Lyon <christophe.lyon@linaro.org> 2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/aarch64/advsimd-intrinsics/vget_lane.c: Add fp16 tests. * gcc.target/aarch64/advsimd-intrinsics/vget_lane.c: Add fp16 tests.
......
/* { dg-do run } */
/* { dg-options "-O2" } */
#pragma GCC optimize("no-unit-at-a-time")
typedef unsigned char u8;
typedef unsigned long long u64;
static inline __attribute__((always_inline)) u64 __swab64p(const u64 *p)
{
return (__builtin_constant_p((u64)(*p)) ? ((u64)( (((u64)(*p) & (u64)0x00000000000000ffULL) << 56) | (((u64)(*p) & (u64)0x000000000000ff00ULL) << 40) | (((u64)(*p) & (u64)0x0000000000ff0000ULL) << 24) | (((u64)(*p) & (u64)0x00000000ff000000ULL) << 8) | (((u64)(*p) & (u64)0x000000ff00000000ULL) >> 8) | (((u64)(*p) & (u64)0x0000ff0000000000ULL) >> 24) | (((u64)(*p) & (u64)0x00ff000000000000ULL) >> 40) | (((u64)(*p) & (u64)0xff00000000000000ULL) >> 56))) : __builtin_bswap64(*p));
}
static inline u64 wwn_to_u64(void *wwn)
{
return __swab64p(wwn);
}
void __attribute__((noinline,noclone)) broken(u64* shost)
{
u8 node_name[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
*shost = wwn_to_u64(node_name);
}
void __attribute__((noinline,noclone)) dummy(void)
{
__builtin_abort();
}
int main(int argc, char* argv[])
{
u64 v;
broken(&v);
if(v != (u64)-1)
__builtin_abort();
return 0;
}
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