OSDN Git Service

2006-11-28 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index 93c366b..0518e4c 100644 (file)
@@ -1170,6 +1170,14 @@ static basic_block current_bb;
 static int
 want_to_gcse_p (rtx x)
 {
+#ifdef STACK_REGS
+  /* On register stack architectures, don't GCSE constants from the
+     constant pool, as the benefits are often swamped by the overhead
+     of shuffling the register stack between basic blocks.  */
+  if (IS_STACK_MODE (GET_MODE (x)))
+    x = avoid_constant_pool_reference (x);
+#endif
+
   switch (GET_CODE (x))
     {
     case REG:
@@ -2639,6 +2647,11 @@ try_replace_reg (rtx from, rtx to, rtx insn)
   int success = 0;
   rtx set = single_set (insn);
 
+  /* Usually we substitute easy stuff, so we won't copy everything.
+     We however need to take care to not duplicate non-trivial CONST
+     expressions.  */
+  to = copy_rtx (to);
+
   validate_replace_src_group (from, to, insn);
   if (num_changes_pending () && apply_change_group ())
     success = 1;
@@ -2652,9 +2665,9 @@ try_replace_reg (rtx from, rtx to, rtx insn)
        validate_change (insn, &SET_SRC (set), src, 0);
     }
 
-  /* If there is already a NOTE, update the expression in it with our
-     replacement.  */
-  if (note != 0)
+  /* If there is already a REG_EQUAL note, update the expression in it
+     with our replacement.  */
+  if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL)
     XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), from, to);
 
   if (!success && set && reg_mentioned_p (from, SET_SRC (set)))
@@ -2681,7 +2694,7 @@ try_replace_reg (rtx from, rtx to, rtx insn)
      We don't allow that. Remove that note. This code ought
      not to happen, because previous code ought to synthesize
      reg-reg move, but be on the safe side.  */
-  if (note && REG_P (XEXP (note, 0)))
+  if (note && REG_NOTE_KIND (note) == REG_EQUAL && REG_P (XEXP (note, 0)))
     remove_note (insn, note);
 
   return success;
@@ -3388,7 +3401,8 @@ one_cprop_pass (int pass, bool cprop_jumps, bool bypass_jumps)
   global_const_prop_count = local_const_prop_count = 0;
   global_copy_prop_count = local_copy_prop_count = 0;
 
-  local_cprop_pass (cprop_jumps);
+  if (cprop_jumps)
+    local_cprop_pass (cprop_jumps);
 
   /* Determine implicit sets.  */
   implicit_sets = XCNEWVEC (rtx, last_basic_block);
@@ -4568,9 +4582,6 @@ one_pre_gcse_pass (int pass)
    LABEL_NUSES count is incremented.  We have to add REG_LABEL notes,
    because the following loop optimization pass requires them.  */
 
-/* ??? This is very similar to the loop.c add_label_notes function.  We
-   could probably share code here.  */
-
 /* ??? If there was a jump optimization pass after gcse and before loop,
    then we would not need to do this here, because jump would add the
    necessary REG_LABEL notes.  */
@@ -6613,7 +6624,7 @@ gate_handle_jump_bypass (void)
 }
 
 /* Perform jump bypassing and control flow optimizations.  */
-static void
+static unsigned int
 rest_of_handle_jump_bypass (void)
 {
   cleanup_cfg (CLEANUP_EXPENSIVE);
@@ -6625,6 +6636,7 @@ rest_of_handle_jump_bypass (void)
       cleanup_cfg (CLEANUP_EXPENSIVE);
       delete_trivially_dead_insns (get_insns (), max_reg_num ());
     }
+  return 0;
 }
 
 struct tree_opt_pass pass_jump_bypass =
@@ -6653,7 +6665,7 @@ gate_handle_gcse (void)
 }
 
 
-static void
+static unsigned int
 rest_of_handle_gcse (void)
 {
   int save_csb, save_cfj;
@@ -6687,12 +6699,13 @@ rest_of_handle_gcse (void)
       timevar_push (TV_JUMP);
       rebuild_jump_labels (get_insns ());
       delete_dead_jumptables ();
-      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+      cleanup_cfg (CLEANUP_EXPENSIVE);
       timevar_pop (TV_JUMP);
     }
 
   flag_cse_skip_blocks = save_csb;
   flag_cse_follow_jumps = save_cfj;
+  return 0;
 }
 
 struct tree_opt_pass pass_gcse =