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) {