* create less temporary rtl
@ 2002-08-12 22:53 Segher Boessenkool
2002-08-13 19:39 ` Richard Henderson
0 siblings, 1 reply; 5+ messages in thread
From: Segher Boessenkool @ 2002-08-12 22:53 UTC (permalink / raw)
To: gcc; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 641 bytes --]
Investigating GCC's memory allocation behaviour, I noticed there are a few
"hot" routines where RTL is generated just to call a function that expects
an rtx while, for example, we only have a register number. The attached
patch fixes one of those places, namely, where call-clobbered registers get
marked as such.
I'm sure I got all the details wrong (and the indenting, too); but it
bootstraps fine (on gnu-linux-powerpc), and is a full minute faster on
bootstrap, too. On some files (expr.c), it saves more than 10% compilation
time.
Of course, with a refcounting garbage collector, the impact would be much
less ;)
Comments?
Segher
[-- Attachment #2: Unknown Document --]
[-- Type: text/plain, Size: 7243 bytes --]
*** flow.c.ORIG Thu Apr 18 22:21:09 2002
--- flow.c Tue Aug 13 05:05:14 2002
***************
*** 304,309 ****
--- 304,313 ----
static void mark_set_1 PARAMS ((struct propagate_block_info *,
enum rtx_code, rtx, rtx,
rtx, int));
+ static void mark_invalidated_by_call PARAMS ((struct propagate_block_info *,
+ rtx, rtx));
+ static void mark_set_reg_invalidated_by_call PARAMS ((struct propagate_block_info *,
+ int, rtx, rtx));
static int find_regno_partial PARAMS ((rtx *, void *));
#ifdef HAVE_conditional_execution
***************
*** 339,344 ****
--- 343,350 ----
rtx));
static void invalidate_mems_from_set PARAMS ((struct propagate_block_info *,
rtx));
+ static void invalidate_mems_from_set_1 PARAMS ((struct propagate_block_info *,
+ int));
static void delete_dead_jumptables PARAMS ((void));
static void clear_log_links PARAMS ((sbitmap));
\f
***************
*** 1694,1700 ****
if (GET_CODE (insn) == CALL_INSN)
{
- int i;
rtx note, cond;
cond = NULL_RTX;
--- 1700,1705 ----
***************
*** 1717,1730 ****
cond, insn, pbi->flags);
/* Calls change all call-used and global registers. */
! for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
! if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
! {
! /* We do not want REG_UNUSED notes for these registers. */
! mark_set_1 (pbi, CLOBBER, gen_rtx_REG (reg_raw_mode[i], i),
! cond, insn,
! pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
! }
}
/* If an insn doesn't use CC0, it becomes dead since we assume
--- 1722,1728 ----
cond, insn, pbi->flags);
/* Calls change all call-used and global registers. */
! mark_invalidated_by_call(pbi, cond, insn);
}
/* If an insn doesn't use CC0, it becomes dead since we assume
***************
*** 2416,2421 ****
--- 2414,2447 ----
}
}
+ static void
+ invalidate_mems_from_set_1 (pbi, regno)
+ struct propagate_block_info *pbi;
+ int regno;
+ {
+ rtx temp = pbi->mem_set_list;
+ rtx prev = NULL_RTX;
+ rtx next;
+
+ while (temp)
+ {
+ next = XEXP (temp, 1);
+ if (refers_to_regno_p (regno, regno, XEXP (temp, 0), (rtx *)0))
+ {
+ /* Splice this entry out of the list. */
+ if (prev)
+ XEXP (prev, 1) = next;
+ else
+ pbi->mem_set_list = next;
+ free_EXPR_LIST_node (temp);
+ pbi->mem_set_list_len--;
+ }
+ else
+ prev = temp;
+ temp = next;
+ }
+ }
+
/* Process the registers that are set within X. Their bits are set to
1 in the regset DEAD, because they are dead prior to this insn.
***************
*** 2802,2807 ****
--- 2828,2964 ----
REG_NOTES (insn)
= alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
}
+ }
+
+ static void
+ mark_set_reg_invalidated_by_call (pbi, regno, cond, insn)
+ struct propagate_block_info *pbi;
+ int regno;
+ rtx cond, insn;
+ {
+ unsigned long not_dead = 0;
+ int flags;
+
+ flags = pbi->flags;
+
+ if ( ! (regno == FRAME_POINTER_REGNUM
+ && (! reload_completed || frame_pointer_needed))
+ #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ && ! (regno == HARD_FRAME_POINTER_REGNUM
+ && (! reload_completed || frame_pointer_needed))
+ #endif
+ #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+ #endif
+ )
+ {
+ int some_was_live = 0, some_was_dead = 0;
+
+ {
+ int needed_regno = REGNO_REG_SET_P (pbi->reg_live, regno);
+ if (pbi->local_set)
+ {
+ /* Order of the set operation matters here since both
+ sets may be the same. */
+ CLEAR_REGNO_REG_SET (pbi->cond_local_set, regno);
+ if (cond != NULL_RTX
+ && ! REGNO_REG_SET_P (pbi->local_set, regno))
+ SET_REGNO_REG_SET (pbi->cond_local_set, regno);
+ else
+ SET_REGNO_REG_SET (pbi->local_set, regno);
+ }
+
+ some_was_live |= needed_regno;
+ some_was_dead |= ! needed_regno;
+ }
+
+ #ifdef HAVE_conditional_execution
+ /* Consider conditional death in deciding that the register needs
+ a death note. */
+ if (some_was_live && ! not_dead
+ /* The stack pointer is never dead. Well, not strictly true,
+ but it's very difficult to tell from here. Hopefully
+ combine_stack_adjustments will fix up the most egregious
+ errors. */
+ && regno != STACK_POINTER_REGNUM)
+ {
+ if (! mark_regno_cond_dead (pbi, regno, cond))
+ not_dead |= 1;
+ }
+ #endif
+
+ /* Additional data to record if this is the final pass. */
+ if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+ {
+ rtx y;
+ int blocknum = pbi->bb->index;
+
+ y = NULL_RTX;
+ if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+ {
+ y = pbi->reg_next_use[regno];
+
+ /* The next use is no longer next, since a store intervenes. */
+ pbi->reg_next_use[regno] = 0;
+ }
+
+ if (! some_was_dead)
+ {
+ if (flags & PROP_LOG_LINKS)
+ {
+ /* Make a logical link from the next following insn
+ that uses this register, back to this insn.
+ The following insns have already been processed.
+
+ We don't build a LOG_LINK for hard registers containing
+ in ASM_OPERANDs. If these registers get replaced,
+ we might wind up changing the semantics of the insn,
+ even if reload can make what appear to be valid
+ assignments later. */
+ if (y && (BLOCK_NUM (y) == blocknum)
+ && (asm_noperands (PATTERN (y)) < 0))
+ LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
+ }
+ }
+ }
+
+ /* Mark the register as being dead. */
+ if (some_was_live
+ /* The stack pointer is never dead. Well, not strictly true,
+ but it's very difficult to tell from here. Hopefully
+ combine_stack_adjustments will fix up the most egregious
+ errors. */
+ && regno != STACK_POINTER_REGNUM)
+ {
+ if (!(not_dead & 1))
+ CLEAR_REGNO_REG_SET (pbi->reg_live, regno);
+ }
+ }
+ else
+ {
+ if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+ pbi->reg_next_use[regno] = 0;
+ }
+ }
+
+ /* Calls change all call-used and global registers. */
+ static void
+ mark_invalidated_by_call (pbi, cond, insn)
+ struct propagate_block_info *pbi;
+ rtx cond;
+ rtx insn;
+ {
+ int i;
+ if (optimize && (pbi->flags & PROP_SCAN_DEAD_CODE))
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
+ {
+ /* This set is a REG, so it kills any MEMs which use the reg. */
+ invalidate_mems_from_set_1 (pbi, i);
+ }
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
+ mark_set_reg_invalidated_by_call (pbi, i, cond, insn);
}
\f
#ifdef HAVE_conditional_execution
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: create less temporary rtl
2002-08-12 22:53 create less temporary rtl Segher Boessenkool
@ 2002-08-13 19:39 ` Richard Henderson
2002-08-14 17:25 ` Segher Boessenkool
0 siblings, 1 reply; 5+ messages in thread
From: Richard Henderson @ 2002-08-13 19:39 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: gcc, gcc-patches
On Tue, Aug 13, 2002 at 07:50:01AM +0200, Segher Boessenkool wrote:
> I'm sure I got all the details wrong (and the indenting, too); but it
> bootstraps fine (on gnu-linux-powerpc), and is a full minute faster on
> bootstrap, too. On some files (expr.c), it saves more than 10% compilation
> time.
You need to look on gcc mainline, in which this has already been fixed.
> ! /* We do not want REG_UNUSED notes for these registers. */
> ! mark_set_1 (pbi, CLOBBER, gen_rtx_REG (reg_raw_mode[i], i),
> ! cond, insn,
> ! pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
Mainline looks like
mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn,
pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
r~
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: create less temporary rtl
2002-08-13 19:39 ` Richard Henderson
@ 2002-08-14 17:25 ` Segher Boessenkool
2002-08-14 17:41 ` Andrew Pinski
2002-08-14 17:55 ` Richard Henderson
0 siblings, 2 replies; 5+ messages in thread
From: Segher Boessenkool @ 2002-08-14 17:25 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc, gcc-patches
Richard Henderson wrote:
>
> On Tue, Aug 13, 2002 at 07:50:01AM +0200, Segher Boessenkool wrote:
> > I'm sure I got all the details wrong (and the indenting, too); but it
> > bootstraps fine (on gnu-linux-powerpc), and is a full minute faster on
> > bootstrap, too. On some files (expr.c), it saves more than 10% compilation
> > time.
>
> You need to look on gcc mainline, in which this has already been fixed.
Whoops. I downloaded a snapshot, thinking it came from mainline. Ouch.
Is there anywhere to download a mainline snapshot? CVS is extremely painful
on my current network connection (dialup. ouch.)
Thanks for the patch review, and I hope my next patch will be less of a waste
of time,
Segher
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: create less temporary rtl
2002-08-14 17:25 ` Segher Boessenkool
@ 2002-08-14 17:41 ` Andrew Pinski
2002-08-14 17:55 ` Richard Henderson
1 sibling, 0 replies; 5+ messages in thread
From: Andrew Pinski @ 2002-08-14 17:41 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: Richard Henderson, gcc, gcc-patches
You could always look into the cvs via the web to is
if there is a problem still.
Thanks,
Andrew Pinski
On Wednesday, August 14, 2002, at 08:23 , Segher Boessenkool wrote:
>
>
> Richard Henderson wrote:
>>
>> On Tue, Aug 13, 2002 at 07:50:01AM +0200, Segher Boessenkool wrote:
>>> I'm sure I got all the details wrong (and the indenting, too); but it
>>> bootstraps fine (on gnu-linux-powerpc), and is a full minute
>>> faster on
>>> bootstrap, too. On some files (expr.c), it saves more than
>>> 10% compilation
>>> time.
>>
>> You need to look on gcc mainline, in which this has already
>> been fixed.
>
> Whoops. I downloaded a snapshot, thinking it came from
> mainline. Ouch.
> Is there anywhere to download a mainline snapshot? CVS is
> extremely painful
> on my current network connection (dialup. ouch.)
>
> Thanks for the patch review, and I hope my next patch will be
> less of a waste
> of time,
>
>
> Segher
>
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: create less temporary rtl
2002-08-14 17:25 ` Segher Boessenkool
2002-08-14 17:41 ` Andrew Pinski
@ 2002-08-14 17:55 ` Richard Henderson
1 sibling, 0 replies; 5+ messages in thread
From: Richard Henderson @ 2002-08-14 17:55 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: gcc, gcc-patches
On Thu, Aug 15, 2002 at 02:23:06AM +0200, Segher Boessenkool wrote:
> Is there anywhere to download a mainline snapshot? CVS is extremely painful
> on my current network connection (dialup. ouch.)
Unfortunately not. We ought to be making snapshots off
of both branches, but we don't.
r~
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-08-15 0:55 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-12 22:53 create less temporary rtl Segher Boessenkool
2002-08-13 19:39 ` Richard Henderson
2002-08-14 17:25 ` Segher Boessenkool
2002-08-14 17:41 ` Andrew Pinski
2002-08-14 17:55 ` Richard Henderson
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).