From patchwork Fri Jul 6 20:12:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [lra] patch for lo_sum support From: Vladimir Makarov X-Patchwork-Id: 169536 Message-Id: <4FF7469F.4010908@redhat.com> To: GCC Patches Date: Fri, 06 Jul 2012 16:12:15 -0400 Working on LRA regression on ppc after the merge, I found that lo_sum support improves code size significantly. Here the patch to support lo_sum. The patch was successfully bootstrapped on x86/x86-64 and ppc. Committed as rev. 189333. 2012-07-05 Vladimir Makarov * lra-constraints.c (extract_loc_address_regs): Process LO_SUM. Remove assert. (process_address): Try LO_SUM. * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Permit some toc references for LRA. Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 189273) +++ lra-constraints.c (working copy) @@ -371,6 +371,7 @@ extract_loc_address_regs (bool top_p, en return; case PLUS: + case LO_SUM: /* When we have an address that is a sum, we must determine whether registers are "base" or "index" regs. If there is a sum of two registers, we must choose one to be the @@ -399,11 +400,10 @@ extract_loc_address_regs (bool top_p, en /* If this machine only allows one register per address, it must be in the first operand. */ - if (MAX_REGS_PER_ADDRESS == 1) + if (MAX_REGS_PER_ADDRESS == 1 || code == LO_SUM) { - extract_loc_address_regs (false, mode, as, arg0_loc, false, PLUS, + extract_loc_address_regs (false, mode, as, arg0_loc, false, code, code1, modify_p, ad); - lra_assert (CONSTANT_P (arg1)); /* It should be a displacement. */ ad->disp_loc = arg1_loc; } /* If index and base registers are the same on this machine, @@ -2600,12 +2600,41 @@ process_address (int nop, rtx *before, r { if (ad.index_reg_loc == NULL) { - /* disp => new_base */ + int code = -1; enum reg_class cl = base_reg_class (mode, as, SCRATCH, SCRATCH); new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, "disp"); - lra_emit_move (new_reg, *ad.disp_loc); - *ad.disp_loc = new_reg; +#ifdef HAVE_lo_sum + { + rtx insn; + rtx last = get_last_insn (); + + /* disp => lo_sum (new_base, disp) */ + insn = emit_insn (gen_rtx_SET + (VOIDmode, new_reg, + gen_rtx_HIGH (Pmode, copy_rtx (*ad.disp_loc)))); + code = recog_memoized (insn); + if (code >= 0) + { + rtx save = *ad.disp_loc; + + *ad.disp_loc = gen_rtx_LO_SUM (Pmode, new_reg, *ad.disp_loc); + if (! valid_address_p (mode, *ad.disp_loc, as)) + { + *ad.disp_loc = save; + code = -1; + } + } + if (code < 0) + delete_insns_since (last); + } +#endif + if (code < 0) + { + /* disp => new_base */ + lra_emit_move (new_reg, *ad.disp_loc); + *ad.disp_loc = new_reg; + } } else { Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 189273) +++ config/rs6000/rs6000.c (working copy) @@ -5378,9 +5378,13 @@ legitimate_lo_sum_address_p (enum machin if (TARGET_ELF || TARGET_MACHO) { + bool toc_ok_p; + if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic) return false; - if (TARGET_TOC) + toc_ok_p = (lra_in_progress && TARGET_CMODEL != CMODEL_SMALL + && small_toc_ref (x, VOIDmode)); + if (TARGET_TOC && ! toc_ok_p) return false; if (GET_MODE_NUNITS (mode) != 1) return false; @@ -5390,7 +5394,7 @@ legitimate_lo_sum_address_p (enum machin && (mode == DFmode || mode == DDmode)))) return false; - return CONSTANT_P (x); + return CONSTANT_P (x) || toc_ok_p; } return false;