OSDN Git Service

* regrename.c (copy_value): Don't replace fixed or global
[pf3gnuchains/gcc-fork.git] / gcc / tree-complex.c
index 1fa76a9..8938f5e 100644 (file)
@@ -15,8 +15,8 @@ for more details.
    
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -150,7 +150,7 @@ init_dont_simulate_again (void)
   basic_block bb;
   block_stmt_iterator bsi;
   tree phi;
-  bool saw_a_complex_value = false;
+  bool saw_a_complex_op = false;
 
   FOR_EACH_BB (bb)
     {
@@ -159,21 +159,70 @@ init_dont_simulate_again (void)
 
       for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
        {
-         tree stmt = bsi_stmt (bsi);
-         bool dsa = true;
+         tree orig_stmt, stmt, rhs = NULL;
+         bool dsa;
 
-         if (TREE_CODE (stmt) == MODIFY_EXPR
-             && is_complex_reg (TREE_OPERAND (stmt, 0)))
+         orig_stmt = stmt = bsi_stmt (bsi);
+
+         /* Most control-altering statements must be initially 
+            simulated, else we won't cover the entire cfg.  */
+         dsa = !stmt_ends_bb_p (stmt);
+
+         switch (TREE_CODE (stmt))
            {
-             dsa = false;
-             saw_a_complex_value = true;
+           case RETURN_EXPR:
+             /* We don't care what the lattice value of <retval> is,
+                since it's never used as an input to another computation.  */
+             dsa = true;
+             stmt = TREE_OPERAND (stmt, 0);
+             if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
+               break;
+             /* FALLTHRU */
+
+           case MODIFY_EXPR:
+             dsa = !is_complex_reg (TREE_OPERAND (stmt, 0));
+             rhs = TREE_OPERAND (stmt, 1);
+             break;
+
+           case COND_EXPR:
+             rhs = TREE_OPERAND (stmt, 0);
+             break;
+
+           default:
+             break;
            }
 
-         DONT_SIMULATE_AGAIN (stmt) = dsa;
+         if (rhs)
+           switch (TREE_CODE (rhs))
+             {
+             case EQ_EXPR:
+             case NE_EXPR:
+               rhs = TREE_OPERAND (rhs, 0);
+               /* FALLTHRU */
+
+             case PLUS_EXPR:
+             case MINUS_EXPR:
+             case MULT_EXPR:
+             case TRUNC_DIV_EXPR:
+             case CEIL_DIV_EXPR:
+             case FLOOR_DIV_EXPR:
+             case ROUND_DIV_EXPR:
+             case RDIV_EXPR:
+             case NEGATE_EXPR:
+             case CONJ_EXPR:
+               if (TREE_CODE (TREE_TYPE (rhs)) == COMPLEX_TYPE)
+                 saw_a_complex_op = true;
+               break;
+
+             default:
+               break;
+             }
+
+         DONT_SIMULATE_AGAIN (orig_stmt) = dsa;
        }
     }
 
-  return saw_a_complex_value;
+  return saw_a_complex_op;
 }
 
 
@@ -187,13 +236,14 @@ complex_visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED,
   unsigned int ver;
   tree lhs, rhs;
 
-  /* These conditions should be satisfied due to the initial filter
-     set up in init_dont_simulate_again.  */
-  gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return SSA_PROP_VARYING;
 
   lhs = TREE_OPERAND (stmt, 0);
   rhs = TREE_OPERAND (stmt, 1);
 
+  /* These conditions should be satisfied due to the initial filter
+     set up in init_dont_simulate_again.  */
   gcc_assert (TREE_CODE (lhs) == SSA_NAME);
   gcc_assert (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE);
 
@@ -308,6 +358,9 @@ create_components (void)
   size_t k, n;
 
   n = num_referenced_vars;
+  if (n == 0)
+    return;
+
   complex_variable_components = VEC_alloc (tree, heap, 2*n);
   VEC_safe_grow (tree, heap, complex_variable_components, 2*n);
 
@@ -531,6 +584,12 @@ update_phi_components (basic_block bb)
            tree arg = PHI_ARG_DEF (phi, i);
            tree r, i;
 
+           /* Avoid no-op assignments.  This also prevents insertting stmts
+              onto abnormal edges, assuming the PHI isn't already broken.  */
+           if (TREE_CODE (arg) == SSA_NAME
+               && SSA_NAME_VAR (arg) == SSA_NAME_VAR (lhs))
+             continue;
+
            r = extract_component (NULL, arg, 0, false);
            i = extract_component (NULL, arg, 1, false);
            update_complex_components_on_edge (e, NULL, lhs, r, i);