On Mon, Oct 21, 2013 at 6:32 PM, Martin Jambor wrote: > --- a/gcc/ira.c > +++ b/gcc/ira.c > @@ -4314,6 +4314,197 @@ find_moveable_pseudos (void) > free_dominance_info (CDI_DOMINATORS); > } > > + > +/* If insn is interesting for parameter range-splitting shring-wrapping > + preparation, i.e. it is a single set from a hard register to a pseudo, > which > + is live at CALL_DOM, return the destination. Otherwise return NULL. */ > + > +static rtx > +interesting_dest_for_shprep (rtx insn, basic_block call_dom) > +{ > + rtx set = single_set (insn); > + if (!set) > + return NULL; > + rtx src = SET_SRC (set); > + rtx dest = SET_DEST (set); > + if (!REG_P (src) || !HARD_REGISTER_P (src) > + || !REG_P (dest) || HARD_REGISTER_P (dest) > + || (call_dom && !bitmap_bit_p (df_get_live_in (call_dom), REGNO > (dest))))
See below... > + return NULL; > + return dest; > +} > + > +/* Split live ranges of pseudos that are loaded from hard registers in the > + first BB in a BB that dominates all non-sibling call if such a BB can be > + found and is not in a loop. */ > + > +static void > +split_live_ranges_for_shrink_wrap (void) > +{ > + basic_block bb, call_dom = NULL; > + basic_block first = single_succ (ENTRY_BLOCK_PTR); > + rtx insn, last_interesting_insn = NULL; > + bitmap_head need_new, reachable; > + vec<basic_block> queue; > + > + if (!flag_shrink_wrap) > + return; > + > + bitmap_initialize (&need_new, 0); > + bitmap_initialize (&reachable, 0); > + queue.create (n_basic_blocks); > + > + FOR_EACH_BB (bb) > + FOR_BB_INSNS (bb, insn) > + if (CALL_P (insn) && !SIBLING_CALL_P (insn)) > + { > + if (bb == first) > + { > + bitmap_clear (&need_new); > + bitmap_clear (&reachable); > + queue.release (); > + return; > + } > + > + bitmap_set_bit (&need_new, bb->index); > + bitmap_set_bit (&reachable, bb->index); > + queue.quick_push (bb); > + break; > + } > + > + if (queue.is_empty ()) > + { > + bitmap_clear (&need_new); > + bitmap_clear (&reachable); > + queue.release (); > + return; > + } > + > + while (!queue.is_empty ()) > + { > + edge e; > + edge_iterator ei; > + > + bb = queue.pop (); > + FOR_EACH_EDGE (e, ei, bb->succs) > + if (e->dest != EXIT_BLOCK_PTR > + && bitmap_set_bit (&reachable, e->dest->index)) > + queue.quick_push (e->dest); > + } > + queue.release (); > + > + FOR_BB_INSNS (first, insn) > + { > + rtx dest = interesting_dest_for_shprep (insn, NULL); > + if (!dest) > + continue; > + > + if (DF_REG_DEF_COUNT (REGNO (dest)) > 1) See below... > + { > + bitmap_clear (&need_new); > + bitmap_clear (&reachable); > + return; > + } > + > + for (df_ref use = DF_REG_USE_CHAIN (REGNO(dest)); > + use; > + use = DF_REF_NEXT_REG (use)) You're using DF in these places. But IRA and LRA don't work with DF. After update_equiv_regs DF caches and liveness may be incorrect. You'd have to add a df_analyze call but I'm not sure how that will interact with IRA/LRA's own dataflow frameworks (e.g. w.r.t. REG_DEAD/REG_UNUSED notes). > + rtx uin = DF_REF_INSN (use); > + int ubbi = BLOCK_FOR_INSN (uin)->index; int ubbi = DF_REF_BB (use)? Ciao! Steven