From patchwork Wed Jun 16 15:58:53 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Kuvyrkov X-Patchwork-Id: 55907 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 3EC77B7D66 for ; Thu, 17 Jun 2010 01:59:09 +1000 (EST) Received: (qmail 21625 invoked by alias); 16 Jun 2010 15:59:07 -0000 Received: (qmail 21616 invoked by uid 22791); 16 Jun 2010 15:59:06 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 16 Jun 2010 15:58:57 +0000 Received: (qmail 22230 invoked from network); 16 Jun 2010 15:58:55 -0000 Received: from unknown (HELO ?172.16.1.24?) (maxim@127.0.0.2) by mail.codesourcery.com with ESMTPA; 16 Jun 2010 15:58:55 -0000 Message-ID: <4C18F4BD.5000906@codesourcery.com> Date: Wed, 16 Jun 2010 19:58:53 +0400 From: Maxim Kuvyrkov User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4 MIME-Version: 1.0 To: Jeff Law , gcc-patches Subject: 0006-GCSE-complex-constants.patch References: <4C18F225.2040509@codesourcery.com> In-Reply-To: <4C18F225.2040509@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Certain architectures (e.g., ARM) cannot easily operate with constants, they need to emit sequences of several instructions to load constants into registers. The common procedure to do this is to emit a (parallel [(set) (clobber (reg1)) ... (clobber (regN))]) instruction which later splits into several instructions using pseudos (regX) to store intermediate values. Currently PRE and hoist do not GCSE constants, and there is a good reason for that, to avoid increasing register pressure; interestingly, symbol_refs are allowed to be GCSE'ed, is this intentional or by accident? In any case, it seems like a good idea to GCSE constants and symbol_refs that need something beyond a simple (set) to get into a register, and not GCSE them otherwise. This patch adds a simple heuristic to gcse.c:want_to_gcse_p() that adjusts preferences for CONST_INTs and SYMBOL_REFs. OK to apply? Thank you, diff --git a/gcc/gcse.c b/gcc/gcse.c index a7c7237..c81d71c 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -431,7 +431,7 @@ static void hash_scan_insn (rtx, struct hash_table_d *); static void hash_scan_set (rtx, rtx, struct hash_table_d *); static void hash_scan_clobber (rtx, rtx, struct hash_table_d *); static void hash_scan_call (rtx, rtx, struct hash_table_d *); -static int want_to_gcse_p (rtx); +static int want_to_gcse_p (rtx, rtx); static bool gcse_constant_p (const_rtx); static int oprs_unchanged_p (const_rtx, const_rtx, int); static int oprs_anticipatable_p (const_rtx, const_rtx); @@ -751,10 +751,10 @@ static basic_block current_bb; /* See whether X, the source of a set, is something we want to consider for - GCSE. */ + GCSE in instruction INSN. */ static int -want_to_gcse_p (rtx x) +want_to_gcse_p (rtx x, rtx insn) { #ifdef STACK_REGS /* On register stack architectures, don't GCSE constants from the @@ -768,13 +768,35 @@ want_to_gcse_p (rtx x) { case REG: case SUBREG: - case CONST_INT: case CONST_DOUBLE: case CONST_FIXED: case CONST_VECTOR: case CALL: return 0; + case CONST_INT: + case SYMBOL_REF: + /* If it takes a PARALLEL to set a constant or a symbol, try to gcse it. + Usually, (clobber (reg)) is the second part of the parallel. + We rely on rematerialization of constants to avoid excessive + register pressure. + + ??? We would also like to GCSE/hoist non-parallel-looking constants + and symbol_refs on architectures which require load from constant + pools to get a constant into register, e.g., ARM. + We do not currently do that because IRA overestimates cost + of allocating a constant to memory, thus unnecessarily increasing + register pressure and causing spills. One side of this problem + is IRA using rtx_costs which are not particularly precise for + constants when optimizing for size. For a good example see + 300.twolf:ucxxo1.c from SPEC2000. + + ??? Should we handle CONST_DOUBLE and CONST_FIXED similarly? + Will rematerialization handle them? */ + if (GET_CODE (PATTERN (insn)) != PARALLEL) + return 0; + /* FALLTHRU */ + default: return can_assign_to_reg_without_clobbers_p (x); } @@ -1328,7 +1350,7 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table) && !REG_P (src) && (table->set_p ? gcse_constant_p (XEXP (note, 0)) - : want_to_gcse_p (XEXP (note, 0)))) + : want_to_gcse_p (XEXP (note, 0), insn))) src = XEXP (note, 0), pat = gen_rtx_SET (VOIDmode, dest, src); /* Only record sets of pseudo-regs in the hash table. */ @@ -1343,7 +1365,7 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table) can't do the same thing at the rtl level. */ && !can_throw_internal (insn) /* Is SET_SRC something we want to gcse? */ - && want_to_gcse_p (src) + && want_to_gcse_p (src, insn) /* Don't CSE a nop. */ && ! set_noop_p (pat) /* Don't GCSE if it has attached REG_EQUIV note. @@ -1404,7 +1426,7 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table_d *table) do that easily for EH edges so disable GCSE on these for now. */ && !can_throw_internal (insn) /* Is SET_DEST something we want to gcse? */ - && want_to_gcse_p (dest) + && want_to_gcse_p (dest, insn) /* Don't CSE a nop. */ && ! set_noop_p (pat) /* Don't GCSE if it has attached REG_EQUIV note.