This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, PR 10474] Split live-ranges of function arguments to help shrink-wrapping


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]