summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline-analysis.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-15 12:15:43 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-09-15 12:15:43 +0000
commit94646c9c4d008ad6813ddbb5864a8a005e90f48e (patch)
treec376038af4bc9d199b58b228906c4ffe40f2fcac /gcc/ipa-inline-analysis.c
parent7d1099cb3bdd9f869ab8990a8311ce4d0eb6e409 (diff)
downloadgcc-94646c9c4d008ad6813ddbb5864a8a005e90f48e.tar.gz
* ipa-inline-analysis.c (add_condition): Add conditions parameter;
simplify obviously true clauses. (and_predicates, or_predicates): Add conditions parameter. (inline_duplication_hoook): Update. (mark_modified): New function. (unmodified_parm): New function. (eliminated_by_inlining_prob, (set_cond_stmt_execution_predicate, set_switch_stmt_execution_predicate, will_be_nonconstant_predicate): Use unmodified_parm. (estimate_function_body_sizes): Update. (remap_predicate): Update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178881 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-inline-analysis.c')
-rw-r--r--gcc/ipa-inline-analysis.c153
1 files changed, 112 insertions, 41 deletions
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index f9254165183..6bc96c7788e 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -232,11 +232,12 @@ add_condition (struct inline_summary *summary, int operand_num,
/* Add clause CLAUSE into the predicate P. */
static inline void
-add_clause (struct predicate *p, clause_t clause)
+add_clause (conditions conditions, struct predicate *p, clause_t clause)
{
int i;
int i2;
int insert_here = -1;
+ int c1, c2;
/* True clause. */
if (!clause)
@@ -281,6 +282,28 @@ add_clause (struct predicate *p, clause_t clause)
if ((p->clause[i] & clause) != clause)
i2++;
}
+
+ /* Look for clauses that are obviously true. I.e.
+ op0 == 5 || op0 != 5. */
+ for (c1 = predicate_first_dynamic_condition; c1 < NUM_CONDITIONS; c1++)
+ for (c2 = c1 + 1; c2 <= NUM_CONDITIONS; c2++)
+ if ((clause & (1 << c1))
+ && (clause & (1 << c2)))
+ {
+ condition *cc1 = VEC_index (condition,
+ conditions,
+ c1 - predicate_first_dynamic_condition);
+ condition *cc2 = VEC_index (condition,
+ conditions,
+ c2 - predicate_first_dynamic_condition);
+ if (cc1->operand_num == cc2->operand_num
+ && cc1->val == cc2->val
+ && cc1->code == invert_tree_comparison (cc2->code,
+ HONOR_NANS (TYPE_MODE (TREE_TYPE (cc1->val)))))
+ return;
+ }
+
+
/* We run out of variants. Be conservative in positive direction. */
if (i2 == MAX_CLAUSES)
return;
@@ -298,7 +321,8 @@ add_clause (struct predicate *p, clause_t clause)
/* Return P & P2. */
static struct predicate
-and_predicates (struct predicate *p, struct predicate *p2)
+and_predicates (conditions conditions,
+ struct predicate *p, struct predicate *p2)
{
struct predicate out = *p;
int i;
@@ -319,7 +343,7 @@ and_predicates (struct predicate *p, struct predicate *p2)
for (; p2->clause[i]; i++)
{
gcc_checking_assert (i < MAX_CLAUSES);
- add_clause (&out, p2->clause[i]);
+ add_clause (conditions, &out, p2->clause[i]);
}
return out;
}
@@ -346,7 +370,7 @@ predicates_equal_p (struct predicate *p, struct predicate *p2)
/* Return P | P2. */
static struct predicate
-or_predicates (struct predicate *p, struct predicate *p2)
+or_predicates (conditions conditions, struct predicate *p, struct predicate *p2)
{
struct predicate out = true_predicate ();
int i,j;
@@ -364,7 +388,7 @@ or_predicates (struct predicate *p, struct predicate *p2)
for (j = 0; p2->clause[j]; j++)
{
gcc_checking_assert (i < MAX_CLAUSES && j < MAX_CLAUSES);
- add_clause (&out, p->clause[i] | p2->clause[j]);
+ add_clause (conditions, &out, p->clause[i] | p2->clause[j]);
}
return out;
}
@@ -753,7 +777,7 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
break;
}
else
- add_clause (&new_predicate,
+ add_clause (info->conds, &new_predicate,
possible_truths & e->predicate.clause[j]);
if (false_predicate_p (&new_predicate))
{
@@ -781,7 +805,7 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
break;
}
else
- add_clause (&new_predicate,
+ add_clause (info->conds, &new_predicate,
possible_truths & es->predicate->clause[j]);
if (false_predicate_p (&new_predicate)
&& !false_predicate_p (es->predicate))
@@ -812,7 +836,7 @@ inline_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst,
break;
}
else
- add_clause (&new_predicate,
+ add_clause (info->conds, &new_predicate,
possible_truths & es->predicate->clause[j]);
if (false_predicate_p (&new_predicate)
&& !false_predicate_p (es->predicate))
@@ -1047,6 +1071,50 @@ initialize_inline_failed (struct cgraph_edge *e)
e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
}
+/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
+ boolean variable pointed to by DATA. */
+
+static bool
+mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
+ void *data)
+{
+ bool *b = (bool *) data;
+ *b = true;
+ return true;
+}
+
+/* If OP reffers to value of function parameter, return
+ the corresponding parameter. */
+
+static tree
+unmodified_parm (gimple stmt, tree op)
+{
+ /* SSA_NAME referring to parm default def? */
+ if (TREE_CODE (op) == SSA_NAME
+ && SSA_NAME_IS_DEFAULT_DEF (op)
+ && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
+ return SSA_NAME_VAR (op);
+ /* Non-SSA parm reference? */
+ if (TREE_CODE (op) == PARM_DECL)
+ {
+ bool modified = false;
+
+ ao_ref refd;
+ ao_ref_init (&refd, op);
+ walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
+ NULL);
+ if (!modified)
+ return op;
+ }
+ /* Assignment from a parameter? */
+ if (TREE_CODE (op) == SSA_NAME
+ && !SSA_NAME_IS_DEFAULT_DEF (op)
+ && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
+ return unmodified_parm (SSA_NAME_DEF_STMT (op),
+ gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)));
+ return NULL;
+}
+
/* See if statement might disappear after inlining.
0 - means not eliminated
1 - half of statements goes away
@@ -1058,6 +1126,10 @@ static int
eliminated_by_inlining_prob (gimple stmt)
{
enum gimple_code code = gimple_code (stmt);
+
+ if (!optimize)
+ return 0;
+
switch (code)
{
case GIMPLE_RETURN:
@@ -1090,11 +1162,7 @@ eliminated_by_inlining_prob (gimple stmt)
|| TREE_CODE (inner_rhs) == MEM_REF)
inner_rhs = TREE_OPERAND (inner_rhs, 0);
-
- if (TREE_CODE (inner_rhs) == PARM_DECL
- || (TREE_CODE (inner_rhs) == SSA_NAME
- && SSA_NAME_IS_DEFAULT_DEF (inner_rhs)
- && TREE_CODE (SSA_NAME_VAR (inner_rhs)) == PARM_DECL))
+ if (unmodified_parm (stmt, inner_rhs))
rhs_free = true;
if (rhs_free && is_gimple_reg (lhs))
lhs_free = true;
@@ -1136,6 +1204,7 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
edge_iterator ei;
gimple set_stmt;
tree op2;
+ tree parm;
last = last_stmt (bb);
if (!last
@@ -1147,11 +1216,10 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
/* TODO: handle conditionals like
var = op0 < 4;
if (var != 0). */
- if (TREE_CODE (op) != SSA_NAME)
- return;
- if (SSA_NAME_IS_DEFAULT_DEF (op))
+ parm = unmodified_parm (last, op);
+ if (parm)
{
- index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op));
+ index = ipa_get_param_decl_index (info, parm);
if (index == -1)
return;
code = gimple_cond_code (last);
@@ -1170,6 +1238,8 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
}
}
+ if (TREE_CODE (op) != SSA_NAME)
+ return;
/* Special case
if (builtin_constant_p (op))
constant_code
@@ -1185,11 +1255,10 @@ set_cond_stmt_execution_predicate (struct ipa_node_params *info,
|| gimple_call_num_args (set_stmt) != 1)
return;
op2 = gimple_call_arg (set_stmt, 0);
- if (TREE_CODE (op2) != SSA_NAME)
+ parm = unmodified_parm (set_stmt, op2);
+ if (!parm)
return;
- if (!SSA_NAME_IS_DEFAULT_DEF (op2))
- return;
- index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op2));
+ index = ipa_get_param_decl_index (info, parm);
if (index == -1)
return;
if (gimple_cond_code (last) != NE_EXPR
@@ -1223,16 +1292,17 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
edge_iterator ei;
size_t n;
size_t case_idx;
+ tree parm;
last = last_stmt (bb);
if (!last
|| gimple_code (last) != GIMPLE_SWITCH)
return;
op = gimple_switch_index (last);
- if (TREE_CODE (op) != SSA_NAME
- || !SSA_NAME_IS_DEFAULT_DEF (op))
+ parm = unmodified_parm (last, op);
+ if (!parm)
return;
- index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op));
+ index = ipa_get_param_decl_index (info, parm);
if (index == -1)
return;
@@ -1270,10 +1340,10 @@ set_switch_stmt_execution_predicate (struct ipa_node_params *info,
p2 = add_condition (summary, index,
LE_EXPR,
max);
- p = and_predicates (&p1, &p2);
+ p = and_predicates (summary->conds, &p1, &p2);
}
*(struct predicate *)e->aux
- = or_predicates (&p, (struct predicate *)e->aux);
+ = or_predicates (summary->conds, &p, (struct predicate *)e->aux);
}
}
@@ -1317,9 +1387,9 @@ compute_bb_predicates (struct cgraph_node *node,
{
struct predicate this_bb_predicate = *(struct predicate *)e->src->aux;
if (e->aux)
- this_bb_predicate = and_predicates (&this_bb_predicate,
+ this_bb_predicate = and_predicates (summary->conds, &this_bb_predicate,
(struct predicate *)e->aux);
- p = or_predicates (&p, &this_bb_predicate);
+ p = or_predicates (summary->conds, &p, &this_bb_predicate);
if (true_predicate_p (&p))
break;
}
@@ -1385,12 +1455,12 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
adding conditionals. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- if (TREE_CODE (use) != SSA_NAME)
- return p;
+ tree parm = unmodified_parm (stmt, use);
/* For arguments we can build a condition. */
- if (SSA_NAME_IS_DEFAULT_DEF (use)
- && ipa_get_param_decl_index (info, SSA_NAME_VAR (use)) >= 0)
+ if (parm && ipa_get_param_decl_index (info, parm) >= 0)
continue;
+ if (TREE_CODE (use) != SSA_NAME)
+ return p;
/* If we know when operand is constant,
we still can say something useful. */
if (!true_predicate_p (VEC_index (predicate_t, nonconstant_names,
@@ -1401,15 +1471,15 @@ will_be_nonconstant_predicate (struct ipa_node_params *info,
op_non_const = false_predicate ();
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- if (SSA_NAME_IS_DEFAULT_DEF (use)
- && ipa_get_param_decl_index (info, SSA_NAME_VAR (use)) >= 0)
+ tree parm = unmodified_parm (stmt, use);
+ if (parm && ipa_get_param_decl_index (info, parm) >= 0)
p = add_condition (summary,
- ipa_get_param_decl_index (info, SSA_NAME_VAR (use)),
+ ipa_get_param_decl_index (info, parm),
IS_NOT_CONSTANT, NULL);
else
p = *VEC_index (predicate_t, nonconstant_names,
SSA_NAME_VERSION (use));
- op_non_const = or_predicates (&p, &op_non_const);
+ op_non_const = or_predicates (summary->conds, &p, &op_non_const);
}
if (gimple_code (stmt) == GIMPLE_ASSIGN
&& TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
@@ -1563,7 +1633,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
fprintf (dump_file, "\t\twill eliminated by inlining\n");
if (parms_info)
- p = and_predicates (&bb_predicate, &will_be_nonconstant);
+ p = and_predicates (info->conds, &bb_predicate, &will_be_nonconstant);
else
p = true_predicate ();
@@ -1575,7 +1645,7 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
if (prob)
{
struct predicate ip = not_inlined_predicate ();
- ip = and_predicates (&ip, &p);
+ ip = and_predicates (info->conds, &ip, &p);
account_size_time (info, this_size * prob,
this_time * prob, &ip);
}
@@ -1901,11 +1971,12 @@ remap_predicate (struct inline_summary *info, struct inline_summary *callee_info
cond_predicate.clause[0] = 1 << cond;
cond_predicate.clause[1] = 0;
}
- clause_predicate = or_predicates (&clause_predicate, &cond_predicate);
+ clause_predicate = or_predicates (info->conds, &clause_predicate,
+ &cond_predicate);
}
- out = and_predicates (&out, &clause_predicate);
+ out = and_predicates (info->conds, &out, &clause_predicate);
}
- return and_predicates (&out, toplev_predicate);
+ return and_predicates (info->conds, &out, toplev_predicate);
}