OSDN Git Service

* config/i386/i386.md (*sinxf2): Rename to *sinxf2_i387.
[pf3gnuchains/gcc-fork.git] / gcc / cse.c
index fc6ffff..549570b 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4499,8 +4499,7 @@ cse_insn (rtx insn, rtx libcall_insn)
                   const_elt; const_elt = const_elt->next_same_value)
                if (REG_P (const_elt->exp))
                  {
-                   src_related = gen_lowpart (mode,
-                                                          const_elt->exp);
+                   src_related = gen_lowpart (mode, const_elt->exp);
                    break;
                  }
            }
@@ -4587,8 +4586,7 @@ cse_insn (rtx insn, rtx libcall_insn)
                   larger_elt; larger_elt = larger_elt->next_same_value)
                if (REG_P (larger_elt->exp))
                  {
-                   src_related = gen_lowpart (mode,
-                                                          larger_elt->exp);
+                   src_related = gen_lowpart (mode, larger_elt->exp);
                    break;
                  }
 
@@ -4858,13 +4856,6 @@ cse_insn (rtx insn, rtx libcall_insn)
              validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
              apply_change_group ();
 
-             /* With non-call exceptions, if this was an insn that could
-                trap, we may have made it non-throwing now.  For example
-                we may have replaced a load with a register.  */
-             if (flag_non_call_exceptions
-                 && insn == BB_END (BLOCK_FOR_INSN (insn)))
-               purge_dead_edges (BLOCK_FOR_INSN (insn));
-
              break;
            }
 
@@ -5800,7 +5791,7 @@ cse_process_notes (rtx x, rtx object)
    Otherwise, DATA->path is filled and the function returns TRUE indicating
    that a path to follow was found.
 
-   If FOLLOW_JUMPS is false, the maximum path lenghth is 1 and the only
+   If FOLLOW_JUMPS is false, the maximum path length is 1 and the only
    block in the path will be FIRST_BB.  */
 
 static bool
@@ -5905,11 +5896,10 @@ cse_find_path (basic_block first_bb, struct cse_basic_block_data *data,
            {
              basic_block bb2 = e->dest;
 
-#if ENABLE_CHECKING
              /* We should only see blocks here that we have not
                 visited yet.  */
              gcc_assert (!TEST_BIT (cse_visited_basic_blocks, bb2->index));
-#endif
+
              SET_BIT (cse_visited_basic_blocks, bb2->index);
              data->path[path_size++].bb = bb2;
              bb = bb2;
@@ -5940,6 +5930,22 @@ cse_dump_path (struct cse_basic_block_data *data, int nsets, FILE *f)
 }
 
 \f
+/* Return true if BB has exception handling successor edges.  */
+
+static bool
+have_eh_succ_edges (basic_block bb)
+{
+  edge e;
+  edge_iterator ei;
+
+  FOR_EACH_EDGE (e, ei, bb->succs)
+    if (e->flags & EDGE_EH)
+      return true;
+
+  return false;
+}
+
+\f
 /* Scan to the end of the path described by DATA.  Return an estimate of
    the total number of SETs, and the lowest and highest insn CUID, of all
    insns in the path.  */
@@ -6110,6 +6116,12 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
       /* Make sure that libcalls don't span multiple basic blocks.  */
       gcc_assert (libcall_insn == NULL_RTX);
 
+      /* With non-call exceptions, we are not always able to update
+        the CFG properly inside cse_insn.  So clean up possibly
+        redundant EH edges here.  */
+      if (flag_non_call_exceptions && have_eh_succ_edges (bb))
+       purge_dead_edges (bb);
+
       /* If we changed a conditional jump, we may have terminated
         the path we are following.  Check that by verifying that
         the edge we would take still exists.  If the edge does
@@ -6119,7 +6131,21 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
        {
          basic_block next_bb = ebb_data->path[path_entry + 1].bb;
          if (!find_edge (bb, next_bb))
-           ebb_data->path_size = path_entry + 1;
+           {
+             do
+               {
+                 path_size--;
+
+                 /* If we truncate the path, we must also reset the
+                    visited bit on the remaining blocks in the path,
+                    or we will never visit them at all.  */
+                 RESET_BIT (cse_visited_basic_blocks,
+                            ebb_data->path[path_size].bb->index);
+                 ebb_data->path[path_size].bb = NULL;
+               }
+             while (path_size - 1 != path_entry);
+             ebb_data->path_size = path_size;
+           }
        }
 
       /* If this is a conditional jump insn, record any known
@@ -6159,7 +6185,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
 {
   struct cse_basic_block_data ebb_data;
   basic_block bb;
-  int *dfs_order = XNEWVEC (int, last_basic_block);
+  int *rc_order = XNEWVEC (int, last_basic_block);
   int i, n_blocks;
 
   init_cse_reg_info (nregs);
@@ -6197,17 +6223,17 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
        INSN_CUID (insn) = ++i;
     }
 
-  /* Loop over basic blocks in DFS order,
+  /* Loop over basic blocks in reverse completion order (RPO),
      excluding the ENTRY and EXIT blocks.  */
-  n_blocks = pre_and_rev_post_order_compute (dfs_order, NULL, false);
+  n_blocks = pre_and_rev_post_order_compute (NULL, rc_order, false);
   i = 0;
   while (i < n_blocks)
     {
-      /* Find the first block in the DFS queue that we have not yet
+      /* Find the first block in the RPO queue that we have not yet
         processed before.  */
       do
        {
-         bb = BASIC_BLOCK (dfs_order[i++]);
+         bb = BASIC_BLOCK (rc_order[i++]);
        }
       while (TEST_BIT (cse_visited_basic_blocks, bb->index)
             && i < n_blocks);
@@ -6222,7 +6248,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
          if (ebb_data.nsets == 0)
            continue;
 
-         /* Get a reasonable extimate for the maximum number of qty's
+         /* Get a reasonable estimate for the maximum number of qty's
             needed for this path.  For this, we take the number of sets
             and multiply that by MAX_RECOG_OPERANDS.  */
          max_qty = ebb_data.nsets * MAX_RECOG_OPERANDS;
@@ -6243,7 +6269,7 @@ cse_main (rtx f ATTRIBUTE_UNUSED, int nregs)
   free (reg_eqv_table);
   free (ebb_data.path);
   sbitmap_free (cse_visited_basic_blocks);
-  free (dfs_order);
+  free (rc_order);
   rtl_hooks = general_rtl_hooks;
 
   return cse_jumps_altered || recorded_label_ref;
@@ -6963,9 +6989,7 @@ gate_handle_cse (void)
 static unsigned int
 rest_of_handle_cse (void)
 {
-static int counter = 0;
   int tem;
-counter++;
   if (dump_file)
     dump_flow_info (dump_file, dump_flags);
 
@@ -6977,10 +7001,6 @@ counter++;
      expecting CSE to be run.  But always rerun it in a cheap mode.  */
   cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
 
-  /* If there are dead edges to purge, we haven't properly updated
-     the CFG incrementally.  */
-  gcc_assert (!purge_all_dead_edges ());
-
   if (tem)
     rebuild_jump_labels (get_insns ());
 
@@ -7033,10 +7053,6 @@ rest_of_handle_cse2 (void)
      bypassed safely.  */
   cse_condition_code_reg ();
 
-  /* If there are dead edges to purge, we haven't properly updated
-     the CFG incrementally.  */
-  gcc_assert (!purge_all_dead_edges ());
-
   delete_trivially_dead_insns (get_insns (), max_reg_num ());
 
   if (tem)