OSDN Git Service

/c-family
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dce.c
index edec49d..6dc8a57 100644 (file)
@@ -271,8 +271,6 @@ mark_operand_necessary (tree op)
 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))
@@ -311,12 +309,6 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
        }
       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:
@@ -433,6 +425,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
   gimple_stmt_iterator gsi;
   edge e;
   gimple phi, stmt;
+  int flags;
 
   FOR_EACH_BB (bb)
     {
@@ -454,9 +447,8 @@ find_obviously_necessary_stmts (struct edge_list *el)
 
   /* 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.  */
@@ -832,7 +824,10 @@ propagate_necessity (struct edge_list *el)
                  && 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
@@ -869,7 +864,8 @@ propagate_necessity (struct edge_list *el)
            {
              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))
@@ -1408,6 +1404,8 @@ perform_tree_ssa_dce (bool aggressive)
   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  */