From patchwork Thu Jun 30 14:48:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Schmidt X-Patchwork-Id: 102766 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 55B8BB6F00 for ; Fri, 1 Jul 2011 00:48:58 +1000 (EST) Received: (qmail 10619 invoked by alias); 30 Jun 2011 14:48:57 -0000 Received: (qmail 10609 invoked by uid 22791); 30 Jun 2011 14:48:55 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL, BAYES_00, TW_FW, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e9.ny.us.ibm.com (HELO e9.ny.us.ibm.com) (32.97.182.139) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 30 Jun 2011 14:48:41 +0000 Received: from d01relay03.pok.ibm.com (d01relay03.pok.ibm.com [9.56.227.235]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p5UEH7Ew030843 for ; Thu, 30 Jun 2011 10:17:07 -0400 Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216]) by d01relay03.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p5UEmSB1163118 for ; Thu, 30 Jun 2011 10:48:28 -0400 Received: from d01av02.pok.ibm.com (loopback [127.0.0.1]) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p5UEmS4w009831 for ; Thu, 30 Jun 2011 11:48:28 -0300 Received: from [9.10.86.63] (ibm-57p4op1vszq.rchland.ibm.com [9.10.86.63] (may be forged)) by d01av02.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p5UEmPed009699; Thu, 30 Jun 2011 11:48:25 -0300 Subject: [PATCH] Address lowering [2/3] Constrain forward propagator From: "William J. Schmidt" To: gcc-patches@gcc.gnu.org Cc: richard.guenther@gmail.com Date: Thu, 30 Jun 2011 09:48:25 -0500 Message-ID: <1309445305.26980.56.camel@oc2474580526.ibm.com> Mime-Version: 1.0 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 Here is the second patch related to address lowering. It looks for a specific pattern where replacement of a reg in a mem rtx is not profitable, and constrains it from occurring. Thanks, Bill 2011-06-30 Bill Schmidt * fwprop.c (fwprop_bb_aux_d): New struct. (record_mem_plus_reg): New. (record_mem_plus_regs): New. (single_def_use_enter_block): Allocate storage; add call to record_mem_plus_regs; add dump logic. (build_single_def_use_links): Allocate storage. (locally_poor_mem_replacement): New. (forward_propagate_and_simplify): Add call to locally_poor_mem_replacement. (fwprop_done): Free storage. Index: gcc/fwprop.c =================================================================== --- gcc/fwprop.c (revision 175664) +++ gcc/fwprop.c (working copy) @@ -131,6 +131,15 @@ static VEC(df_ref,heap) *reg_defs_stack; static bitmap local_md; static bitmap local_lr; +/* Auxiliary information for each block for this pass. */ +typedef struct GTY(()) fwprop_bb_aux_d +{ + /* Registers appearing in (mem (plus (reg ... patterns in this block. */ + bitmap mem_plus_regs; +} fwprop_bb_aux, *fwprop_bb_aux_t; + +#define MEM_PLUS_REGS(BB) ((fwprop_bb_aux_t) ((BB)->aux))->mem_plus_regs + /* Return the only def in USE's use-def chain, or NULL if there is more than one def in the chain. */ @@ -212,7 +221,43 @@ process_uses (df_ref *use_rec, int top_flag) } +/* Record whether EXPR in block BB is of the form (mem (plus (reg ... */ static void +record_mem_plus_reg (basic_block bb, rtx expr) +{ + rtx addr, reg; + + if (GET_CODE (expr) != MEM) + return; + + addr = XEXP (expr, 0); + if (GET_CODE (addr) != PLUS) + return; + + reg = XEXP (addr, 0); + if (!REG_P (reg)) + return; + + (void)bitmap_set_bit (MEM_PLUS_REGS (bb), REGNO (reg)); +} + + +/* Record whether INSN in block BB contains any patterns of the form + (mem (plus (reg ... */ +static void +record_mem_plus_regs (basic_block bb, rtx insn) +{ + rtx insn_set = single_set (insn); + + if (insn_set) + { + record_mem_plus_reg (bb, SET_DEST (insn_set)); + record_mem_plus_reg (bb, SET_SRC (insn_set)); + } +} + + +static void single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, basic_block bb) { @@ -230,6 +275,8 @@ single_def_use_enter_block (struct dom_walk_data * process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP); process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP); + MEM_PLUS_REGS (bb) = BITMAP_ALLOC (NULL); + /* We don't call df_simulate_initialize_forwards, as it may overestimate the live registers if there are unused artificial defs. We prefer liveness to be underestimated. */ @@ -242,8 +289,15 @@ single_def_use_enter_block (struct dom_walk_data * process_uses (DF_INSN_UID_EQ_USES (uid), 0); process_defs (DF_INSN_UID_DEFS (uid), 0); df_simulate_one_insn_forwards (bb, insn, local_lr); + record_mem_plus_regs (bb, insn); } + if (dump_file) + { + fprintf (dump_file, "mem_plus_regs (%d): ", bb->index); + dump_bitmap (dump_file, MEM_PLUS_REGS (bb)); + } + process_uses (df_get_artificial_uses (bb_index), 0); process_defs (df_get_artificial_defs (bb_index), 0); } @@ -295,6 +349,8 @@ build_single_def_use_links (void) local_md = BITMAP_ALLOC (NULL); local_lr = BITMAP_ALLOC (NULL); + alloc_aux_for_blocks (sizeof (fwprop_bb_aux)); + /* Walk the dominator tree looking for single reaching definitions dominating the uses. This is similar to how SSA form is built. */ walk_data.dom_direction = CDI_DOMINATORS; @@ -1205,6 +1261,69 @@ forward_propagate_asm (df_ref use, rtx def_insn, r return true; } +/* We are proposing to replace a USE of REG in USE_SET. Determine + whether we have a situation where two storage uses of REG occur + in the same block as follows. Each use can be either a memory + store or a memory load. + + ... (mem (reg REG)) + + ... (mem (plus (reg REG) + (...))) + + The problem is that it will look profitable to propagate something + like + + (set (reg REG) + (plus (reg X) + (reg Y))) + + into the first use, but not into the second one. This breaks a + CSE opportunity and raises register pressure by extending the + lifetimes of X and Y. To avoid this, don't propagate into the + first use when this very specific situation arises. */ +static bool +locally_poor_mem_replacement (df_ref use, rtx use_set, rtx reg, rtx def_set) +{ + rtx rhs, addend, mem, base; + unsigned i; + + /* We're only concerned if the RHS of def_set is the sum of two + registers. */ + rhs = SET_SRC (def_set); + + if (GET_CODE (rhs) != PLUS) + return false; + + for (i = 0; i < 2; i++) + { + addend = XEXP (rhs, i); + if (!REG_P (addend)) + return false; + } + + /* The use must have a single SET and be used in addressing. */ + if (!use_set || !DF_REF_REG_MEM_P (use)) + return false; + + if (DF_REF_REG_MEM_STORE_P (use)) + mem = SET_DEST (use_set); + else + mem = SET_SRC (use_set); + + if (GET_CODE (mem) != MEM) + return false; + + /* We are specifically interested in the base address. */ + base = XEXP (mem, 0); + if (reg != base) + return false; + + /* We've found a use of the first form. Check whether uses of the + second form exist in the same block. If found, don't replace. */ + return bitmap_bit_p (MEM_PLUS_REGS (DF_REF_BB (use)), DF_REF_REGNO (use)); +} + /* Try to replace USE with SRC (defined in DEF_INSN) and simplify the result. */ @@ -1268,6 +1387,11 @@ forward_propagate_and_simplify (df_ref use, rtx de return false; } + /* Check for a specific unprofitable propagation into a memory + reference, where the propagation will break a CSE opportunity. */ + if (locally_poor_mem_replacement (use, use_set, reg, def_set)) + return false; + if (asm_use >= 0) return forward_propagate_asm (use, def_insn, def_set, reg); @@ -1398,6 +1522,12 @@ fwprop_init (void) static void fwprop_done (void) { + basic_block bb; + + FOR_EACH_BB (bb) + BITMAP_FREE (MEM_PLUS_REGS (bb)); + free_aux_for_blocks (); + loop_optimizer_finalize (); VEC_free (df_ref, heap, use_def_ref);