===================================================================
@@ -936,6 +936,57 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUS
return true;
}
+/* Return ture if STMT is builtin_expect on one of its variants. */
+
+static bool
+builtin_expect_call_p (gimple *stmt)
+{
+ return ((gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
+ || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY)
+ || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
+ && gimple_call_num_args (stmt));
+}
+
+/* Walk to the original assignment to OP skipping wrapping noop casts,
+ builtin expectes etc. */
+
+static tree
+strip_copies (tree op, gimple **stmt = NULL)
+{
+ STRIP_NOPS (op);
+ /* TODO: We should have some common way to tell if function returns its
+ argument. */
+ if (TREE_CODE (op) == CALL_EXPR)
+ {
+ tree fndecl = get_callee_fndecl (op);
+ if (!fndecl)
+ return op;
+ if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+ || DECL_FUNCTION_CODE (fndecl)
+ == BUILT_IN_EXPECT_WITH_PROBABILITY))
+ return strip_copies (CALL_EXPR_ARG (op, 0), stmt);
+ return op;
+ }
+ if (TREE_CODE (op) == SSA_NAME
+ && builtin_expect_call_p (SSA_NAME_DEF_STMT (op)))
+ {
+ if (stmt)
+ *stmt = SSA_NAME_DEF_STMT (op);
+ return strip_copies (gimple_call_arg (SSA_NAME_DEF_STMT (op), 0), stmt);
+ }
+ if (TREE_CODE (op) == SSA_NAME
+ && !SSA_NAME_IS_DEFAULT_DEF (op)
+ && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
+ {
+ if (stmt)
+ *stmt = SSA_NAME_DEF_STMT (op);
+ return strip_copies (gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
+ stmt);
+ }
+ return op;
+}
+
/* If OP refers to value of function parameter, return the corresponding
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. */
@@ -979,16 +1030,10 @@ unmodified_parm_1 (gimple *stmt, tree op
static tree
unmodified_parm (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
{
+ op = strip_copies (op, &stmt);
tree res = unmodified_parm_1 (stmt, op, size_p);
if (res)
return res;
-
- 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)),
- size_p);
return NULL_TREE;
}
@@ -1005,6 +1050,7 @@ unmodified_parm_or_parm_agg_item (struct
HOST_WIDE_INT *size_p,
struct agg_position_info *aggpos)
{
+ op = strip_copies (op, &stmt);
tree res = unmodified_parm_1 (stmt, op, size_p);
gcc_checking_assert (aggpos);
@@ -1450,12 +1496,13 @@ will_be_nonconstant_expr_predicate (stru
nonconstant_names);
return p2.or_with (summary->conds, p1);
}
- else if (TREE_CODE (expr) == CALL_EXPR)
- return true;
- else
+ else
{
- debug_tree (expr);
- gcc_unreachable ();
+ tree expr2 = strip_copies (expr);
+ if (expr2 != expr)
+ return will_be_nonconstant_expr_predicate (info, summary, expr2,
+ nonconstant_names);
+ return true;
}
return false;
}