+ /* That may have inserted instructions into the last block. */
+ if (last_bb && !last_bb_active)
+ last_bb_active = bb_active_p (last_bb);
+
+ bitmap_initialize (&bb_antic_flags, &bitmap_default_obstack);
+ bitmap_initialize (&bb_on_list, &bitmap_default_obstack);
+
+ /* Find the set of basic blocks that require a stack frame. */
+
+ vec = VEC_alloc (basic_block, heap, n_basic_blocks);
+
+ CLEAR_HARD_REG_SET (set_up_by_prologue);
+ add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
+ add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
+ if (frame_pointer_needed)
+ add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+ HARD_FRAME_POINTER_REGNUM);
+ if (pic_offset_table_rtx)
+ add_to_hard_reg_set (&set_up_by_prologue, Pmode,
+ PIC_OFFSET_TABLE_REGNUM);
+
+ FOR_EACH_BB (bb)
+ {
+ rtx insn;
+ /* As a special case, check for jumps to the last bb that
+ cannot successfully be converted to simple_returns later
+ on, and mark them as requiring a frame. These are
+ conditional jumps that jump to their fallthru block, so
+ it's not a case that is expected to occur often. */
+ if (JUMP_P (BB_END (bb)) && any_condjump_p (BB_END (bb))
+ && single_succ_p (bb)
+ && !last_bb_active
+ && single_succ (bb) == last_bb)
+ {
+ bitmap_set_bit (&bb_flags, bb->index);
+ VEC_quick_push (basic_block, vec, bb);
+ }
+ else
+ FOR_BB_INSNS (bb, insn)
+ if (requires_stack_frame_p (insn, prologue_used,
+ set_up_by_prologue))
+ {
+ bitmap_set_bit (&bb_flags, bb->index);
+ VEC_quick_push (basic_block, vec, bb);
+ break;
+ }
+ }
+
+ /* For every basic block that needs a prologue, mark all blocks
+ reachable from it, so as to ensure they are also seen as
+ requiring a prologue. */
+ while (!VEC_empty (basic_block, vec))
+ {
+ basic_block tmp_bb = VEC_pop (basic_block, vec);
+ edge e;
+ edge_iterator ei;
+ FOR_EACH_EDGE (e, ei, tmp_bb->succs)
+ if (e->dest != EXIT_BLOCK_PTR
+ && bitmap_set_bit (&bb_flags, e->dest->index))
+ VEC_quick_push (basic_block, vec, e->dest);
+ }
+ /* If the last basic block contains only a label, we'll be able
+ to convert jumps to it to (potentially conditional) return
+ insns later. This means we don't necessarily need a prologue
+ for paths reaching it. */
+ if (last_bb && optimize)
+ {
+ if (!last_bb_active)
+ bitmap_clear_bit (&bb_flags, last_bb->index);
+ else if (!bitmap_bit_p (&bb_flags, last_bb->index))
+ goto fail_shrinkwrap;
+ }
+
+ /* Now walk backwards from every block that is marked as needing
+ a prologue to compute the bb_antic_flags bitmap. */
+ bitmap_copy (&bb_antic_flags, &bb_flags);
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ edge_iterator ei;
+ if (!bitmap_bit_p (&bb_flags, bb->index))
+ continue;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!bitmap_bit_p (&bb_antic_flags, e->src->index)
+ && bitmap_set_bit (&bb_on_list, e->src->index))
+ VEC_quick_push (basic_block, vec, e->src);
+ }
+ while (!VEC_empty (basic_block, vec))
+ {
+ basic_block tmp_bb = VEC_pop (basic_block, vec);
+ edge e;
+ edge_iterator ei;
+ bool all_set = true;
+
+ bitmap_clear_bit (&bb_on_list, tmp_bb->index);
+ FOR_EACH_EDGE (e, ei, tmp_bb->succs)
+ if (!bitmap_bit_p (&bb_antic_flags, e->dest->index))
+ {
+ all_set = false;
+ break;
+ }
+
+ if (all_set)
+ {
+ bitmap_set_bit (&bb_antic_flags, tmp_bb->index);
+ FOR_EACH_EDGE (e, ei, tmp_bb->preds)
+ if (!bitmap_bit_p (&bb_antic_flags, e->src->index)
+ && bitmap_set_bit (&bb_on_list, e->src->index))
+ VEC_quick_push (basic_block, vec, e->src);
+ }
+ }
+ /* Find exactly one edge that leads to a block in ANTIC from
+ a block that isn't. */
+ if (!bitmap_bit_p (&bb_antic_flags, entry_edge->dest->index))
+ FOR_EACH_BB (bb)
+ {
+ if (!bitmap_bit_p (&bb_antic_flags, bb->index))
+ continue;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!bitmap_bit_p (&bb_antic_flags, e->src->index))
+ {
+ if (entry_edge != orig_entry_edge)
+ {
+ entry_edge = orig_entry_edge;
+ if (dump_file)
+ fprintf (dump_file, "More than one candidate edge.\n");
+ goto fail_shrinkwrap;
+ }
+ if (dump_file)
+ fprintf (dump_file, "Found candidate edge for "
+ "shrink-wrapping, %d->%d.\n", e->src->index,
+ e->dest->index);
+ entry_edge = e;
+ }
+ }
+
+ /* Test whether the prologue is known to clobber any register
+ (other than FP or SP) which are live on the edge. */
+ CLEAR_HARD_REG_BIT (prologue_clobbered, STACK_POINTER_REGNUM);
+ if (frame_pointer_needed)
+ CLEAR_HARD_REG_BIT (prologue_clobbered, HARD_FRAME_POINTER_REGNUM);
+ CLEAR_HARD_REG_SET (live_on_edge);
+ reg_set_to_hard_reg_set (&live_on_edge,
+ df_get_live_in (entry_edge->dest));
+ if (hard_reg_set_intersect_p (live_on_edge, prologue_clobbered))
+ {
+ entry_edge = orig_entry_edge;
+ if (dump_file)
+ fprintf (dump_file, "Shrink-wrapping aborted due to clobber.\n");
+ }
+ else if (entry_edge != orig_entry_edge)
+ {
+ crtl->shrink_wrapped = true;
+ if (dump_file)
+ fprintf (dump_file, "Performing shrink-wrapping.\n");
+ }
+
+ fail_shrinkwrap:
+ bitmap_clear (&bb_antic_flags);
+ bitmap_clear (&bb_on_list);
+ VEC_free (basic_block, heap, vec);