OSDN Git Service

gcc/fortran/
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-phiopt.c
index 3cdb9b3..482f267 100644 (file)
@@ -24,12 +24,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "ggc.h"
 #include "tree.h"
-#include "rtl.h"
 #include "flags.h"
 #include "tm_p.h"
 #include "basic-block.h"
 #include "timevar.h"
-#include "diagnostic.h"
 #include "tree-flow.h"
 #include "tree-pass.h"
 #include "tree-dump.h"
@@ -207,7 +205,7 @@ tree_ssa_phiopt_worker (bool do_store_elim)
   bb_order = blocks_in_phiopt_order ();
   n = n_basic_blocks - NUM_FIXED_BLOCKS;
 
-  for (i = 0; i < n; i++) 
+  for (i = 0; i < n; i++)
     {
       gimple cond_stmt, phi;
       basic_block bb1, bb2;
@@ -307,7 +305,7 @@ tree_ssa_phiopt_worker (bool do_store_elim)
     }
 
   free (bb_order);
-  
+
   if (do_store_elim)
     pointer_set_destroy (nontrap);
   /* If the CFG has changed, we should cleanup the CFG.  */
@@ -332,12 +330,12 @@ blocks_in_phiopt_order (void)
 {
   basic_block x, y;
   basic_block *order = XNEWVEC (basic_block, n_basic_blocks);
-  unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS; 
+  unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS;
   unsigned np, i;
-  sbitmap visited = sbitmap_alloc (last_basic_block); 
+  sbitmap visited = sbitmap_alloc (last_basic_block);
 
-#define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index)) 
-#define VISITED_P(BB) (TEST_BIT (visited, (BB)->index)) 
+#define MARK_VISITED(BB) (SET_BIT (visited, (BB)->index))
+#define VISITED_P(BB) (TEST_BIT (visited, (BB)->index))
 
   sbitmap_zero (visited);
 
@@ -384,7 +382,12 @@ bool
 empty_block_p (basic_block bb)
 {
   /* BB must have no executable statements.  */
-  return gsi_end_p (gsi_after_labels (bb));
+  gimple_stmt_iterator gsi = gsi_after_labels (bb);
+  if (gsi_end_p (gsi))
+    return true;
+  if (is_gimple_debug (gsi_stmt (gsi)))
+    gsi_next_nondebug (&gsi);
+  return gsi_end_p (gsi);
 }
 
 /* Replace PHI node element whose edge is E in block BB with variable NEW.
@@ -513,6 +516,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
 
   if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
     {
+      source_location locus_0, locus_1;
+
       new_var2 = create_tmp_var (TREE_TYPE (result), NULL);
       add_referenced_var (new_var2);
       new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
@@ -521,6 +526,13 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
       gimple_assign_set_lhs (new_stmt, new_var2);
       gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
       new_var = new_var2;
+
+      /* Set the locus to the first argument, unless is doesn't have one.  */
+      locus_0 = gimple_phi_arg_location (phi, 0);
+      locus_1 = gimple_phi_arg_location (phi, 1);
+      if (locus_0 == UNKNOWN_LOCATION)
+        locus_0 = locus_1;
+      gimple_set_location (new_stmt, locus_0);
     }
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
@@ -682,7 +694,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
          && operand_equal_for_phi_arg_p (arg_false, larger))
        {
          /* Case
-        
+
             if (smaller < larger)
             rslt = smaller;
             else
@@ -843,7 +855,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
 
       /* Move the statement from the middle block.  */
       gsi = gsi_last_bb (cond_bb);
-      gsi_from = gsi_last_bb (middle_bb);
+      gsi_from = gsi_last_nondebug_bb (middle_bb);
       gsi_move_before (&gsi_from, &gsi);
     }
 
@@ -891,7 +903,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
      optimize.  */
   if (assign == NULL)
     return false;
-      
+
   /* If we got here, then we have found the only executable statement
      in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
      arg1 = -arg0, then we can not optimize.  */
@@ -904,7 +916,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
     return false;
 
   rhs = gimple_assign_rhs1 (assign);
-              
+
   /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
   if (!(lhs == arg0 && rhs == arg1)
       && !(lhs == arg1 && rhs == arg0))
@@ -982,10 +994,10 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
 
 /* Auxiliary functions to determine the set of memory accesses which
    can't trap because they are preceded by accesses to the same memory
-   portion.  We do that for INDIRECT_REFs, so we only need to track
+   portion.  We do that for MEM_REFs, so we only need to track
    the SSA_NAME of the pointer indirectly referenced.  The algorithm
    simply is a walk over all instructions in dominator order.  When
-   we see an INDIRECT_REF we determine if we've already seen a same
+   we see an MEM_REF we determine if we've already seen a same
    ref anywhere up to the root of the dominator tree.  If we do the
    current access can't trap.  If we don't see any dominating access
    the current access might trap, but might also make later accesses
@@ -999,7 +1011,7 @@ abs_replacement (basic_block cond_bb, basic_block middle_bb,
    trap even if a store doesn't (write-only memory).  This probably is
    overly conservative.  */
 
-/* A hash-table of SSA_NAMEs, and in which basic block an INDIRECT_REF
+/* A hash-table of SSA_NAMEs, and in which basic block an MEM_REF
    through it was seen, which would constitute a no-trap region for
    same accesses.  */
 struct name_to_bb
@@ -1012,7 +1024,7 @@ struct name_to_bb
 /* The hash table for remembering what we've seen.  */
 static htab_t seen_ssa_names;
 
-/* The set of INDIRECT_REFs which can't trap.  */
+/* The set of MEM_REFs which can't trap.  */
 static struct pointer_set_t *nontrap_set;
 
 /* The hash function, based on the pointer to the pointer SSA_NAME.  */
@@ -1035,7 +1047,7 @@ name_to_bb_eq (const void *p1, const void *p2)
 }
 
 /* We see the expression EXP in basic block BB.  If it's an interesting
-   expression (an INDIRECT_REF through an SSA_NAME) possibly insert the
+   expression (an MEM_REF through an SSA_NAME) possibly insert the
    expression into the set NONTRAP or the hash table of seen expressions.
    STORE is true if this expression is on the LHS, otherwise it's on
    the RHS.  */
@@ -1043,7 +1055,7 @@ static void
 add_or_mark_expr (basic_block bb, tree exp,
                  struct pointer_set_t *nontrap, bool store)
 {
-  if (INDIRECT_REF_P (exp)
+  if (TREE_CODE (exp) == MEM_REF
       && TREE_CODE (TREE_OPERAND (exp, 0)) == SSA_NAME)
     {
       tree name = TREE_OPERAND (exp, 0);
@@ -1052,7 +1064,7 @@ add_or_mark_expr (basic_block bb, tree exp,
       struct name_to_bb *n2bb;
       basic_block found_bb = 0;
 
-      /* Try to find the last seen INDIRECT_REF through the same
+      /* Try to find the last seen MEM_REF through the same
          SSA_NAME, which can trap.  */
       map.ssa_name = name;
       map.bb = 0;
@@ -1062,7 +1074,7 @@ add_or_mark_expr (basic_block bb, tree exp,
       if (n2bb)
         found_bb = n2bb->bb;
 
-      /* If we've found a trapping INDIRECT_REF, _and_ it dominates EXP
+      /* If we've found a trapping MEM_REF, _and_ it dominates EXP
          (it's in a basic block on the path from us to the dominator root)
         then we can't trap.  */
       if (found_bb && found_bb->aux == (void *)1)
@@ -1123,7 +1135,7 @@ nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
 /* This is the entry point of gathering non trapping memory accesses.
    It will do a dominator walk over the whole function, and it will
    make use of the bb->aux pointers.  It returns a set of trees
-   (the INDIRECT_REFs itself) which can't trap.  */
+   (the MEM_REFs itself) which can't trap.  */
 static struct pointer_set_t *
 get_non_trapping (void)
 {
@@ -1139,18 +1151,12 @@ get_non_trapping (void)
 
   /* Setup callbacks for the generic dominator tree walker.  */
   nontrap_set = nontrap;
-  walk_data.walk_stmts_backward = false;
   walk_data.dom_direction = CDI_DOMINATORS;
   walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children_before_stmts = nt_init_block;
-  walk_data.before_dom_children_walk_stmts = NULL;
-  walk_data.before_dom_children_after_stmts = NULL;
-  walk_data.after_dom_children_before_stmts = NULL;
-  walk_data.after_dom_children_walk_stmts = NULL;
-  walk_data.after_dom_children_after_stmts = nt_fini_block;
+  walk_data.before_dom_children = nt_init_block;
+  walk_data.after_dom_children = nt_fini_block;
   walk_data.global_data = NULL;
   walk_data.block_local_data_size = 0;
-  walk_data.interesting_blocks = NULL;
 
   init_walk_dominator_tree (&walk_data);
   walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
@@ -1183,6 +1189,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
   tree lhs, rhs, name;
   gimple newphi, new_stmt;
   gimple_stmt_iterator gsi;
+  source_location locus;
   enum tree_code code;
 
   /* Check if middle_bb contains of only one store.  */
@@ -1190,9 +1197,11 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
       || gimple_code (assign) != GIMPLE_ASSIGN)
     return false;
 
+  locus = gimple_location (assign);
   lhs = gimple_assign_lhs (assign);
   rhs = gimple_assign_rhs1 (assign);
-  if (!INDIRECT_REF_P (lhs))
+  if (TREE_CODE (lhs) != MEM_REF
+      || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME)
     return false;
 
   /* RHS is either a single SSA_NAME or a constant. */
@@ -1216,11 +1225,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
         of the memory touched by the store, if we need to.  */
   if (!condstoretemp || TREE_TYPE (lhs) != TREE_TYPE (condstoretemp))
     {
-      condstoretemp = create_tmp_var (TREE_TYPE (lhs), "cstore");
+      condstoretemp = create_tmp_reg (TREE_TYPE (lhs), "cstore");
       get_var_ann (condstoretemp);
-      if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
-          || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
-       DECL_GIMPLE_REG_P (condstoretemp) = 1;
     }
   add_referenced_var (condstoretemp);
 
@@ -1230,6 +1236,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
   new_stmt = gimple_build_assign (condstoretemp, lhs);
   name = make_ssa_name (condstoretemp, new_stmt);
   gimple_assign_set_lhs (new_stmt, name);
+  gimple_set_location (new_stmt, locus);
   mark_symbols_for_renaming (new_stmt);
   gsi_insert_on_edge (e1, new_stmt);
 
@@ -1237,8 +1244,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
         holding the old RHS, and the other holding the temporary
         where we stored the old memory contents.  */
   newphi = create_phi_node (condstoretemp, join_bb);
-  add_phi_arg (newphi, rhs, e0);
-  add_phi_arg (newphi, name, e1);
+  add_phi_arg (newphi, rhs, e0, locus);
+  add_phi_arg (newphi, name, e1, locus);
 
   lhs = unshare_expr (lhs);
   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));