From: Steve Ellcey <sje@cup.hp.com>
To: gcc-patches@gcc.gnu.org
Subject: Patch for PR 31850 and slow compilation of limits-fndefn.c
Date: Thu, 24 May 2007 15:59:00 -0000 [thread overview]
Message-ID: <200705241551.IAA07054@hpsje.cup.hp.com> (raw)
The PR 31850 bug report actually talks about a slowdown in
limits-fnargs.c but while fixing that I found that limits-fndefn.c was
also very slow, but for a different reason.
This patch fixes the slowdown in the compilation of limits-fndefn.c. On
my PA box complilation goes from 30 minutes to 2 minutes after applying
this patch.
The problem is that for each argument we pass into a function we look to
see if we need to create any conversion instructions and as part of this
we call push_to_sequence. push_to_sequence takes the instruction passed
it and walks the sequence to the end in order to set last_insn. As the
sequence gets longer and longer push_to_sequence gets slower and slower.
This patch fixes the problem by creating push_to_sequence2 which takes
the last instruction (as well as the first) as arguments so it doesn't
have to walk the list. I added a field to the assign_parm_data_all
structure in function.c so we could save the first and last instructions
in the conversion sequence instead of just saving the first instruction.
Regression tested on IA64 HP-UX and Linux and on HPPA HP-UX.
OK to checkin?
2007-05-23 Steve Ellcey <sje@cup.hp.com>
PR target/31850
* rtl.h (push_to_sequence2): New.
* emit-rtl.c (push_to_sequence2): New.
* function.c (assign_parm_data_all): Add new fields.
(assign_parm_setup_block): Call push_to_sequence2 instead of
push_to_sequence.
(assign_parm_setup_reg): Ditto.
(assign_parm_setup_stack): Ditto.
(assign_parms_unsplit_complex): Ditto.
(assign_parms): Change field name.
Index: rtl.h
===================================================================
--- rtl.h (revision 124974)
+++ rtl.h (working copy)
@@ -1494,6 +1494,7 @@ extern rtx get_first_nonnote_insn (void)
extern rtx get_last_nonnote_insn (void);
extern void start_sequence (void);
extern void push_to_sequence (rtx);
+extern void push_to_sequence2 (rtx, rtx);
extern void end_sequence (void);
extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
enum machine_mode);
Index: emit-rtl.c
===================================================================
--- emit-rtl.c (revision 124974)
+++ emit-rtl.c (working copy)
@@ -4630,6 +4630,18 @@ push_to_sequence (rtx first)
last_insn = last;
}
+/* Like push_to_sequence, but take the last insn as an argument to avoid
+ looping through the list. */
+
+void
+push_to_sequence2 (rtx first, rtx last)
+{
+ start_sequence ();
+
+ first_insn = first;
+ last_insn = last;
+}
+
/* Set up the outer-level insn chain
as the current sequence, saving the previously current one. */
Index: function.c
===================================================================
--- function.c (revision 124974)
+++ function.c (working copy)
@@ -1895,7 +1895,8 @@ struct assign_parm_data_all
struct args_size stack_args_size;
tree function_result_decl;
tree orig_fnargs;
- rtx conversion_insns;
+ rtx first_conversion_insn;
+ rtx last_conversion_insn;
HOST_WIDE_INT pretend_args_size;
HOST_WIDE_INT extra_pretend_bytes;
int reg_parm_stack_space;
@@ -2489,7 +2490,8 @@ assign_parm_setup_block (struct assign_p
{
rtx parmreg = gen_reg_rtx (data->nominal_mode);
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn,
+ all->last_conversion_insn);
/* For values returned in multiple registers, handle possible
incompatible calls to emit_group_store.
@@ -2514,7 +2516,8 @@ assign_parm_setup_block (struct assign_p
emit_group_store (parmreg, entry_parm, data->nominal_type,
int_size_in_bytes (data->nominal_type));
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
SET_DECL_RTL (parm, parmreg);
@@ -2561,9 +2564,11 @@ assign_parm_setup_block (struct assign_p
/* Handle values in multiple non-contiguous locations. */
if (GET_CODE (entry_parm) == PARALLEL)
{
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn,
+ all->last_conversion_insn);
emit_group_store (mem, entry_parm, data->passed_type, size);
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
}
@@ -2622,10 +2627,11 @@ assign_parm_setup_block (struct assign_p
}
else if (data->stack_parm == 0)
{
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
BLOCK_OP_NORMAL);
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
}
@@ -2698,7 +2704,7 @@ assign_parm_setup_reg (struct assign_par
emit_move_insn (tempreg, validize_mem (data->entry_parm));
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp);
if (GET_CODE (tempreg) == SUBREG
@@ -2719,7 +2725,8 @@ assign_parm_setup_reg (struct assign_par
save_tree_used = TREE_USED (parm);
expand_assignment (parm, make_tree (data->nominal_type, tempreg));
TREE_USED (parm) = save_tree_used;
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
did_conversion = true;
@@ -2745,11 +2752,13 @@ assign_parm_setup_reg (struct assign_par
rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm)));
int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm));
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn,
+ all->last_conversion_insn);
emit_move_insn (tempreg, DECL_RTL (parm));
tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p);
emit_move_insn (parmreg, tempreg);
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
did_conversion = true;
@@ -2835,7 +2844,7 @@ assign_parm_setup_stack (struct assign_p
emit_move_insn (tempreg, validize_mem (data->entry_parm));
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
to_conversion = true;
data->entry_parm = convert_to_mode (data->nominal_mode, tempreg,
@@ -2867,7 +2876,8 @@ assign_parm_setup_stack (struct assign_p
{
/* Use a block move to handle potentially misaligned entry_parm. */
if (!to_conversion)
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn,
+ all->last_conversion_insn);
to_conversion = true;
emit_block_move (dest, src,
@@ -2880,7 +2890,8 @@ assign_parm_setup_stack (struct assign_p
if (to_conversion)
{
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
}
@@ -2924,10 +2935,12 @@ assign_parms_unsplit_complex (struct ass
set_mem_attributes (tmp, parm, 1);
rmem = adjust_address_nv (tmp, inner, 0);
imem = adjust_address_nv (tmp, inner, GET_MODE_SIZE (inner));
- push_to_sequence (all->conversion_insns);
+ push_to_sequence2 (all->first_conversion_insn,
+ all->last_conversion_insn);
emit_move_insn (rmem, real);
emit_move_insn (imem, imag);
- all->conversion_insns = get_insns ();
+ all->first_conversion_insn = get_insns ();
+ all->last_conversion_insn = get_last_insn ();
end_sequence ();
}
else
@@ -3025,7 +3038,7 @@ assign_parms (tree fndecl)
/* Output all parameter conversion instructions (possibly including calls)
now that all parameters have been copied out of hard registers. */
- emit_insn (all.conversion_insns);
+ emit_insn (all.first_conversion_insn);
/* If we are receiving a struct value address as the first argument, set up
the RTL for the function result. As this might require code to convert
reply other threads:[~2007-05-24 15:51 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=200705241551.IAA07054@hpsje.cup.hp.com \
--to=sje@cup.hp.com \
--cc=gcc-patches@gcc.gnu.org \
/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).