-#include "obstack.h"
-static int count_basic_blocks PARAMS ((rtx));
-static void find_basic_blocks_1 PARAMS ((rtx));
-static rtx find_label_refs PARAMS ((rtx, rtx));
-static void make_edges PARAMS ((rtx, int, int, int));
-static void make_label_edge PARAMS ((sbitmap *, basic_block,
- rtx, int));
-static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
+static int count_basic_blocks (rtx);
+static void find_basic_blocks_1 (rtx);
+static void make_edges (basic_block, basic_block, int);
+static void make_label_edge (sbitmap *, basic_block, rtx, int);
+static void find_bb_boundaries (basic_block);
+static void compute_outgoing_frequencies (basic_block);
+\f
+/* Return true if insn is something that should be contained inside basic
+ block. */
+
+bool
+inside_basic_block_p (rtx insn)
+{
+ switch (GET_CODE (insn))
+ {
+ case CODE_LABEL:
+ /* Avoid creating of basic block for jumptables. */
+ return (NEXT_INSN (insn) == 0
+ || !JUMP_P (NEXT_INSN (insn))
+ || (GET_CODE (PATTERN (NEXT_INSN (insn))) != ADDR_VEC
+ && GET_CODE (PATTERN (NEXT_INSN (insn))) != ADDR_DIFF_VEC));
+
+ case JUMP_INSN:
+ return (GET_CODE (PATTERN (insn)) != ADDR_VEC
+ && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
+
+ case CALL_INSN:
+ case INSN:
+ return true;
+
+ case BARRIER:
+ case NOTE:
+ return false;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Return true if INSN may cause control flow transfer, so it should be last in
+ the basic block. */
+
+bool
+control_flow_insn_p (rtx insn)
+{
+ rtx note;
+
+ switch (GET_CODE (insn))
+ {
+ case NOTE:
+ case CODE_LABEL:
+ return false;
+
+ case JUMP_INSN:
+ /* Jump insn always causes control transfer except for tablejumps. */
+ return (GET_CODE (PATTERN (insn)) != ADDR_VEC
+ && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);
+
+ case CALL_INSN:
+ /* Noreturn and sibling call instructions terminate the basic blocks
+ (but only if they happen unconditionally). */
+ if ((SIBLING_CALL_P (insn)
+ || find_reg_note (insn, REG_NORETURN, 0))
+ && GET_CODE (PATTERN (insn)) != COND_EXEC)
+ return true;
+ /* Call insn may return to the nonlocal goto handler. */
+ return ((nonlocal_goto_handler_labels
+ && (0 == (note = find_reg_note (insn, REG_EH_REGION,
+ NULL_RTX))
+ || INTVAL (XEXP (note, 0)) >= 0))
+ /* Or may trap. */
+ || can_throw_internal (insn));
+
+ case INSN:
+ return (flag_non_call_exceptions && can_throw_internal (insn));
+
+ case BARRIER:
+ /* It is nonsense to reach barrier when looking for the
+ end of basic block, but before dead code is eliminated
+ this may happen. */
+ return false;
+
+ default:
+ gcc_unreachable ();
+ }
+}