This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, PR 10474] Split live-ranges of function arguments to help shrink-wrapping
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Vladimir Makarov <vmakarov at redhat dot com>
- Date: Tue, 22 Oct 2013 00:56:39 +0200
- Subject: Re: [PATCH, PR 10474] Split live-ranges of function arguments to help shrink-wrapping
- Authentication-results: sourceware.org; auth=none
- References: <20131021163237 dot GA11578 at virgil dot suse>
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