tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Use bsi_after_labels.
authorZdenek Dvorak <dvorakz@suse.cz>
Tue, 1 May 2007 10:17:43 +0000 (12:17 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Tue, 1 May 2007 10:17:43 +0000 (10:17 +0000)
* tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Use
bsi_after_labels.  Always insert statements before bsi.
* tree-vect-transform.c (vect_create_epilog_for_reduction): Ditto.
* predict.c (apply_return_prediction): Check for empty blocks.
* cfgexpand.c (lab_rtx_for_bb): New variable.
(label_rtx_for_bb): Do not create new tree labels.
(expand_gimple_basic_block): Add labels recorded in lab_rtx_for_bb.
(tree_expand_cfg): Initialize lab_rtx_for_bb.
* tree-cfg.c (build_tree_cfg): Call cleanup_dead_labels after
creating edges.
(label_for_bb): Add field used.
(update_eh_label, main_block_label): Mark the label used.
(cleanup_dead_labels): Remove unused labels.

From-SVN: r124322

gcc/ChangeLog
gcc/cfgexpand.c
gcc/predict.c
gcc/tree-cfg.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-vect-transform.c

index 33a45f0ce139474a7556861d964c9ef1e727c03c..2230102974d838567003aff951dea9372d3e8e96 100644 (file)
@@ -1,3 +1,19 @@
+2007-05-01  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Use
+       bsi_after_labels.  Always insert statements before bsi.
+       * tree-vect-transform.c (vect_create_epilog_for_reduction): Ditto.
+       * predict.c (apply_return_prediction): Check for empty blocks.
+       * cfgexpand.c (lab_rtx_for_bb): New variable.
+       (label_rtx_for_bb): Do not create new tree labels.
+       (expand_gimple_basic_block): Add labels recorded in lab_rtx_for_bb.
+       (tree_expand_cfg): Initialize lab_rtx_for_bb.
+       * tree-cfg.c (build_tree_cfg): Call cleanup_dead_labels after
+       creating edges.
+       (label_for_bb): Add field used.
+       (update_eh_label, main_block_label): Mark the label used.
+       (cleanup_dead_labels): Remove unused labels.
+
 2007-05-01  Richard Guenther  <rguenther@suse.de>
 
        * tree-vrp.c (set_value_range): Do not allocate equiv bitmap
index c8d446f12bd9ce5ede98649c69d9b025cf94b96a..da1e8552e24bb1f36b7dc7842133b780021c87a1 100644 (file)
@@ -1244,6 +1244,10 @@ maybe_dump_rtl_for_tree_stmt (tree stmt, rtx since)
     }
 }
 
+/* Maps the blocks that do not contain tree labels to rtx labels.  */
+
+static struct pointer_map_t *lab_rtx_for_bb;
+
 /* Returns the label_rtx expression for a label starting basic block BB.  */
 
 static rtx
@@ -1251,12 +1255,17 @@ label_rtx_for_bb (basic_block bb)
 {
   tree_stmt_iterator tsi;
   tree lab, lab_stmt;
+  void **elt;
 
   if (bb->flags & BB_RTL)
     return block_label (bb);
 
-  /* We cannot use tree_block_label, as we no longer have stmt annotations.
-     TODO -- avoid creating the new tree labels.  */
+  elt = pointer_map_contains (lab_rtx_for_bb, bb);
+  if (elt)
+    return *elt;
+
+  /* Find the tree label if it is present.  */
+     
   for (tsi = tsi_start (bb_stmt_list (bb)); !tsi_end_p (tsi); tsi_next (&tsi))
     {
       lab_stmt = tsi_stmt (tsi);
@@ -1270,10 +1279,9 @@ label_rtx_for_bb (basic_block bb)
       return label_rtx (lab);
     }
 
-  lab = create_artificial_label ();
-  lab_stmt = build1 (LABEL_EXPR, void_type_node, lab);
-  tsi_link_before (&tsi, lab_stmt, TSI_NEW_STMT);
-  return label_rtx (lab);
+  elt = pointer_map_insert (lab_rtx_for_bb, bb);
+  *elt = gen_label_rtx ();
+  return *elt;
 }
 
 /* A subroutine of expand_gimple_basic_block.  Expand one COND_EXPR.
@@ -1477,6 +1485,7 @@ expand_gimple_basic_block (basic_block bb)
   rtx note, last;
   edge e;
   edge_iterator ei;
+  void **elt;
 
   if (dump_file)
     {
@@ -1510,20 +1519,32 @@ expand_gimple_basic_block (basic_block bb)
 
   tsi = tsi_start (stmts);
   if (!tsi_end_p (tsi))
-    stmt = tsi_stmt (tsi);
+    {
+      stmt = tsi_stmt (tsi);
+      if (TREE_CODE (stmt) != LABEL_EXPR)
+       stmt = NULL_TREE;
+    }
 
-  if (stmt && TREE_CODE (stmt) == LABEL_EXPR)
+  elt = pointer_map_contains (lab_rtx_for_bb, bb);
+
+  if (stmt || elt)
     {
       last = get_last_insn ();
 
-      expand_expr_stmt (stmt);
+      if (stmt)
+       {
+         expand_expr_stmt (stmt);
+         tsi_next (&tsi);
+       }
+
+      if (elt)
+       emit_label (*elt);
 
       /* Java emits line number notes in the top of labels.
         ??? Make this go away once line number notes are obsoleted.  */
       BB_HEAD (bb) = NEXT_INSN (last);
       if (NOTE_P (BB_HEAD (bb)))
        BB_HEAD (bb) = NEXT_INSN (BB_HEAD (bb));
-      tsi_next (&tsi);
       note = emit_note_after (NOTE_INSN_BASIC_BLOCK, BB_HEAD (bb));
 
       maybe_dump_rtl_for_tree_stmt (stmt, last);
@@ -1896,8 +1917,10 @@ tree_expand_cfg (void)
   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
     e->flags &= ~EDGE_EXECUTABLE;
 
+  lab_rtx_for_bb = pointer_map_create ();
   FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
     bb = expand_gimple_basic_block (bb);
+  pointer_map_destroy (lab_rtx_for_bb);
 
   construct_exit_block ();
   set_curr_insn_block (DECL_INITIAL (current_function_decl));
index c51c80809c8a67a15ee8c9bc3f7559e71eed7bf0..f4ecb6fd415af60a4db366c952de552ac381ac48 100644 (file)
@@ -1240,7 +1240,8 @@ apply_return_prediction (int *heads)
   FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
     {
       return_stmt = last_stmt (e->src);
-      if (TREE_CODE (return_stmt) == RETURN_EXPR)
+      if (return_stmt
+         && TREE_CODE (return_stmt) == RETURN_EXPR)
        break;
     }
   if (!e)
index 89339bc9a61ea7ebffda6588a788d8a2637afb3c..bf15bceeb4c905a35e7fea04078fe9e85ce8ae30 100644 (file)
@@ -181,6 +181,7 @@ build_tree_cfg (tree *tp)
 
   /* Create the edges of the flowgraph.  */
   make_edges ();
+  cleanup_dead_labels ();
 
   /* Debugging dumps.  */
 
@@ -830,11 +831,19 @@ make_goto_expr_edges (basic_block bb)
    to do early because it allows us to group case labels before creating
    the edges for the CFG, and it speeds up block statement iterators in
    all passes later on.
-   We only run this pass once, running it more than once is probably not
-   profitable.  */
+   We rerun this pass after CFG is created, to get rid of the labels that
+   are no longer referenced.  After then we do not run it any more, since
+   (almost) no new labels should be created.  */
 
 /* A map from basic block index to the leading label of that block.  */
-static tree *label_for_bb;
+static struct label_record
+{
+  /* The label.  */
+  tree label;
+
+  /* True if the label is referenced from somewhere.  */
+  bool used;
+} *label_for_bb;
 
 /* Callback for for_each_eh_region.  Helper for cleanup_dead_labels.  */
 static void
@@ -852,7 +861,8 @@ update_eh_label (struct eh_region *region)
       if (! bb)
        return;
 
-      new_label = label_for_bb[bb->index];
+      new_label = label_for_bb[bb->index].label;
+      label_for_bb[bb->index].used = true;
       set_eh_region_tree_label (region, new_label);
     }
 }
@@ -862,11 +872,17 @@ static tree
 main_block_label (tree label)
 {
   basic_block bb = label_to_block (label);
+  tree main_label = label_for_bb[bb->index].label;
 
   /* label_to_block possibly inserted undefined label into the chain.  */
-  if (!label_for_bb[bb->index])
-    label_for_bb[bb->index] = label;
-  return label_for_bb[bb->index];
+  if (!main_label)
+    {
+      label_for_bb[bb->index].label = label;
+      main_label = label;
+    }
+
+  label_for_bb[bb->index].used = true;
+  return main_label;
 }
 
 /* Cleanup redundant labels.  This is a three-step process:
@@ -878,7 +894,7 @@ void
 cleanup_dead_labels (void)
 {
   basic_block bb;
-  label_for_bb = XCNEWVEC (tree, last_basic_block);
+  label_for_bb = XCNEWVEC (struct label_record, last_basic_block);
 
   /* Find a suitable label for each block.  We use the first user-defined
      label if there is one, or otherwise just the first label we see.  */
@@ -897,19 +913,19 @@ cleanup_dead_labels (void)
 
          /* If we have not yet seen a label for the current block,
             remember this one and see if there are more labels.  */
-         if (! label_for_bb[bb->index])
+         if (!label_for_bb[bb->index].label)
            {
-             label_for_bb[bb->index] = label;
+             label_for_bb[bb->index].label = label;
              continue;
            }
 
          /* If we did see a label for the current block already, but it
             is an artificially created label, replace it if the current
             label is a user defined label.  */
-         if (! DECL_ARTIFICIAL (label)
-             && DECL_ARTIFICIAL (label_for_bb[bb->index]))
+         if (!DECL_ARTIFICIAL (label)
+             && DECL_ARTIFICIAL (label_for_bb[bb->index].label))
            {
-             label_for_bb[bb->index] = label;
+             label_for_bb[bb->index].label = label;
              break;
            }
        }
@@ -981,11 +997,15 @@ cleanup_dead_labels (void)
   FOR_EACH_BB (bb)
     {
       block_stmt_iterator i;
-      tree label_for_this_bb = label_for_bb[bb->index];
+      tree label_for_this_bb = label_for_bb[bb->index].label;
 
-      if (! label_for_this_bb)
+      if (!label_for_this_bb)
        continue;
 
+      /* If the main label of the block is unused, we may still remove it.  */
+      if (!label_for_bb[bb->index].used)
+       label_for_this_bb = NULL;
+
       for (i = bsi_start (bb); !bsi_end_p (i); )
        {
          tree label, stmt = bsi_stmt (i);
index d26608b4cd1917ff044b4807666947c4cad16562..1e5c5039ac028eb6351ba4f2f205c7a775200d82 100644 (file)
@@ -4866,7 +4866,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
 {
   tree comp;
   tree op, stmts, tgt, ass;
-  block_stmt_iterator bsi, pbsi;
+  block_stmt_iterator bsi;
 
   /* An important special case -- if we are asked to express value of
      the original iv by itself, just exit; there is no need to
@@ -4937,13 +4937,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       if (name_info (data, tgt)->preserve_biv)
        return;
 
-      pbsi = bsi = bsi_start (bb_for_stmt (use->stmt));
-      while (!bsi_end_p (pbsi)
-            && TREE_CODE (bsi_stmt (pbsi)) == LABEL_EXPR)
-       {
-         bsi = pbsi;
-         bsi_next (&pbsi);
-       }
+      bsi = bsi_after_labels (bb_for_stmt (use->stmt));
       break;
 
     case GIMPLE_MODIFY_STMT:
@@ -4956,22 +4950,18 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
     }
 
   op = force_gimple_operand (comp, &stmts, false, SSA_NAME_VAR (tgt));
+  if (stmts)
+    bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
 
   if (TREE_CODE (use->stmt) == PHI_NODE)
     {
-      if (stmts)
-       bsi_insert_after (&bsi, stmts, BSI_CONTINUE_LINKING);
       ass = build_gimple_modify_stmt (tgt, op);
-      bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
+      bsi_insert_before (&bsi, ass, BSI_SAME_STMT);
       remove_statement (use->stmt, false);
       SSA_NAME_DEF_STMT (tgt) = ass;
     }
   else
-    {
-      if (stmts)
-       bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
-      GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
-    }
+    GIMPLE_STMT_OPERAND (use->stmt, 1) = op;
 }
 
 /* Replaces ssa name in index IDX by its basic variable.  Callback for
index 4051cc6eb3fce2120465b5b6c4c82940a03750c5..161e82d3314da6ecb9e59bfa9650a735b50074f1 100644 (file)
@@ -1174,7 +1174,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
   exit_bb = single_exit (loop)->dest;
   new_phi = create_phi_node (SSA_NAME_VAR (vect_def), exit_bb);
   SET_PHI_ARG_DEF (new_phi, single_exit (loop)->dest_idx, vect_def);
-  exit_bsi = bsi_start (exit_bb);
+  exit_bsi = bsi_after_labels (exit_bb);
 
   /* 2.2 Get the relevant tree-code to use in the epilog for schemes 2,3 
          (i.e. when reduc_code is not available) and in the final adjustment
@@ -1223,7 +1223,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
       epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
       new_temp = make_ssa_name (vec_dest, epilog_stmt);
       GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
-      bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+      bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
 
       extract_scalar_result = true;
     }
@@ -1280,13 +1280,13 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
              epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
              new_name = make_ssa_name (vec_dest, epilog_stmt);
              GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_name;
-             bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+             bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
 
              tmp = build2 (code, vectype, new_name, new_temp);
              epilog_stmt = build_gimple_modify_stmt (vec_dest, tmp);
              new_temp = make_ssa_name (vec_dest, epilog_stmt);
              GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
-             bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+             bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
            }
 
          extract_scalar_result = true;
@@ -1316,7 +1316,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
          epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
          new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
          GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
-         bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+         bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
              
          for (bit_offset = element_bitsize;
               bit_offset < vec_size_in_bits;
@@ -1331,13 +1331,13 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
              epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
              new_name = make_ssa_name (new_scalar_dest, epilog_stmt);
              GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_name;
-             bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+             bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
 
              tmp = build2 (code, scalar_type, new_name, new_temp);
              epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, tmp);
              new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
              GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
-             bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+             bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
            }
 
          extract_scalar_result = false;
@@ -1366,7 +1366,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
       epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, rhs);
       new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
       GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp; 
-      bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+      bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
     }
 
   /* 2.4 Adjust the final result by the initial value of the reduction
@@ -1382,7 +1382,7 @@ vect_create_epilog_for_reduction (tree vect_def, tree stmt,
       epilog_stmt = build_gimple_modify_stmt (new_scalar_dest, tmp);
       new_temp = make_ssa_name (new_scalar_dest, epilog_stmt);
       GIMPLE_STMT_OPERAND (epilog_stmt, 0) = new_temp;
-      bsi_insert_after (&exit_bsi, epilog_stmt, BSI_NEW_STMT);
+      bsi_insert_before (&exit_bsi, epilog_stmt, BSI_SAME_STMT);
     }
 
   /* 2.6 Replace uses of s_out0 with uses of s_out3  */