public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jan Hubicka <jh@suse.cz>
To: gcc-patches@gcc.gnu.org
Subject: Reduce startup cost of compiler (patch 3)
Date: Tue, 24 Jul 2007 06:51:00 -0000	[thread overview]
Message-ID: <20070724050556.GD10270@kam.mff.cuni.cz> (raw)

Hi,
another surprise in the profile of empty function compilation is
constrain_operands.  This I always believed to be related to reload
overhead that is not quite true.  caller-save.c is computing quite large
table specifying if given pseudo can be saved in given mode.
Since number of modes is high, this consume quite a lot of time.  This
patch employs lazy computation, so we don't need to compute each
impossible alternative, just those appearing in practice.

This needed some ggc tweaks to keep the testing instruction around.

Bootstrapped/regtested ia64-linux, OK?

Honza

	* caller-save.c: Include ggc.h, gt-caller-save.h
	(reg_save_code, reg_restore_code): Rename to ...
	(cached_reg_save_code, cached_reg_restore_code): ... those.
	(savepat, restpat, test_reg, test_mem, saveinsn, restinsn): New.
	(reg_save_code, reg_restore_code): New functions.
	(init_caller_save): Do not intialize
	reg_save_code/reg_restore_code tables.
	* Makeifle.in: (gt-caller-save.h): New.
Index: caller-save.c
===================================================================
*** caller-save.c	(revision 126800)
--- caller-save.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 37,42 ****
--- 37,43 ----
  #include "tm_p.h"
  #include "addresses.h"
  #include "df.h"
+ #include "ggc.h"
  
  #ifndef MAX_MOVE_MAX
  #define MAX_MOVE_MAX MOVE_MAX
*************** static rtx
*** 69,77 ****
     be recognized.  */
  
  static int
!   reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
  static int
!   reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
  
  /* Set of hard regs currently residing in save area (during insn scan).  */
  
--- 70,78 ----
     be recognized.  */
  
  static int
!   cached_reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
  static int
!   cached_reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
  
  /* Set of hard regs currently residing in save area (during insn scan).  */
  
*************** static struct insn_chain *insert_one_ins
*** 96,101 ****
--- 97,164 ----
  					   rtx);
  static void add_stored_regs (rtx, rtx, void *);
  \f
+ static GTY(()) rtx savepat;
+ static GTY(()) rtx restpat;
+ static GTY(()) rtx test_reg;
+ static GTY(()) rtx test_mem;
+ static GTY(()) rtx saveinsn;
+ static GTY(()) rtx restinsn;
+ 
+ static int
+ reg_save_code (int reg, enum machine_mode mode)
+ {
+   bool ok;
+   if (cached_reg_save_code[reg][mode])
+      return cached_reg_save_code[reg][mode];
+   if (!HARD_REGNO_MODE_OK (reg, mode))
+      {
+        cached_reg_save_code[reg][mode] = -1;
+        return -1;
+      }
+ 
+   /* Update the register number and modes of the register
+      and memory operand.  */
+   SET_REGNO (test_reg, reg);
+   PUT_MODE (test_reg, mode);
+   PUT_MODE (test_mem, mode);
+ 
+   /* Force re-recognition of the modified insns.  */
+   INSN_CODE (saveinsn) = -1;
+ 
+   cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
+   cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
+ 
+   /* Now extract both insns and see if we can meet their
+      constraints.  */
+   ok = (cached_reg_save_code[reg][mode] != -1
+ 	&& cached_reg_restore_code[reg][mode] != -1);
+   if (ok)
+     {
+       extract_insn (saveinsn);
+       ok = constrain_operands (1);
+       extract_insn (restinsn);
+       ok &= constrain_operands (1);
+     }
+ 
+   if (! ok)
+     {
+       cached_reg_save_code[reg][mode] = -1;
+       cached_reg_restore_code[reg][mode] = -1;
+     }
+   gcc_assert (cached_reg_save_code[reg][mode]);
+   return cached_reg_save_code[reg][mode];
+ }
+ 
+ static int
+ reg_restore_code (int reg, enum machine_mode mode)
+ {
+   if (cached_reg_restore_code[reg][mode])
+      return cached_reg_restore_code[reg][mode];
+   /* polute our cache.  */
+   reg_save_code (reg, mode);
+   return cached_reg_restore_code[reg][mode];
+ }
+ \f
  /* Initialize for caller-save.
  
     Look at all the hard registers that are used by a call and for which
*************** init_caller_save (void)
*** 113,122 ****
    int offset;
    rtx address;
    int i, j;
-   enum machine_mode mode;
-   rtx savepat, restpat;
-   rtx test_reg, test_mem;
-   rtx saveinsn, restinsn;
  
    /* First find all the registers that we need to deal with and all
       the modes that they can have.  If we can't find a mode to use,
--- 176,181 ----
*************** init_caller_save (void)
*** 194,244 ****
    restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0);
  
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-     for (mode = 0 ; mode < MAX_MACHINE_MODE; mode++)
-       if (HARD_REGNO_MODE_OK (i, mode))
- 	{
- 	  int ok;
- 
- 	  /* Update the register number and modes of the register
- 	     and memory operand.  */
- 	  SET_REGNO (test_reg, i);
- 	  PUT_MODE (test_reg, mode);
- 	  PUT_MODE (test_mem, mode);
- 
- 	  /* Force re-recognition of the modified insns.  */
- 	  INSN_CODE (saveinsn) = -1;
- 	  INSN_CODE (restinsn) = -1;
- 
- 	  reg_save_code[i][mode] = recog_memoized (saveinsn);
- 	  reg_restore_code[i][mode] = recog_memoized (restinsn);
- 
- 	  /* Now extract both insns and see if we can meet their
- 	     constraints.  */
- 	  ok = (reg_save_code[i][mode] != -1
- 		&& reg_restore_code[i][mode] != -1);
- 	  if (ok)
- 	    {
- 	      extract_insn (saveinsn);
- 	      ok = constrain_operands (1);
- 	      extract_insn (restinsn);
- 	      ok &= constrain_operands (1);
- 	    }
- 
- 	  if (! ok)
- 	    {
- 	      reg_save_code[i][mode] = -1;
- 	      reg_restore_code[i][mode] = -1;
- 	    }
- 	}
-       else
- 	{
- 	  reg_save_code[i][mode] = -1;
- 	  reg_restore_code[i][mode] = -1;
- 	}
- 
-   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      for (j = 1; j <= MOVE_MAX_WORDS; j++)
!       if (reg_save_code [i][regno_save_mode[i][j]] == -1)
  	{
  	  regno_save_mode[i][j] = VOIDmode;
  	  if (j == 1)
--- 253,260 ----
    restinsn = gen_rtx_INSN (VOIDmode, 0, 0, 0, 0, 0, restpat, -1, 0);
  
    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      for (j = 1; j <= MOVE_MAX_WORDS; j++)
!       if (reg_save_code (i,regno_save_mode[i][j]) == -1)
  	{
  	  regno_save_mode[i][j] = VOIDmode;
  	  if (j == 1)
*************** insert_restore (struct insn_chain *chain
*** 688,694 ****
    pat = gen_rtx_SET (VOIDmode,
  		     gen_rtx_REG (GET_MODE (mem),
  				  regno), mem);
!   code = reg_restore_code[regno][GET_MODE (mem)];
    new = insert_one_insn (chain, before_p, code, pat);
  
    /* Clear status for all registers we restored.  */
--- 704,710 ----
    pat = gen_rtx_SET (VOIDmode,
  		     gen_rtx_REG (GET_MODE (mem),
  				  regno), mem);
!   code = reg_restore_code(regno, GET_MODE (mem));
    new = insert_one_insn (chain, before_p, code, pat);
  
    /* Clear status for all registers we restored.  */
*************** insert_save (struct insn_chain *chain, i
*** 760,766 ****
    pat = gen_rtx_SET (VOIDmode, mem,
  		     gen_rtx_REG (GET_MODE (mem),
  				  regno));
!   code = reg_save_code[regno][GET_MODE (mem)];
    new = insert_one_insn (chain, before_p, code, pat);
  
    /* Set hard_regs_saved and dead_or_set for all the registers we saved.  */
--- 776,782 ----
    pat = gen_rtx_SET (VOIDmode, mem,
  		     gen_rtx_REG (GET_MODE (mem),
  				  regno));
!   code = reg_save_code(regno, GET_MODE (mem));
    new = insert_one_insn (chain, before_p, code, pat);
  
    /* Set hard_regs_saved and dead_or_set for all the registers we saved.  */
*************** insert_one_insn (struct insn_chain *chai
*** 861,863 ****
--- 877,880 ----
    INSN_CODE (new->insn) = code;
    return new;
  }
+ #include "gt-caller-save.h"
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 126800)
+++ Makefile.in	(working copy)
@@ -2700,7 +2700,8 @@ postreload-gcse.o : postreload-gcse.c $(
    $(PARAMS_H) $(TIMEVAR_H) tree-pass.h $(REAL_H) $(DBGCNT_H)
 caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
-   addresses.h $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H) $(DF_H)
+   addresses.h $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H) $(DF_H) \
+   gt-caller-save.h
 bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \
    $(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \
    $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) tree-pass.h toplev.h $(DF_H)
@@ -3039,7 +3040,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/co
   $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
   $(srcdir)/ipa-reference.h $(srcdir)/output.h $(srcdir)/cfgloop.h \
   $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/cgraph.h \
-  $(srcdir)/reload.h \
+  $(srcdir)/reload.h $(srcdir)/caller-save.c \
   $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
   $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c $(srcdir)/matrix-reorg.c \
   $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \

             reply	other threads:[~2007-07-24  5:06 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-24  6:51 Jan Hubicka [this message]
2007-07-24 12:57 ` Diego Novillo
2007-07-24 15:01   ` Daniel Jacobowitz
2007-07-24 15:09     ` Diego Novillo
2007-08-07 14:30 ` Rask Ingemann Lambertsen

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=20070724050556.GD10270@kam.mff.cuni.cz \
    --to=jh@suse.cz \
    --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).