- case NOTE:
- {
- int kind = NOTE_LINE_NUMBER (insn);
-
- /* Look for basic block notes with which to keep the
- basic_block_info pointers stable. Unthread the note now;
- we'll put it back at the right place in create_basic_block.
- Or not at all if we've already found a note in this block. */
- if (kind == NOTE_INSN_BASIC_BLOCK)
- {
- if (bb_note == NULL_RTX)
- bb_note = insn;
- else
- next = delete_insn (insn);
- }
- break;
- }
-
- case CODE_LABEL:
- /* A basic block starts at a label. If we've closed one off due
- to a barrier or some such, no need to do it again. */
- if (head != NULL_RTX)
- {
- create_basic_block_structure (i++, head, end, bb_note);
- bb_note = NULL_RTX;
- }
-
- head = end = insn;
- break;
-
- case JUMP_INSN:
- /* A basic block ends at a jump. */
- if (head == NULL_RTX)
- head = insn;
- else
- {
- /* ??? Make a special check for table jumps. The way this
- happens is truly and amazingly gross. We are about to
- create a basic block that contains just a code label and
- an addr*vec jump insn. Worse, an addr_diff_vec creates
- its own natural loop.
-
- Prevent this bit of brain damage, pasting things together
- correctly in make_edges.
-
- The correct solution involves emitting the table directly
- on the tablejump instruction as a note, or JUMP_LABEL. */
-
- if (GET_CODE (PATTERN (insn)) == ADDR_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
- {
- head = end = NULL;
- n_basic_blocks--;
- break;
- }
- }
- end = insn;
- goto new_bb_inclusive;
-
- case BARRIER:
- /* A basic block ends at a barrier. It may be that an unconditional
- jump already closed the basic block -- no need to do it again. */
- if (head == NULL_RTX)
- break;
- goto new_bb_exclusive;
-
- case CALL_INSN:
- {
- /* Record whether this call created an edge. */
- rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
- int region = (note ? INTVAL (XEXP (note, 0)) : 0);
-
- if (GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
- {
- /* Scan each of the alternatives for label refs. */
- lvl = find_label_refs (XEXP (PATTERN (insn), 0), lvl);
- lvl = find_label_refs (XEXP (PATTERN (insn), 1), lvl);
- lvl = find_label_refs (XEXP (PATTERN (insn), 2), lvl);
- /* Record its tail recursion label, if any. */
- if (XEXP (PATTERN (insn), 3) != NULL_RTX)
- trll = alloc_EXPR_LIST (0, XEXP (PATTERN (insn), 3), trll);
- }
-
- /* A basic block ends at a call that can either throw or
- do a non-local goto. */
- if ((nonlocal_goto_handler_labels && region >= 0)
- || can_throw_internal (insn))
- {
- new_bb_inclusive:
- if (head == NULL_RTX)
- head = insn;
- end = insn;
-
- new_bb_exclusive:
- create_basic_block_structure (i++, head, end, bb_note);
- head = end = NULL_RTX;
- bb_note = NULL_RTX;
- break;
- }
- }
- /* Fall through. */
-
- case INSN:
- /* Non-call exceptions generate new blocks just like calls. */
- if (flag_non_call_exceptions && can_throw_internal (insn))
- goto new_bb_inclusive;
-
- if (head == NULL_RTX)
- head = insn;
- end = insn;
- break;
-
- default:
- abort ();
- }
-
- if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
- {
- rtx note;
-
- /* Make a list of all labels referred to other than by jumps.
-
- Make a special exception for labels followed by an ADDR*VEC,
- as this would be a part of the tablejump setup code.
-
- Make a special exception to registers loaded with label
- values just before jump insns that use them. */
-
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- if (REG_NOTE_KIND (note) == REG_LABEL)
- {
- rtx lab = XEXP (note, 0), next;
-
- if ((next = next_nonnote_insn (lab)) != NULL
- && GET_CODE (next) == JUMP_INSN
- && (GET_CODE (PATTERN (next)) == ADDR_VEC
- || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
- ;
- else if (GET_CODE (lab) == NOTE)
- ;
- else if (GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
- && find_reg_note (NEXT_INSN (insn), REG_LABEL, lab))
- ;
- else
- lvl = alloc_EXPR_LIST (0, XEXP (note, 0), lvl);
- }