* [patch] PR debug/53948
@ 2012-07-18 17:47 Steven Bosscher
2012-07-18 17:55 ` Jan Kratochvil
2012-12-18 11:45 ` Richard Biener
0 siblings, 2 replies; 6+ messages in thread
From: Steven Bosscher @ 2012-07-18 17:47 UTC (permalink / raw)
To: GCC Patches, jan.kratochvil
[-- Attachment #1: Type: text/plain, Size: 1532 bytes --]
Hello,
This is my proposed fix for PR53948. We don't want to put user
variables in callee-clobbered registers, but obviously function
arguments are OK there. REG_USERVAR_P is set on PARM_DECLs and on user
variables, so it can't be used to distinguish between the two.
As it turns out, I can hi-jack a bit for that: 'unchanging' (currently
incorrectly documented as used on REG) for a new macro
REG_FUNCTION_PARM_P. I found one obvious place where this bit can be
used instead of REG_USERVAR_P, and probably there are a few more
places where this is useful (TBD, I'm going to look at all places
where RTL code looks at tree's PARM_DECL later).
Bootstrapped&tested on powerpc64-unknown-linux-gnu.
OK for trunk?
Ciao!
Steven
PR debug/53948
* rtl.h (REG_FUNCTION_PARM_P): New flag on a REG. Re-use 'unchaning'.
* emit-rtl.c (mark_function_parm_reg): New function.
* function.c (assign_parm_setup_reg): Use mark_function_parm_reg
instead of mark_user_reg.
* combine.c (can_change_dest_mode): Preserve REG_FUNCTION_PARM_P.
* web.c (entry_register): Likewise.
* reload1.c (reload): Likewise.
* ira-emit.c (ira_create_new_reg): Likewise.
* reginfo.c (reg_scan_mark_refs): Likewise.
* optabs.c (emit_libcall_block_1): Use REG_FUNCTION_PARM_P instead
of REG_USERVAR_P.
* regstat.c (dump_reg_info): Print REG_FUNCTION_PARM_P.
* doc/rtl.texi (REG_FUNCTION_PARM_P): Document it.
('unchanging' flag): Fix documentation.
[-- Attachment #2: PR53948.diff --]
[-- Type: application/octet-stream, Size: 8972 bytes --]
PR debug/53948
* rtl.h (REG_FUNCTION_PARM_P): New flag on a REG. Re-use 'unchanging'.
* emit-rtl.c (mark_function_parm_reg): New function.
* function.c (assign_parm_setup_reg): Use mark_function_parm_reg
instead of mark_user_reg.
* combine.c (can_change_dest_mode): Preserve REG_FUNCTION_PARM_P.
* web.c (entry_register): Likewise.
* reload1.c (reload): Likewise.
* ira-emit.c (ira_create_new_reg): Likewise.
* reginfo.c (reg_scan_mark_refs): Likewise.
* optabs.c (emit_libcall_block_1): Use REG_FUNCTION_PARM_P instead
of REG_USERVAR_P.
* regstat.c (dump_reg_info): Print REG_FUNCTION_PARM_P.
* doc/rtl.texi (REG_FUNCTION_PARM_P): Document it.
('unchanging' flag): Fix documentation.
Index: rtl.h
===================================================================
--- rtl.h (revision 189546)
+++ rtl.h (working copy)
@@ -274,7 +274,8 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"),
1 in a CALL_INSN logically equivalent to
ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P. */
unsigned int call : 1;
- /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
+ /* 1 in a REG if the register is a placeholder for a function parameter.
+ 1 in a MEM, or CONCAT if the value is set at most once, anywhere.
1 in a SUBREG used for SUBREG_PROMOTED_UNSIGNED_P.
1 in a SYMBOL_REF if it addresses something in the per-function
constants pool.
@@ -1101,6 +1102,10 @@ rhs_regno (const_rtx x)
#define REG_USERVAR_P(RTX) \
(RTL_FLAG_CHECK1("REG_USERVAR_P", (RTX), REG)->volatil)
+/* 1 if RTX is a reg that corresponds to a function parameter. */
+#define REG_FUNCTION_PARM_P(RTX) \
+ (RTL_FLAG_CHECK1("REG_FUNCTION_PARM_P", (RTX), REG)->unchanging)
+
/* 1 if RTX is a reg that holds a pointer value. */
#define REG_POINTER(RTX) \
(RTL_FLAG_CHECK1("REG_POINTER", (RTX), REG)->frame_related)
@@ -2415,6 +2420,7 @@ extern void maybe_set_first_label_num (rtx);
extern void delete_insns_since (rtx);
extern void mark_reg_pointer (rtx, int);
extern void mark_user_reg (rtx);
+extern void mark_function_parm_reg (rtx);
extern void reset_used_flags (rtx);
extern void set_used_flags (rtx);
extern void reorder_insns (rtx, rtx, rtx);
Index: emit-rtl.c
===================================================================
--- emit-rtl.c (revision 189546)
+++ emit-rtl.c (working copy)
@@ -1124,6 +1124,23 @@ mark_user_reg (rtx reg)
}
}
+/* Identify REG (which may be a CONCAT) as a user function parameter. */
+
+void
+mark_function_parm_reg (rtx reg)
+{
+ if (GET_CODE (reg) == CONCAT)
+ {
+ REG_FUNCTION_PARM_P (XEXP (reg, 0)) = 1;
+ REG_FUNCTION_PARM_P (XEXP (reg, 1)) = 1;
+ }
+ else
+ {
+ gcc_assert (REG_P (reg));
+ REG_FUNCTION_PARM_P (reg) = 1;
+ }
+}
+
/* Identify REG as a probable pointer register and show its alignment
as ALIGN, if nonzero. */
Index: function.c
===================================================================
--- function.c (revision 189546)
+++ function.c (working copy)
@@ -2923,7 +2923,7 @@ assign_parm_setup_reg (struct assign_parm_data_all
parmreg = gen_reg_rtx (promoted_nominal_mode);
if (!DECL_ARTIFICIAL (parm))
- mark_user_reg (parmreg);
+ mark_function_parm_reg (parmreg);
/* If this was an item that we received a pointer to,
set DECL_RTL appropriately. */
@@ -3075,7 +3075,7 @@ assign_parm_setup_reg (struct assign_parm_data_all
/* We can't use nominal_mode, because it will have been set to
Pmode above. We must use the actual mode of the parm. */
parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
- mark_user_reg (parmreg);
+ mark_function_parm_reg (parmreg);
if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
{
Index: combine.c
===================================================================
--- combine.c (revision 189546)
+++ combine.c (working copy)
@@ -2334,7 +2334,8 @@ can_change_dest_mode (rtx x, int added_sets, enum
/* Or a pseudo that is only used once. */
return (REG_N_SETS (regno) == 1 && !added_sets
- && !REG_USERVAR_P (x));
+ && !REG_USERVAR_P (x)
+ && !REG_FUNCTION_PARM_P (x));
}
Index: web.c
===================================================================
--- web.c (revision 189546)
+++ web.c (working copy)
@@ -263,6 +263,7 @@ entry_register (struct web_entry *entry, df_ref re
{
newreg = gen_reg_rtx (GET_MODE (reg));
REG_USERVAR_P (newreg) = REG_USERVAR_P (reg);
+ REG_FUNCTION_PARM_P (newreg) = REG_FUNCTION_PARM_P (reg);
REG_POINTER (newreg) = REG_POINTER (reg);
REG_ATTRS (newreg) = REG_ATTRS (reg);
if (dump_file)
Index: reload1.c
===================================================================
--- reload1.c (revision 189546)
+++ reload1.c (working copy)
@@ -1106,6 +1106,7 @@ reload (rtx first, int global)
rtx reg = regno_reg_rtx[i];
REG_USERVAR_P (reg) = 0;
+ REG_FUNCTION_PARM_P (reg) = 0;
PUT_CODE (reg, MEM);
XEXP (reg, 0) = addr;
if (reg_equiv_memory_loc (i))
Index: ira-emit.c
===================================================================
--- ira-emit.c (revision 189546)
+++ ira-emit.c (working copy)
@@ -335,6 +335,7 @@ ira_create_new_reg (rtx original_reg)
new_reg = gen_reg_rtx (GET_MODE (original_reg));
ORIGINAL_REGNO (new_reg) = ORIGINAL_REGNO (original_reg);
REG_USERVAR_P (new_reg) = REG_USERVAR_P (original_reg);
+ REG_FUNCTION_PARM_P (new_reg) = REG_FUNCTION_PARM_P (original_reg);
REG_POINTER (new_reg) = REG_POINTER (original_reg);
REG_ATTRS (new_reg) = REG_ATTRS (original_reg);
if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
Index: reginfo.c
===================================================================
--- reginfo.c (revision 189546)
+++ reginfo.c (working copy)
@@ -1081,6 +1081,7 @@ reg_scan_mark_refs (rtx x, rtx insn)
pseudo if this is the only set of that pseudo. */
&& DF_REG_DEF_COUNT (REGNO (SET_DEST (x))) == 1
&& ! REG_USERVAR_P (SET_DEST (x))
+ && ! REG_FUNCTION_PARM_P (SET_DEST (x))
&& ! REG_POINTER (SET_DEST (x))
&& ((REG_P (SET_SRC (x))
&& REG_POINTER (SET_SRC (x)))
Index: optabs.c
===================================================================
--- optabs.c (revision 189546)
+++ optabs.c (working copy)
@@ -3851,9 +3851,10 @@ emit_libcall_block_1 (rtx insns, rtx target, rtx r
rtx final_dest = target;
rtx next, last, insn;
- /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
- into a MEM later. Protect the libcall block from this change. */
- if (! REG_P (target) || REG_USERVAR_P (target))
+ /* If this is a reg with REG_FUNCTION_PARM_P set, then it could possibly turn
+ into a MEM later (e.g. if a REG_EQUIV note is attached to the insns that
+ sets the reg). Protect the libcall block from this change. */
+ if (! REG_P (target) || REG_FUNCTION_PARM_P (target))
target = gen_reg_rtx (GET_MODE (target));
/* If we're using non-call exceptions, a libcall corresponding to an
Index: regstat.c
===================================================================
--- regstat.c (revision 189546)
+++ regstat.c (working copy)
@@ -578,6 +578,8 @@ dump_reg_info (FILE *file)
(DF_REG_DEF_COUNT (i) == 1) ? "" : "s");
if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
fputs ("; user var", file);
+ if (regno_reg_rtx[i] != NULL && REG_FUNCTION_PARM_P (regno_reg_rtx[i]))
+ fputs ("; function parm", file);
if (REG_N_DEATHS (i) != 1)
fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
if (REG_N_CALLS_CROSSED (i) == 1)
Index: doc/rtl.texi
===================================================================
--- doc/rtl.texi (revision 189546)
+++ doc/rtl.texi (working copy)
@@ -731,6 +731,15 @@ The same hard register may be used also for collec
functions called by this one, but @code{REG_FUNCTION_VALUE_P} is zero
in this kind of use.
+@findex REG_FUNCTION_PARM_P
+@cindex @code{reg} and @samp{/u}
+@cindex @code{unchanging}, in @code{reg}
+@item REG_FUNCTION_PARM_P (@var{x})
+In a @code{reg}, nonzero if it corresponds to a function argument present
+in the user's source code. Zero for arguments generated internally by
+the compiler. Stored in the @code{unchanging} field and printed as
+@samp{/u}. The flag uses its meaning after reload has completed.
+
@findex RTX_FRAME_RELATED_P
@cindex @code{insn} and @samp{/f}
@cindex @code{call_insn} and @samp{/f}
@@ -978,7 +987,10 @@ In an RTL dump, this flag is represented as @samp{
@findex unchanging
@cindex @samp{/u} in RTL dump
@item unchanging
-In @code{reg} and @code{mem} expressions, 1 means
+In @code{reg} expressions, 1 means
+that the register is used for a function argument.
+
+In @code{mem} expressions, 1 means
that the value of the expression never changes.
In @code{subreg} expressions, it is 1 if the @code{subreg} references an
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] PR debug/53948
2012-07-18 17:47 [patch] PR debug/53948 Steven Bosscher
@ 2012-07-18 17:55 ` Jan Kratochvil
2012-07-18 18:06 ` Steven Bosscher
2012-12-18 11:45 ` Richard Biener
1 sibling, 1 reply; 6+ messages in thread
From: Jan Kratochvil @ 2012-07-18 17:55 UTC (permalink / raw)
To: Steven Bosscher; +Cc: GCC Patches
Hello Steven,
On Wed, 18 Jul 2012 19:46:16 +0200, Steven Bosscher wrote:
> This is my proposed fix for PR53948.
I can't speak for the GCC code but could it have a GCC testcase?
Thanks,
Jan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] PR debug/53948
2012-07-18 17:55 ` Jan Kratochvil
@ 2012-07-18 18:06 ` Steven Bosscher
2012-07-18 18:55 ` Jan Kratochvil
0 siblings, 1 reply; 6+ messages in thread
From: Steven Bosscher @ 2012-07-18 18:06 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: GCC Patches
On Wed, Jul 18, 2012 at 7:55 PM, Jan Kratochvil
<jan.kratochvil@redhat.com> wrote:
> Hello Steven,
>
> On Wed, 18 Jul 2012 19:46:16 +0200, Steven Bosscher wrote:
>> This is my proposed fix for PR53948.
>
> I can't speak for the GCC code but could it have a GCC testcase?
I wouldn't know what to test for. Looking for a .loc marker seems a bit fragile.
Ciao!
Steven
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] PR debug/53948
2012-07-18 18:06 ` Steven Bosscher
@ 2012-07-18 18:55 ` Jan Kratochvil
2012-07-18 19:01 ` Jakub Jelinek
0 siblings, 1 reply; 6+ messages in thread
From: Jan Kratochvil @ 2012-07-18 18:55 UTC (permalink / raw)
To: Steven Bosscher; +Cc: GCC Patches
On Wed, 18 Jul 2012 20:05:46 +0200, Steven Bosscher wrote:
> I wouldn't know what to test for. Looking for a .loc marker seems a bit fragile.
What is fragile on
// { dg-final { scan-assembler-times "\\.loc\t1 3 0\\r\\n\t\[^.\]" 6 } }
or something like that. Line numbers are constant for the testcase.
Thanks,
Jan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] PR debug/53948
2012-07-18 18:55 ` Jan Kratochvil
@ 2012-07-18 19:01 ` Jakub Jelinek
0 siblings, 0 replies; 6+ messages in thread
From: Jakub Jelinek @ 2012-07-18 19:01 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: Steven Bosscher, GCC Patches
On Wed, Jul 18, 2012 at 08:55:17PM +0200, Jan Kratochvil wrote:
> On Wed, 18 Jul 2012 20:05:46 +0200, Steven Bosscher wrote:
> > I wouldn't know what to test for. Looking for a .loc marker seems a bit fragile.
>
> What is fragile on
> // { dg-final { scan-assembler-times "\\.loc\t1 3 0\\r\\n\t\[^.\]" 6 } }
>
> or something like that. Line numbers are constant for the testcase.
Not all assemblers support .loc markers, sometimes .debug_line is emitted by
gcc directly, and not all targets use dwarf. For the latter we can just put
the test into gcc.dg/debug/dwarf/, for the former we would need a new
dejagnu test. But more importantly, on different arches I'd guess the
number of .loc times might be different.
Better than that would be a guality testcase limited to -O0.
Jakub
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch] PR debug/53948
2012-07-18 17:47 [patch] PR debug/53948 Steven Bosscher
2012-07-18 17:55 ` Jan Kratochvil
@ 2012-12-18 11:45 ` Richard Biener
1 sibling, 0 replies; 6+ messages in thread
From: Richard Biener @ 2012-12-18 11:45 UTC (permalink / raw)
To: Steven Bosscher; +Cc: GCC Patches, jan.kratochvil
On Wed, Jul 18, 2012 at 7:46 PM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> Hello,
>
> This is my proposed fix for PR53948. We don't want to put user
> variables in callee-clobbered registers, but obviously function
> arguments are OK there. REG_USERVAR_P is set on PARM_DECLs and on user
> variables, so it can't be used to distinguish between the two.
>
> As it turns out, I can hi-jack a bit for that: 'unchanging' (currently
> incorrectly documented as used on REG) for a new macro
> REG_FUNCTION_PARM_P. I found one obvious place where this bit can be
> used instead of REG_USERVAR_P, and probably there are a few more
> places where this is useful (TBD, I'm going to look at all places
> where RTL code looks at tree's PARM_DECL later).
>
> Bootstrapped&tested on powerpc64-unknown-linux-gnu.
> OK for trunk?
Just being pointed back to this patch ... I wonder if simply looking
at REG_EXPR of a REG_USERVAR_P reg and checking whether
it's a PARM_DECL isn't good enough (and simpler)?
I suppose the optabs.c change was the "real" fix, thus sth like
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (revision 194552)
+++ gcc/optabs.c (working copy)
@@ -3848,9 +3848,13 @@ emit_libcall_block_1 (rtx insns, rtx tar
rtx final_dest = target;
rtx next, last, insn;
- /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
- into a MEM later. Protect the libcall block from this change. */
- if (! REG_P (target) || REG_USERVAR_P (target))
+ /* If this is a parameter with REG_USERVAR_P set, then it could possibly turn
+ into a MEM later (e.g. if a REG_EQUIV note is attached to the insns that
+ sets the reg). Protect the libcall block from this change. */
+ if (! REG_P (target)
+ || (REG_USERVAR_P (target)
+ && REG_EXPR (target) != NULL_TREE
+ && TREE_CODE (REG_EXPR (target)) == PARM_DECL))
target = gen_reg_rtx (GET_MODE (target));
/* If we're using non-call exceptions, a libcall corresponding to an
(untested)
Thanks,
Richard.
> Ciao!
> Steven
>
> PR debug/53948
> * rtl.h (REG_FUNCTION_PARM_P): New flag on a REG. Re-use 'unchaning'.
> * emit-rtl.c (mark_function_parm_reg): New function.
> * function.c (assign_parm_setup_reg): Use mark_function_parm_reg
> instead of mark_user_reg.
> * combine.c (can_change_dest_mode): Preserve REG_FUNCTION_PARM_P.
> * web.c (entry_register): Likewise.
> * reload1.c (reload): Likewise.
> * ira-emit.c (ira_create_new_reg): Likewise.
> * reginfo.c (reg_scan_mark_refs): Likewise.
> * optabs.c (emit_libcall_block_1): Use REG_FUNCTION_PARM_P instead
> of REG_USERVAR_P.
> * regstat.c (dump_reg_info): Print REG_FUNCTION_PARM_P.
> * doc/rtl.texi (REG_FUNCTION_PARM_P): Document it.
> ('unchanging' flag): Fix documentation.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-12-18 11:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-18 17:47 [patch] PR debug/53948 Steven Bosscher
2012-07-18 17:55 ` Jan Kratochvil
2012-07-18 18:06 ` Steven Bosscher
2012-07-18 18:55 ` Jan Kratochvil
2012-07-18 19:01 ` Jakub Jelinek
2012-12-18 11:45 ` Richard Biener
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).