aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/cse.c75
2 files changed, 57 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3349ca4..f837bb4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2006-12-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cse.c (this_insn_cc0, this_insn_cc0_mode): New global
+ variables, moved out from cse_insn.
+ (prev_insn): Remove this global variable).
+ (new_basic_block): Don't set it.
+ (cse_insn): Idem. Also, move code to delete unused CC0-setter
+ insns and code to set prev_insn_cc0 and prev_insn_cc0_mode
+ from here...
+ (cse_extended_basic_block): ...to here. Do not clear
+ prev_insn_cc0 until after recording equivalences from jumps.
+
2006-12-16 Jan Hubicka <jh@suse.cz>
* cgraphunit.c (ipa_passes): Clear current_function_decl.
@@ -376,9 +388,10 @@
are the left hand side, set the element's is_vector_lhs to true.
(instantiate_element): For vector types which were on the left
hand size, set DECL_GIMPLE_REG_P to false.
- * tree-nested.c (create_tmp_var_for): Use the renamed DECL_GIMPLE_REG_P. * tree-inline.c (declare_return_variable): Use the renamed
- DECL_GIMPLE_REG_P
- and check for VECTOR_TYPE.
+ * tree-nested.c (create_tmp_var_for): Use the renamed
+ DECL_GIMPLE_REG_P.
+ * tree-inline.c (declare_return_variable): Use the renamed
+ DECL_GIMPLE_REG_P and check for VECTOR_TYPE.
(copy_decl_to_var): Use the renamed DECL_GIMPLE_REG_P.
(copy_result_decl_to_var): Likewise.
* tree-vect-transform.c (vect_get_new_vect_var): For vector types,
diff --git a/gcc/cse.c b/gcc/cse.c
index 015e1de..fc6ffff 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -269,17 +269,13 @@ struct change_cc_mode_args
table since its use is guaranteed to be the insn immediately following
its definition and any other insn is presumed to invalidate it.
- Instead, we store below the value last assigned to CC0. If it should
- happen to be a constant, it is stored in preference to the actual
- assigned value. In case it is a constant, we store the mode in which
- the constant should be interpreted. */
+ Instead, we store below the current and last value assigned to CC0.
+ If it should happen to be a constant, it is stored in preference
+ to the actual assigned value. In case it is a constant, we store
+ the mode in which the constant should be interpreted. */
-static rtx prev_insn_cc0;
-static enum machine_mode prev_insn_cc0_mode;
-
-/* Previous actual insn. 0 if at first insn of basic block. */
-
-static rtx prev_insn;
+static rtx this_insn_cc0, prev_insn_cc0;
+static enum machine_mode this_insn_cc0_mode, prev_insn_cc0_mode;
#endif
/* Insn being scanned. */
@@ -900,7 +896,6 @@ new_basic_block (void)
}
#ifdef HAVE_cc0
- prev_insn = 0;
prev_insn_cc0 = 0;
#endif
}
@@ -4022,8 +4017,8 @@ cse_insn (rtx insn, rtx libcall_insn)
#ifdef HAVE_cc0
/* Records what this insn does to set CC0. */
- rtx this_insn_cc0 = 0;
- enum machine_mode this_insn_cc0_mode = VOIDmode;
+ this_insn_cc0 = 0;
+ this_insn_cc0_mode = VOIDmode;
#endif
rtx src_eqv = 0;
@@ -5644,20 +5639,6 @@ cse_insn (rtx insn, rtx libcall_insn)
}
done:;
-#ifdef HAVE_cc0
- /* If the previous insn set CC0 and this insn no longer references CC0,
- delete the previous insn. Here we use the fact that nothing expects CC0
- to be valid over an insn, which is true until the final pass. */
- if (prev_insn && NONJUMP_INSN_P (prev_insn)
- && (tem = single_set (prev_insn)) != 0
- && SET_DEST (tem) == cc0_rtx
- && ! reg_mentioned_p (cc0_rtx, x))
- delete_insn_and_edges (prev_insn);
-
- prev_insn_cc0 = this_insn_cc0;
- prev_insn_cc0_mode = this_insn_cc0_mode;
- prev_insn = insn;
-#endif
}
/* Remove from the hash table all expressions that reference memory. */
@@ -6096,19 +6077,39 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
&& for_each_rtx (&PATTERN (insn), check_for_label_ref,
(void *) insn))
recorded_label_ref = 1;
+
+#ifdef HAVE_cc0
+ /* If the previous insn set CC0 and this insn no longer
+ references CC0, delete the previous insn. Here we use
+ fact that nothing expects CC0 to be valid over an insn,
+ which is true until the final pass. */
+ {
+ rtx prev_insn, tem;
+
+ prev_insn = PREV_INSN (insn);
+ if (prev_insn && NONJUMP_INSN_P (prev_insn)
+ && (tem = single_set (prev_insn)) != 0
+ && SET_DEST (tem) == cc0_rtx
+ && ! reg_mentioned_p (cc0_rtx, PATTERN (insn)))
+ delete_insn (prev_insn);
+ }
+
+ /* If this insn is not the last insn in the basic block,
+ it will be PREV_INSN(insn) in the next iteration. If
+ we recorded any CC0-related information for this insn,
+ remember it. */
+ if (insn != BB_END (bb))
+ {
+ prev_insn_cc0 = this_insn_cc0;
+ prev_insn_cc0_mode = this_insn_cc0_mode;
+ }
+#endif
}
}
/* Make sure that libcalls don't span multiple basic blocks. */
gcc_assert (libcall_insn == NULL_RTX);
-#ifdef HAVE_cc0
- /* Clear the CC0-tracking related insns, they can't provide
- useful information across basic block boundaries. */
- prev_insn_cc0 = 0;
- prev_insn = 0;
-#endif
-
/* 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
@@ -6133,6 +6134,12 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
bool taken = (next_bb == BRANCH_EDGE (bb)->dest);
record_jump_equiv (insn, taken);
}
+
+#ifdef HAVE_cc0
+ /* Clear the CC0-tracking related insns, they can't provide
+ useful information across basic block boundaries. */
+ prev_insn_cc0 = 0;
+#endif
}
gcc_assert (next_qty <= max_qty);