-/* It is possible that ebb scheduling elliminated some blocks.
- Place blocks from FIRST to LAST before BEFORE. */
-
-static void
-add_missing_bbs (before, first, last)
- rtx before;
- basic_block first, last;
-{
- for (; last != first->prev_bb; last = last->prev_bb)
- {
- before = emit_note_before (NOTE_INSN_BASIC_BLOCK, before);
- NOTE_BASIC_BLOCK (before) = last;
- last->head = before;
- last->end = before;
- update_bb_for_insn (last);
- }
-}
-
-/* Fixup the CFG after EBB scheduling. Re-recognize the basic
- block boundaries in between HEAD and TAIL and update basic block
- structures between BB and LAST. */
-
-static basic_block
-fix_basic_block_boundaries (bb, last, head, tail)
- basic_block bb, last;
- rtx head, tail;
-{
- rtx insn = head;
- rtx last_inside = bb->head;
- rtx aftertail = NEXT_INSN (tail);
-
- head = bb->head;
-
- for (; insn != aftertail; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == CODE_LABEL)
- abort ();
- /* Create new basic blocks just before first insn. */
- if (inside_basic_block_p (insn))
- {
- if (!last_inside)
- {
- rtx note;
-
- /* Re-emit the basic block note for newly found BB header. */
- if (GET_CODE (insn) == CODE_LABEL)
- {
- note = emit_note_after (NOTE_INSN_BASIC_BLOCK, insn);
- head = insn;
- last_inside = note;
- }
- else
- {
- note = emit_note_before (NOTE_INSN_BASIC_BLOCK, insn);
- head = note;
- last_inside = insn;
- }
- }
- else
- last_inside = insn;
- }
- /* Control flow instruction terminate basic block. It is possible
- that we've elliminated some basic blocks (made them empty).
- Find the proper basic block using BLOCK_FOR_INSN and arrange things in
- a sensible way by inserting empty basic blocks as needed. */
- if (control_flow_insn_p (insn) || (insn == tail && last_inside))
- {
- basic_block curr_bb = BLOCK_FOR_INSN (insn);
- rtx note;
-
- if (!control_flow_insn_p (insn))
- curr_bb = last;
- if (bb == last->next_bb)
- {
- edge f;
- rtx h;
-
- /* An obscure special case, where we do have partially dead
- instruction scheduled after last control flow instruction.
- In this case we can create new basic block. It is
- always exactly one basic block last in the sequence. Handle
- it by splitting the edge and repositioning the block.
- This is somewhat hackish, but at least avoid cut&paste
-
- Safter sollution can be to bring the code into sequence,
- do the split and re-emit it back in case this will ever
- trigger problem. */
- f = bb->prev_bb->succ;
- while (f && !(f->flags & EDGE_FALLTHRU))
- f = f->succ_next;
-
- if (f)
- {
- last = curr_bb = split_edge (f);
- h = curr_bb->head;
- curr_bb->head = head;
- curr_bb->end = insn;
- /* Edge splitting created missplaced BASIC_BLOCK note, kill
- it. */
- delete_insn (h);
- }
- /* It may happen that code got moved past unconditional jump in
- case the code is completely dead. Kill it. */
- else
- {
- rtx next = next_nonnote_insn (insn);
- delete_insn_chain (head, insn);
- /* We keep some notes in the way that may split barrier from the
- jump. */
- if (GET_CODE (next) == BARRIER)
- {
- emit_barrier_after (prev_nonnote_insn (head));
- delete_insn (next);
- }
- insn = NULL;
- }
- }
- else
- {
- curr_bb->head = head;
- curr_bb->end = insn;
- add_missing_bbs (curr_bb->head, bb, curr_bb->prev_bb);
- }
- note = GET_CODE (head) == CODE_LABEL ? NEXT_INSN (head) : head;
- NOTE_BASIC_BLOCK (note) = curr_bb;
- update_bb_for_insn (curr_bb);
- bb = curr_bb->next_bb;
- last_inside = NULL;
- if (!insn)
- break;
- }
- }
- add_missing_bbs (last->next_bb->head, bb, last);
- return bb->prev_bb;
-}
-