From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15828 invoked by alias); 24 Jul 2007 05:06:04 -0000 Received: (qmail 15820 invoked by uid 22791); 24 Jul 2007 05:06:02 -0000 X-Spam-Check-By: sourceware.org Received: from nikam-dmz.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 24 Jul 2007 05:05:59 +0000 Received: from localhost (camellia.ms.mff.cuni.cz [195.113.18.73]) by nikam.ms.mff.cuni.cz (Postfix) with ESMTP id C79A65B8B9 for ; Tue, 24 Jul 2007 07:05:56 +0200 (CEST) Received: by localhost (Postfix, from userid 16202) id BA6168B74E; Tue, 24 Jul 2007 07:05:56 +0200 (CEST) Date: Tue, 24 Jul 2007 06:51:00 -0000 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Reduce startup cost of compiler (patch 3) Message-ID: <20070724050556.GD10270@kam.mff.cuni.cz> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.9i Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-07/txt/msg01704.txt.bz2 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 *); + 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]; + } + /* 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 \