- /* The FALLTHRU edge is also CAN_FALLTHRU edge. */
- for (e = bb->succ; e; e = e->succ_next)
- if (e->flags & EDGE_FALLTHRU)
- e->flags |= EDGE_CAN_FALLTHRU;
-
- /* If the BB ends with an invertable condjump all (2) edges are
- CAN_FALLTHRU edges. */
- if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
- continue;
- if (!any_condjump_p (bb->end))
- continue;
- if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
- continue;
- invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
- bb->succ->flags |= EDGE_CAN_FALLTHRU;
- bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
- }
-}
-
-/* Return true if we need to add fake edge to exit.
- Helper function for the flow_call_edges_add. */
-
-static bool
-need_fake_edge_p (insn)
- rtx insn;
-{
- if (!INSN_P (insn))
- return false;
-
- if ((GET_CODE (insn) == CALL_INSN
- && !SIBLING_CALL_P (insn)
- && !find_reg_note (insn, REG_NORETURN, NULL)
- && !find_reg_note (insn, REG_ALWAYS_RETURN, NULL)
- && !CONST_OR_PURE_CALL_P (insn)))
- return true;
-
- return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
- && MEM_VOLATILE_P (PATTERN (insn)))
- || (GET_CODE (PATTERN (insn)) == PARALLEL
- && asm_noperands (insn) != -1
- && MEM_VOLATILE_P (XVECEXP (PATTERN (insn), 0, 0)))
- || GET_CODE (PATTERN (insn)) == ASM_INPUT);
-}
-
-/* Add fake edges to the function exit for any non constant and non noreturn
- calls, volatile inline assembly in the bitmap of blocks specified by
- BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks
- that were split.
-
- The goal is to expose cases in which entering a basic block does not imply
- that all subsequent instructions must be executed. */
-
-int
-flow_call_edges_add (blocks)
- sbitmap blocks;
-{
- int i;
- int blocks_split = 0;
- int last_bb = last_basic_block;
- bool check_last_block = false;
-
- if (n_basic_blocks == 0)
- return 0;
-
- if (! blocks)
- check_last_block = true;
- else
- check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
-
- /* In the last basic block, before epilogue generation, there will be
- a fallthru edge to EXIT. Special care is required if the last insn
- of the last basic block is a call because make_edge folds duplicate
- edges, which would result in the fallthru edge also being marked
- fake, which would result in the fallthru edge being removed by
- remove_fake_edges, which would result in an invalid CFG.
-
- Moreover, we can't elide the outgoing fake edge, since the block
- profiler needs to take this into account in order to solve the minimal
- spanning tree in the case that the call doesn't return.
-
- Handle this by adding a dummy instruction in a new last basic block. */
- if (check_last_block)
- {
- basic_block bb = EXIT_BLOCK_PTR->prev_bb;
- rtx insn = bb->end;
-
- /* Back up past insns that must be kept in the same block as a call. */
- while (insn != bb->head
- && keep_with_call_p (insn))
- insn = PREV_INSN (insn);
-
- if (need_fake_edge_p (insn))