This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: Fix dse / postreload not to bypass add expanders
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: Joern Rennecke <amylaar at spamcop dot net>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 3 Nov 2011 20:01:00 +0100
- Subject: Re: RFA: Fix dse / postreload not to bypass add expanders
- References: <20111101045348.qp9lxw7jhkogcook-nzlynne@webmail.spamcop.net>
> This patch makes emit_inc_dec_insn_before use add3_insn / gen_move_insn
> so that the appropriate expanders are used to create the new instructions,
> and for dse it use the available register liveness information to check
> that no live fixed hard register, like a flags register, is clobbered in
> the process. For postreload, there is no such information available, so we
> give up when we see a clobber / set that might be problematic.
2011-10-31 Joern Rennecke <joern.rennecke@embecosm.com>
* regset.h (fixed_regset): Declare.
* dse.c: Include regset.h .
(struct insn_info): Add member fixed_regs_live.
(note_add_store_info): New typedef.
(note_add_store): New function.
(emit_inc_dec_insn_before): Expect arg to be of type insn_info_t .
Use gen_add3_insn / gen_move_insn.
Check new insn for unwanted clobbers before emitting it.
(check_for_inc_dec): Rename to...
(check_for_inc_dec_1:) ... this. Return bool. Take insn_info
parameter. Changed all callers in file.
(check_for_inc_dec, copy_fixed_regs): New functions.
(scan_insn): Set fixed_regs_live field of insn_info.
* rtl.h (check_for_inc_dec): Update prototype.
* postreload.c (reload_cse_simplify): Take new signature of
check_ind_dec into account.
* reginfo.c (fixed_regset): New variable.
(init_reg_sets_1): Initialize it.
OK modulo the following:
+typedef struct
+{
+ rtx insert_before;
This field is never read.
+ rtx first, current;
+ regset fixed_regs_live;
+ bool failure;
+} note_add_store_info;
+
+/* Callback for emit_inc_dec_insn_before via note_stores.
+ Check if a register is clobbered which is life afterwards. */
"live"
+static void
+note_add_store (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *data)
Missing blank line. The functions in dse.c have a blank line between head
comment and body.
+{
+ rtx insn, *nextp;
+ note_add_store_info *info = (note_add_store_info *) data;
+ int r, n;
+
+ if (!REG_P (loc))
+ return;
+ /* If this register is referenced by the current or an earlier insn,
+ that's OK. E.g. this applies to the register that is being incremented
+ with this addition. */
Blank line before the comment.
+ nextp = &info->first;
+ do
+ {
+ insn = *nextp;
+ nextp = &NEXT_INSN (insn);
+ if (reg_referenced_p (loc, PATTERN (insn)))
+ return;
+ }
+ while (insn != info->current);
Isn't that a convoluted way of writing this?
for (insn = info->first;
insn != NEXT_INSN (info->current);
insn = NEXT_INSN (insn))
if (reg_referenced_p (loc, PATTERN (insn)))
return;
+ if (!info->fixed_regs_live)
+ {
+ info->failure = true;
+ return;
+ }
Missing comment explaining why we do that.
+ /* Now check if this is a live fixed register. */
+ r = REGNO (loc);
+ n = HARD_REGNO_NREGS (r, GET_MODE (loc));
+ while (--n >= 0)
+ if (REGNO_REG_SET_P (info->fixed_regs_live, r+n))
+ info->failure = true;
Blank line before the comment. What's the point in the reverse iteration?
for (i = 0; i < hard_regno_nregs[regno][GET_MODE (loc)]; i++)
if (REGNO_REG_SET_P (info->fixed_regs_live, regno + i))
{
info->failure = true;
return;
}
hard_regno_nregs in small letters.
+ info.insert_before = insn;
+ info.first = new_insn;
+ info.fixed_regs_live = insn_info->fixed_regs_live;
+ info.failure = false;
+ for (cur = new_insn; cur; cur = NEXT_INSN (cur))
+ {
+ info.current = cur;
+ note_stores (PATTERN (cur), note_add_store, &info);
+ }
+ if (info.failure)
+ return 1;
Missing comment explaining what we're doing.
/* Before we delete INSN, make sure that the auto inc/dec, if it is
- there, is split into a separate insn. */
+ there, is split into a separate insn.
+ Return true on success (or if there was nothing to do), false on failure.
*/
-void
-check_for_inc_dec (rtx insn)
+static bool
+check_for_inc_dec_1 (insn_info_t insn_info)
Missing adjustment in the comment: "Before we delete the insn described by
INSN_INFO, make sure..."
+/* Entry point for postreload. */
+bool
+check_for_inc_dec (rtx insn, regset fixed_regs_live)
No point in adding an argument if it is always null. Missing blank line and
head comment: "Same as above, but take a naked INSN instead. This is used by
passes like that don't compute precise liveness information."
+/* Return a bitmap of the fixed registers contained in IN. */
+static bitmap
+copy_fixed_regs (const_bitmap in)
+{
+ bitmap ret;
+
+ ret = ALLOC_REG_SET (NULL);
+ bitmap_and (ret, in, fixed_regset);
+ return ret;
+}
Missing blank line.
+/* Same information as fixed_reg_set but in regset form. */
+regset fixed_regset;
Hum, you'd better have a good trick to remember which is which. This isn't
pretty, but let's mimic what is just above:
/* Same information as FIXED_REG_SET but in regset form. */
regset fixed_reg_set_regset;
--
Eric Botcazou