summaryrefslogtreecommitdiff
path: root/gcc/haifa-sched.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2009-10-17 06:28:43 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2009-10-17 06:28:43 +0000
commitf49b295a191729400b3cbb9bf9e8d1dffedde666 (patch)
treeaba3b71df6de715f9777fb83f5018b7b4c61856c /gcc/haifa-sched.c
parentaf16209f32e1920919942ae2989fa1b857dfe73c (diff)
downloadgcc-f49b295a191729400b3cbb9bf9e8d1dffedde666.tar.gz
re PR debug/41535 (Broken var location info after scheduling)
PR debug/41535 * sched-deps.c (depl_on_debug_p): New. (attach_dep_link): Reject debug deps before nondebug deps. (add_to_deps_list): Insert debug deps after nondebug deps. (sd_lists_empty_p): Stop at first nonempty list. Disregard debug deps. (sd_add_dep): Do not reject debug deps. (add_insn_mem_dependence): Don't count debug deps. (remove_from_deps): Likewise. (sched_analyze_2): Set up mem deps on debug insns. (sched_analyze_insn): Record reg uses for deps on debug insns. * haifa-sched.c (schedule_insn): Reset deferred debug insn. Don't try_ready nondebug insn after debug insn. * ddg.c (create_ddg_dep_from_intra_loop_link, create_ddg_dep_no_link): Don't reject debug deps. From-SVN: r152927
Diffstat (limited to 'gcc/haifa-sched.c')
-rw-r--r--gcc/haifa-sched.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index dc0791f6f2f..bc947fad6f6 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -989,7 +989,7 @@ dep_list_size (rtx insn)
{
if (DEBUG_INSN_P (DEP_CON (dep)))
dbgcount++;
- else
+ else if (!DEBUG_INSN_P (DEP_PRO (dep)))
nodbgcount++;
}
@@ -1688,6 +1688,39 @@ schedule_insn (rtx insn)
should have been removed from the ready list. */
gcc_assert (sd_lists_empty_p (insn, SD_LIST_BACK));
+ /* Reset debug insns invalidated by moving this insn. */
+ if (MAY_HAVE_DEBUG_INSNS && !DEBUG_INSN_P (insn))
+ for (sd_it = sd_iterator_start (insn, SD_LIST_BACK);
+ sd_iterator_cond (&sd_it, &dep);)
+ {
+ rtx dbg = DEP_PRO (dep);
+
+ gcc_assert (DEBUG_INSN_P (dbg));
+
+ if (sched_verbose >= 6)
+ fprintf (sched_dump, ";;\t\tresetting: debug insn %d\n",
+ INSN_UID (dbg));
+
+ /* ??? Rather than resetting the debug insn, we might be able
+ to emit a debug temp before the just-scheduled insn, but
+ this would involve checking that the expression at the
+ point of the debug insn is equivalent to the expression
+ before the just-scheduled insn. They might not be: the
+ expression in the debug insn may depend on other insns not
+ yet scheduled that set MEMs, REGs or even other debug
+ insns. It's not clear that attempting to preserve debug
+ information in these cases is worth the effort, given how
+ uncommon these resets are and the likelihood that the debug
+ temps introduced won't survive the schedule change. */
+ INSN_VAR_LOCATION_LOC (dbg) = gen_rtx_UNKNOWN_VAR_LOC ();
+ df_insn_rescan (dbg);
+
+ /* We delete rather than resolve these deps, otherwise we
+ crash in sched_free_deps(), because forward deps are
+ expected to be released before backward deps. */
+ sd_delete_dep (sd_it);
+ }
+
gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
@@ -1712,6 +1745,12 @@ schedule_insn (rtx insn)
advancing the iterator. */
sd_resolve_dep (sd_it);
+ /* Don't bother trying to mark next as ready if insn is a debug
+ insn. If insn is the last hard dependency, it will have
+ already been discounted. */
+ if (DEBUG_INSN_P (insn) && !DEBUG_INSN_P (next))
+ continue;
+
if (!IS_SPECULATION_BRANCHY_CHECK_P (insn))
{
int effective_cost;