static void
mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
{
- tree lhs = NULL_TREE;
-
/* With non-call exceptions, we have to assume that all statements could
throw. If a statement may throw, it is inherently necessary. */
if (cfun->can_throw_non_call_exceptions && stmt_could_throw_p (stmt))
}
if (!gimple_call_lhs (stmt))
return;
- lhs = gimple_call_lhs (stmt);
- /* Fall through */
-
- case GIMPLE_ASSIGN:
- if (!lhs)
- lhs = gimple_assign_lhs (stmt);
break;
case GIMPLE_DEBUG:
gimple_stmt_iterator gsi;
edge e;
gimple phi, stmt;
+ int flags;
FOR_EACH_BB (bb)
{
/* Pure and const functions are finite and thus have no infinite loops in
them. */
- if ((TREE_READONLY (current_function_decl)
- || DECL_PURE_P (current_function_decl))
- && !DECL_LOOPING_CONST_OR_PURE_P (current_function_decl))
+ flags = flags_from_decl_or_type (current_function_decl);
+ if ((flags & (ECF_CONST|ECF_PURE)) && !(flags & ECF_LOOPING_CONST_OR_PURE))
return;
/* Prevent the empty possibly infinite loops from being removed. */
&& DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
&& (DECL_FUNCTION_CODE (callee) == BUILT_IN_MEMSET
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
- || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE))
+ || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
+ || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
+ || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
+ || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE))
continue;
/* Calls implicitly load from memory, their arguments
{
tree rhs = gimple_return_retval (stmt);
/* A return statement may perform a load. */
- if (TREE_CODE (rhs) != SSA_NAME
+ if (rhs
+ && TREE_CODE (rhs) != SSA_NAME
&& !is_gimple_min_invariant (rhs))
{
if (!ref_may_be_aliased (rhs))
struct edge_list *el = NULL;
bool something_changed = 0;
+ calculate_dominance_info (CDI_DOMINATORS);
+
/* Preheaders are needed for SCEV to work.
Simple lateches and recorded exits improve chances that loop will
proved to be finite in testcases such as in loop-15.c and loop-24.c */