Seongbae Park (???, ???) wrote:
...
I'm looking at it. It is either a scheduler problem,
or some other problem downstream triggered by the scheduler.
However, I'm having hard time adding fine-grained dbg_cnt to our scheduler
- do you know who might be interested in adding insn level
dbg_cnt in the scheduler ? Current dbg_cnt (sched_insn) causes ICE :(
IMHO, the least intrusive way of using a debug counter in scheduler is
to place into instruction choosing module and make scheduler to chose
next instruction at all times. I have successfully used this technique
in debugging selective scheduler and believe it will suit haifa
scheduler perfectly.
I've attached a patch that moves dbg_cnt to choose_ready () routine, but
at this point have no time to test it for usability (though it compiles
fine on x86_64). If the patch won't work please let me know and I'll
fix it during the weekend.
Regards,
Maxim
Index: haifa-sched.c
===================================================================
--- haifa-sched.c (revision 125737)
+++ haifa-sched.c (working copy)
@@ -539,7 +539,7 @@ static rtx ready_remove (struct ready_li
static void ready_remove_insn (rtx);
static int max_issue (struct ready_list *, int *, int);
-static rtx choose_ready (struct ready_list *);
+static int choose_ready (struct ready_list *, rtx *);
static void fix_inter_tick (rtx, rtx);
static int fix_tick_ready (rtx);
@@ -1980,17 +1980,42 @@ max_issue (struct ready_list *ready, int
/* The following function chooses insn from READY and modifies
*N_READY and READY. The following function is used only for first
- cycle multipass scheduling. */
-
-static rtx
-choose_ready (struct ready_list *ready)
+ cycle multipass scheduling.
+ Return:
+ -1 if cycle should be advanced,
+ 0 if INSN_PTR is set to point to the desirable insn,
+ 1 if choose_ready () should be restarted without advancing the cycle. */
+static int
+choose_ready (struct ready_list *ready, rtx *insn_ptr)
{
- int lookahead = 0;
+ int lookahead;
+
+ if (dbg_cnt (sched_insn) == false)
+ {
+ rtx insn;
+
+ insn = NEXT_INSN (last_scheduled_insn);
+
+ if (QUEUE_INDEX (insn) == QUEUE_READY)
+ /* INSN is in the ready_list. */
+ {
+ *insn_ptr = insn;
+ return 0;
+ }
+
+ /* INSN is in the queue. Advance cycle to move it to the ready list. */
+ return -1;
+ }
+
+ lookahead = 0;
if (targetm.sched.first_cycle_multipass_dfa_lookahead)
lookahead = targetm.sched.first_cycle_multipass_dfa_lookahead ();
if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)))
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
else
{
/* Try to choose the better insn. */
@@ -2007,7 +2032,10 @@ choose_ready (struct ready_list *ready)
}
insn = ready_element (ready, 0);
if (INSN_CODE (insn) < 0)
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
if (spec_info
&& spec_info->flags & (PREFER_NON_DATA_SPEC
@@ -2049,7 +2077,7 @@ choose_ready (struct ready_list *ready)
list. */
{
change_queue_index (insn, 1);
- return 0;
+ return 1;
}
max_points = ISSUE_POINTS (insn);
@@ -2071,9 +2099,15 @@ choose_ready (struct ready_list *ready)
}
if (max_issue (ready, &index, max_points) == 0)
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
else
- return ready_remove (ready, index);
+ {
+ *insn_ptr = ready_remove (ready, index);
+ return 0;
+ }
}
}
@@ -2271,29 +2305,22 @@ schedule_block (basic_block *target_bb,
|| !(*current_sched_info->schedule_more_p) ())
break;
- if (dbg_cnt (sched_insn) == false)
- {
- insn = NEXT_INSN (last_scheduled_insn);
- while ((*current_sched_info->schedule_more_p) ())
- {
- (*current_sched_info->begin_schedule_ready) (insn,
- last_scheduled_insn);
- if (QUEUE_INDEX (insn) >= 0)
- queue_remove (insn);
- last_scheduled_insn = insn;
- insn = NEXT_INSN (insn);
- }
- while (ready.n_ready)
- ready_remove_first (&ready);
- goto bail_out;
- }
-
/* Select and remove the insn from the ready list. */
if (sort_p)
{
- insn = choose_ready (&ready);
- if (!insn)
+ int res;
+
+ insn = NULL_RTX;
+ res = choose_ready (&ready, &insn);
+
+ if (res < 0)
+ /* Finish cycle. */
+ break;
+ if (res > 0)
+ /* Restart choose_ready (). */
continue;
+
+ gcc_assert (insn != NULL_RTX);
}
else
insn = ready_remove_first (&ready);
@@ -2445,7 +2472,6 @@ schedule_block (basic_block *target_bb,
}
}
-bail_out:
/* Debug info. */
if (sched_verbose)
{