diff options
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/haifa-sched.c | 24 | ||||
-rw-r--r-- | gcc/sched-deps.c | 114 | ||||
-rw-r--r-- | gcc/sched-ebb.c | 11 | ||||
-rw-r--r-- | gcc/sched-rgn.c | 60 |
5 files changed, 198 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2cbeff1fcf7..262eb0be3f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2003-01-16 Vladimir Makarov <vmakarov@redhat.com> + + * haifa-sched.c (move_insn): Restore moving all schedule group. + (set_priorities): Restore taking SCHED_GROUP_P into account. + + * sched-deps.c (add_dependence): Restore processing the last group + insn. + (remove_dependence, group_leader): Restore the functions. + (set_sched_group_p): Restore adding dependencies from previous insn + in the group. + (compute_forward_dependences): Restore usage of group_leader. + + * sched-ebb.c (init_ready_list): Restore taking SCHED_GROUP_P into + account. + + * sched-rgn.c (init_ready_list): Restore taking SCHED_GROUP_P into + account. + (can_schedule_ready_p): Ditto. + (add_branch_dependences): Restore skipping over the group insns. + 2003-01-16 Stephane Carrez <stcarrez@nerim.fr> * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix handling diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 046abc34423..c6b2aab4935 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -1769,6 +1769,25 @@ move_insn (insn, last) { rtx retval = NULL; + /* If INSN has SCHED_GROUP_P set, then issue it and any other + insns with SCHED_GROUP_P set first. */ + while (SCHED_GROUP_P (insn)) + { + rtx prev = PREV_INSN (insn); + + /* Move a SCHED_GROUP_P insn. */ + move_insn1 (insn, last); + /* If this is the first call to reemit_notes, then record + its return value. */ + if (retval == NULL_RTX) + retval = reemit_notes (insn, insn); + else + reemit_notes (insn, insn); + /* Consume SCHED_GROUP_P flag. */ + SCHED_GROUP_P (insn) = 0; + insn = prev; + } + /* Now move the first non SCHED_GROUP_P insn. */ move_insn1 (insn, last); @@ -1779,8 +1798,6 @@ move_insn (insn, last) else reemit_notes (insn, insn); - SCHED_GROUP_P (insn) = 0; - return retval; } @@ -2376,7 +2393,8 @@ set_priorities (head, tail) if (GET_CODE (insn) == NOTE) continue; - n_insn++; + if (! SCHED_GROUP_P (insn)) + n_insn++; (void) priority (insn); } diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index a735125495c..d6fa2c821a6 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -83,12 +83,14 @@ static sbitmap *forward_dependency_cache; static int deps_may_trap_p PARAMS ((rtx)); static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note)); static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note)); +static void remove_dependence PARAMS ((rtx, rtx)); static void set_sched_group_p PARAMS ((rtx)); static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int)); static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx)); static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx)); static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx)); +static rtx group_leader PARAMS ((rtx)); static rtx get_condition PARAMS ((rtx)); static int conditions_mutex_p PARAMS ((rtx, rtx)); @@ -235,13 +237,16 @@ add_dependence (insn, elem, dep_type) rtx nnext; while ((nnext = next_nonnote_insn (next)) != NULL && INSN_P (nnext) - && next != insn && SCHED_GROUP_P (nnext)) next = nnext; - if (insn != next) - add_dependence (insn, next, REG_DEP_ANTI); + /* Again, don't depend an insn on itself. */ + if (insn == next) + return; + /* Make the dependence to NEXT, the last insn of the group, + instead of the original ELEM. */ + elem = next; } @@ -380,6 +385,76 @@ add_dependence_list_and_free (insn, listp, dep_type) } } +/* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS + of INSN. Abort if not found. */ + +static void +remove_dependence (insn, elem) + rtx insn; + rtx elem; +{ + rtx prev, link, next; + int found = 0; + + for (prev = 0, link = LOG_LINKS (insn); link; link = next) + { + next = XEXP (link, 1); + if (XEXP (link, 0) == elem) + { + if (prev) + XEXP (prev, 1) = next; + else + LOG_LINKS (insn) = next; + +#ifdef INSN_SCHEDULING + /* If we are removing a dependency from the LOG_LINKS list, + make sure to remove it from the cache too. */ + if (true_dependency_cache != NULL) + { + if (REG_NOTE_KIND (link) == 0) + RESET_BIT (true_dependency_cache[INSN_LUID (insn)], + INSN_LUID (elem)); + else if (REG_NOTE_KIND (link) == REG_DEP_ANTI) + RESET_BIT (anti_dependency_cache[INSN_LUID (insn)], + INSN_LUID (elem)); + else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT) + RESET_BIT (output_dependency_cache[INSN_LUID (insn)], + INSN_LUID (elem)); + } +#endif + + free_INSN_LIST_node (link); + + found = 1; + } + else + prev = link; + } + + if (!found) + abort (); + return; +} + +/* Return an insn which represents a SCHED_GROUP, which is + the last insn in the group. */ + +static rtx +group_leader (insn) + rtx insn; +{ + rtx prev; + + do + { + prev = insn; + insn = next_nonnote_insn (insn); + } + while (insn && INSN_P (insn) && SCHED_GROUP_P (insn)); + + return prev; +} + /* Set SCHED_GROUP_P and care for the rest of the bookkeeping that goes along with that. */ @@ -391,21 +466,22 @@ set_sched_group_p (insn) SCHED_GROUP_P (insn) = 1; - for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) - { - prev = insn; - do - { - prev = prev_nonnote_insn (prev); - if (XEXP (link, 0) == prev) - break; - } - while (SCHED_GROUP_P (prev)); - if (XEXP (link, 0) != prev) - add_dependence (prev, XEXP (link, 0), REG_DEP_ANTI); - } + /* There may be a note before this insn now, but all notes will + be removed before we actually try to schedule the insns, so + it won't cause a problem later. We must avoid it here + though. */ prev = prev_nonnote_insn (insn); - add_dependence (insn, prev, REG_DEP_ANTI); + + /* Make a copy of all dependencies on the immediately previous + insn, and add to this insn. This is so that all the + dependencies will apply to the group. Remove an explicit + dependence on this insn as SCHED_GROUP_P now represents it. */ + + if (find_insn_list (prev, LOG_LINKS (insn))) + remove_dependence (insn, prev); + + for (link = LOG_LINKS (prev); link; link = XEXP (link, 1)) + add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link)); } /* Process an insn's memory dependencies. There are four kinds of @@ -1370,9 +1446,11 @@ compute_forward_dependences (head, tail) if (! INSN_P (insn)) continue; + insn = group_leader (insn); + for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) { - rtx x = XEXP (link, 0); + rtx x = group_leader (XEXP (link, 0)); rtx new_link; if (x != XEXP (link, 0)) diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c index 29189a68d0c..59f7ac04329 100644 --- a/gcc/sched-ebb.c +++ b/gcc/sched-ebb.c @@ -90,9 +90,16 @@ init_ready_list (ready) Count number of insns in the target block being scheduled. */ for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn)) { - if (INSN_DEP_COUNT (insn) == 0) + rtx next; + + if (! INSN_P (insn)) + continue; + next = NEXT_INSN (insn); + + if (INSN_DEP_COUNT (insn) == 0 + && (! INSN_P (next) || SCHED_GROUP_P (next) == 0)) ready_add (ready, insn); - if (!(SCHED_GROUP_P (insn))) + if (! SCHED_GROUP_P (insn)) target_n_insns++; } } diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index 36a53f73c26..0bbe148a283 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -2023,9 +2023,17 @@ init_ready_list (ready) Count number of insns in the target block being scheduled. */ for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn)) { - if (INSN_DEP_COUNT (insn) == 0) + rtx next; + + if (! INSN_P (insn)) + continue; + next = NEXT_INSN (insn); + + if (INSN_DEP_COUNT (insn) == 0 + && (! INSN_P (next) || SCHED_GROUP_P (next) == 0)) ready_add (ready, insn); - target_n_insns++; + if (! SCHED_GROUP_P (insn)) + target_n_insns++; } /* Add to ready list all 'ready' insns in valid source blocks. @@ -2059,8 +2067,19 @@ init_ready_list (ready) insn, insn) <= 3))) && check_live (insn, bb_src) && is_exception_free (insn, bb_src, target_bb)))) - if (INSN_DEP_COUNT (insn) == 0) - ready_add (ready, insn); + { + rtx next; + + /* Note that we haven't squirreled away the notes for + blocks other than the current. So if this is a + speculative insn, NEXT might otherwise be a note. */ + next = next_nonnote_insn (insn); + if (INSN_DEP_COUNT (insn) == 0 + && (! next + || ! INSN_P (next) + || SCHED_GROUP_P (next) == 0)) + ready_add (ready, insn); + } } } } @@ -2078,6 +2097,7 @@ can_schedule_ready_p (insn) /* An interblock motion? */ if (INSN_BB (insn) != target_bb) { + rtx temp; basic_block b1; if (IS_SPECULATIVE_INSN (insn)) @@ -2094,9 +2114,18 @@ can_schedule_ready_p (insn) } nr_inter++; + /* Find the beginning of the scheduling group. */ + /* ??? Ought to update basic block here, but later bits of + schedule_block assumes the original insn block is + still intact. */ + + temp = insn; + while (SCHED_GROUP_P (temp)) + temp = PREV_INSN (temp); + /* Update source block boundaries. */ - b1 = BLOCK_FOR_INSN (insn); - if (insn == b1->head && insn == b1->end) + b1 = BLOCK_FOR_INSN (temp); + if (temp == b1->head && temp == b1->end) { /* We moved all the insns in the basic block. Emit a note after the last insn and update the @@ -2110,9 +2139,9 @@ can_schedule_ready_p (insn) /* We took insns from the end of the basic block, so update the end of block boundary so that it points to the first insn we did not move. */ - b1->end = PREV_INSN (insn); + b1->end = PREV_INSN (temp); } - else if (insn == b1->head) + else if (temp == b1->head) { /* We took insns from the start of the basic block, so update the start of block boundary so that @@ -2332,6 +2361,17 @@ add_branch_dependences (head, tail) CANT_MOVE (insn) = 1; last = insn; + /* Skip over insns that are part of a group. + Make each insn explicitly depend on the previous insn. + This ensures that only the group header will ever enter + the ready queue (and, when scheduled, will automatically + schedule the SCHED_GROUP_P block). */ + while (SCHED_GROUP_P (insn)) + { + rtx temp = prev_nonnote_insn (insn); + add_dependence (insn, temp, REG_DEP_ANTI); + insn = temp; + } } /* Don't overrun the bounds of the basic block. */ @@ -2353,6 +2393,10 @@ add_branch_dependences (head, tail) add_dependence (last, insn, REG_DEP_ANTI); INSN_REF_COUNT (insn) = 1; + + /* Skip over insns that are part of a group. */ + while (SCHED_GROUP_P (insn)) + insn = prev_nonnote_insn (insn); } } |