diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2009-10-17 06:28:43 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2009-10-17 06:28:43 +0000 |
commit | f49b295a191729400b3cbb9bf9e8d1dffedde666 (patch) | |
tree | aba3b71df6de715f9777fb83f5018b7b4c61856c /gcc/haifa-sched.c | |
parent | af16209f32e1920919942ae2989fa1b857dfe73c (diff) | |
download | gcc-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.c | 41 |
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; |