Patchwork [lra] patch for lo_sum support

login
register
mail settings
Submitter Vladimir Makarov
Date July 6, 2012, 8:12 p.m.
Message ID <4FF7469F.4010908@redhat.com>
Download mbox | patch
Permalink /patch/169536/
State New
Headers show

Comments

Vladimir Makarov - July 6, 2012, 8:12 p.m.
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  <vmakarov@redhat.com>

         * 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.

Patch

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;