summaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 5f83892c79f..3f3b863794f 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4358,6 +4358,8 @@ cse_insn (rtx insn)
apply_change_group ();
fold_rtx (x, insn);
}
+ else if (DEBUG_INSN_P (insn))
+ canon_reg (PATTERN (insn), insn);
/* Store the equivalent value in SRC_EQV, if different, or if the DEST
is a STRICT_LOW_PART. The latter condition is necessary because SRC_EQV
@@ -5788,7 +5790,7 @@ cse_insn (rtx insn)
{
prev = PREV_INSN (prev);
}
- while (prev != bb_head && NOTE_P (prev));
+ while (prev != bb_head && (NOTE_P (prev) || DEBUG_INSN_P (prev)));
/* Do not swap the registers around if the previous instruction
attaches a REG_EQUIV note to REG1.
@@ -6244,7 +6246,7 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
FIXME: This is a real kludge and needs to be done some other
way. */
- if (INSN_P (insn)
+ if (NONDEBUG_INSN_P (insn)
&& num_insns++ > PARAM_VALUE (PARAM_MAX_CSE_INSNS))
{
flush_hash_table ();
@@ -6536,6 +6538,9 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
incr);
return;
+ case DEBUG_INSN:
+ return;
+
case CALL_INSN:
case INSN:
case JUMP_INSN:
@@ -6608,6 +6613,19 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
}
}
+/* Return true if a register is dead. Can be used in for_each_rtx. */
+
+static int
+is_dead_reg (rtx *loc, void *data)
+{
+ rtx x = *loc;
+ int *counts = (int *)data;
+
+ return (REG_P (x)
+ && REGNO (x) >= FIRST_PSEUDO_REGISTER
+ && counts[REGNO (x)] == 0);
+}
+
/* Return true if set is live. */
static bool
set_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0. */
@@ -6628,9 +6646,7 @@ set_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0. */
|| !reg_referenced_p (cc0_rtx, PATTERN (tem))))
return false;
#endif
- else if (!REG_P (SET_DEST (set))
- || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
- || counts[REGNO (SET_DEST (set))] != 0
+ else if (!is_dead_reg (&SET_DEST (set), counts)
|| side_effects_p (SET_SRC (set)))
return true;
return false;
@@ -6662,6 +6678,29 @@ insn_live_p (rtx insn, int *counts)
}
return false;
}
+ else if (DEBUG_INSN_P (insn))
+ {
+ rtx next;
+
+ for (next = NEXT_INSN (insn); next; next = NEXT_INSN (next))
+ if (NOTE_P (next))
+ continue;
+ else if (!DEBUG_INSN_P (next))
+ return true;
+ else if (INSN_VAR_LOCATION_DECL (insn) == INSN_VAR_LOCATION_DECL (next))
+ return false;
+
+ /* If this debug insn references a dead register, drop the
+ location expression for now. ??? We could try to find the
+ def and see if propagation is possible. */
+ if (for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), is_dead_reg, counts))
+ {
+ INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+ df_insn_rescan (insn);
+ }
+
+ return true;
+ }
else
return true;
}