From: "William J. Schmidt" <wschmidt@linux.vnet.ibm.com>
To: gcc-patches@gcc.gnu.org
Cc: richard.guenther@gmail.com
Subject: [PATCH] Address lowering [2/3] Constrain forward propagator
Date: Thu, 30 Jun 2011 14:59:00 -0000 [thread overview]
Message-ID: <1309445305.26980.56.camel@oc2474580526.ibm.com> (raw)
Here is the second patch related to address lowering. It looks for a
specific pattern where replacement of a reg in a mem rtx is not
profitable, and constrains it from occurring.
Thanks,
Bill
2011-06-30 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
* fwprop.c (fwprop_bb_aux_d): New struct.
(record_mem_plus_reg): New.
(record_mem_plus_regs): New.
(single_def_use_enter_block): Allocate storage; add call to
record_mem_plus_regs; add dump logic.
(build_single_def_use_links): Allocate storage.
(locally_poor_mem_replacement): New.
(forward_propagate_and_simplify): Add call to
locally_poor_mem_replacement.
(fwprop_done): Free storage.
Index: gcc/fwprop.c
===================================================================
--- gcc/fwprop.c (revision 175664)
+++ gcc/fwprop.c (working copy)
@@ -131,6 +131,15 @@ static VEC(df_ref,heap) *reg_defs_stack;
static bitmap local_md;
static bitmap local_lr;
+/* Auxiliary information for each block for this pass. */
+typedef struct GTY(()) fwprop_bb_aux_d
+{
+ /* Registers appearing in (mem (plus (reg ... patterns in this block. */
+ bitmap mem_plus_regs;
+} fwprop_bb_aux, *fwprop_bb_aux_t;
+
+#define MEM_PLUS_REGS(BB) ((fwprop_bb_aux_t) ((BB)->aux))->mem_plus_regs
+
/* Return the only def in USE's use-def chain, or NULL if there is
more than one def in the chain. */
@@ -212,7 +221,43 @@ process_uses (df_ref *use_rec, int top_flag)
}
+/* Record whether EXPR in block BB is of the form (mem (plus (reg ... */
static void
+record_mem_plus_reg (basic_block bb, rtx expr)
+{
+ rtx addr, reg;
+
+ if (GET_CODE (expr) != MEM)
+ return;
+
+ addr = XEXP (expr, 0);
+ if (GET_CODE (addr) != PLUS)
+ return;
+
+ reg = XEXP (addr, 0);
+ if (!REG_P (reg))
+ return;
+
+ (void)bitmap_set_bit (MEM_PLUS_REGS (bb), REGNO (reg));
+}
+
+
+/* Record whether INSN in block BB contains any patterns of the form
+ (mem (plus (reg ... */
+static void
+record_mem_plus_regs (basic_block bb, rtx insn)
+{
+ rtx insn_set = single_set (insn);
+
+ if (insn_set)
+ {
+ record_mem_plus_reg (bb, SET_DEST (insn_set));
+ record_mem_plus_reg (bb, SET_SRC (insn_set));
+ }
+}
+
+
+static void
single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
basic_block bb)
{
@@ -230,6 +275,8 @@ single_def_use_enter_block (struct dom_walk_data *
process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP);
process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP);
+ MEM_PLUS_REGS (bb) = BITMAP_ALLOC (NULL);
+
/* We don't call df_simulate_initialize_forwards, as it may overestimate
the live registers if there are unused artificial defs. We prefer
liveness to be underestimated. */
@@ -242,8 +289,15 @@ single_def_use_enter_block (struct dom_walk_data *
process_uses (DF_INSN_UID_EQ_USES (uid), 0);
process_defs (DF_INSN_UID_DEFS (uid), 0);
df_simulate_one_insn_forwards (bb, insn, local_lr);
+ record_mem_plus_regs (bb, insn);
}
+ if (dump_file)
+ {
+ fprintf (dump_file, "mem_plus_regs (%d): ", bb->index);
+ dump_bitmap (dump_file, MEM_PLUS_REGS (bb));
+ }
+
process_uses (df_get_artificial_uses (bb_index), 0);
process_defs (df_get_artificial_defs (bb_index), 0);
}
@@ -295,6 +349,8 @@ build_single_def_use_links (void)
local_md = BITMAP_ALLOC (NULL);
local_lr = BITMAP_ALLOC (NULL);
+ alloc_aux_for_blocks (sizeof (fwprop_bb_aux));
+
/* Walk the dominator tree looking for single reaching definitions
dominating the uses. This is similar to how SSA form is built. */
walk_data.dom_direction = CDI_DOMINATORS;
@@ -1205,6 +1261,69 @@ forward_propagate_asm (df_ref use, rtx def_insn, r
return true;
}
+/* We are proposing to replace a USE of REG in USE_SET. Determine
+ whether we have a situation where two storage uses of REG occur
+ in the same block as follows. Each use can be either a memory
+ store or a memory load.
+
+ ... (mem (reg REG))
+
+ ... (mem (plus (reg REG)
+ (...)))
+
+ The problem is that it will look profitable to propagate something
+ like
+
+ (set (reg REG)
+ (plus (reg X)
+ (reg Y)))
+
+ into the first use, but not into the second one. This breaks a
+ CSE opportunity and raises register pressure by extending the
+ lifetimes of X and Y. To avoid this, don't propagate into the
+ first use when this very specific situation arises. */
+static bool
+locally_poor_mem_replacement (df_ref use, rtx use_set, rtx reg, rtx def_set)
+{
+ rtx rhs, addend, mem, base;
+ unsigned i;
+
+ /* We're only concerned if the RHS of def_set is the sum of two
+ registers. */
+ rhs = SET_SRC (def_set);
+
+ if (GET_CODE (rhs) != PLUS)
+ return false;
+
+ for (i = 0; i < 2; i++)
+ {
+ addend = XEXP (rhs, i);
+ if (!REG_P (addend))
+ return false;
+ }
+
+ /* The use must have a single SET and be used in addressing. */
+ if (!use_set || !DF_REF_REG_MEM_P (use))
+ return false;
+
+ if (DF_REF_REG_MEM_STORE_P (use))
+ mem = SET_DEST (use_set);
+ else
+ mem = SET_SRC (use_set);
+
+ if (GET_CODE (mem) != MEM)
+ return false;
+
+ /* We are specifically interested in the base address. */
+ base = XEXP (mem, 0);
+ if (reg != base)
+ return false;
+
+ /* We've found a use of the first form. Check whether uses of the
+ second form exist in the same block. If found, don't replace. */
+ return bitmap_bit_p (MEM_PLUS_REGS (DF_REF_BB (use)), DF_REF_REGNO (use));
+}
+
/* Try to replace USE with SRC (defined in DEF_INSN) and simplify the
result. */
@@ -1268,6 +1387,11 @@ forward_propagate_and_simplify (df_ref use, rtx de
return false;
}
+ /* Check for a specific unprofitable propagation into a memory
+ reference, where the propagation will break a CSE opportunity. */
+ if (locally_poor_mem_replacement (use, use_set, reg, def_set))
+ return false;
+
if (asm_use >= 0)
return forward_propagate_asm (use, def_insn, def_set, reg);
@@ -1398,6 +1522,12 @@ fwprop_init (void)
static void
fwprop_done (void)
{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ BITMAP_FREE (MEM_PLUS_REGS (bb));
+ free_aux_for_blocks ();
+
loop_optimizer_finalize ();
VEC_free (df_ref, heap, use_def_ref);
reply other threads:[~2011-06-30 14:48 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1309445305.26980.56.camel@oc2474580526.ibm.com \
--to=wschmidt@linux.vnet.ibm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).