This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: PATCH: PR gas/12049: Unnecessary relaxation


On Mon, Oct 18, 2010 at 06:25:41AM -0700, H.J. Lu wrote:
> On Sun, Oct 17, 2010 at 10:32 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> > On Sun, Oct 17, 2010 at 8:35 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> >> On Sun, Oct 17, 2010 at 6:32 PM, Alan Modra <amodra@gmail.com> wrote:
> >>> A possible fix for your testcase is to allow relax_frag to shrink
> >>> rs_machine_dependent frags, rather than just grow them as it does at
> >>> the moment.
> >>>
> >> I tried it and it doesn't work. The problem is

You didn't try very hard.  This patch of course needs to touch all the
other md_relax_tables too.

Index: gas/as.h
===================================================================
RCS file: /cvs/src/src/gas/as.h,v
retrieving revision 1.68
diff -u -p -r1.68 as.h
--- gas/as.h	3 Jul 2010 20:52:24 -0000	1.68
+++ gas/as.h	18 Oct 2010 13:29:10 -0000
@@ -323,6 +323,8 @@ struct relax_type
 
   /* Next longer relax-state.  0 means there is no 'next' relax-state.  */
   relax_substateT rlx_more;
+  /* Next smaller relax-state.  -1 means there is no 'next' relax-state.  */
+  relax_substateT rlx_less;
 };
 
 typedef struct relax_type relax_typeS;
Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.132
diff -u -p -r1.132 write.c
--- gas/write.c	3 Jul 2010 20:52:24 -0000	1.132
+++ gas/write.c	18 Oct 2010 13:27:37 -0000
@@ -2175,30 +2175,56 @@ relax_frag (segT segment, fragS *fragP, 
   if (aim < 0)
     {
       /* Look backwards.  */
-      for (next_state = this_type->rlx_more; next_state;)
-	if (aim >= this_type->rlx_backward)
-	  next_state = 0;
-	else
-	  {
-	    /* Grow to next state.  */
-	    this_state = next_state;
-	    this_type = table + this_state;
-	    next_state = this_type->rlx_more;
-	  }
+      if (this_type->rlx_backward == 0 || aim >= this_type->rlx_backward)
+	{
+	  /* It fits, maybe the previous state does also?  */
+	  while ((next_state = this_type->rlx_less) != (relax_substateT) -1)
+	    if (aim >= table[next_state].rlx_backward)
+	      {
+		this_state = next_state;
+		this_type = table + this_state;
+	      }
+	    else
+	      break;
+	}
+      else
+	{
+	  while ((next_state = this_type->rlx_more) != 0)
+	    {
+	      /* Grow to next state.  */
+	      this_state = next_state;
+	      this_type = table + this_state;
+	      if (aim >= this_type->rlx_backward)
+		break;
+	    }
+	}
     }
   else
     {
       /* Look forwards.  */
-      for (next_state = this_type->rlx_more; next_state;)
-	if (aim <= this_type->rlx_forward)
-	  next_state = 0;
-	else
-	  {
-	    /* Grow to next state.  */
-	    this_state = next_state;
-	    this_type = table + this_state;
-	    next_state = this_type->rlx_more;
-	  }
+      if (this_type->rlx_forward == 0 || aim <= this_type->rlx_forward)
+	{
+	  /* It fits, maybe the previous state does also?  */
+	  while ((next_state = this_type->rlx_less) != (relax_substateT) -1)
+	    if (aim <= table[next_state].rlx_forward)
+	      {
+		this_state = next_state;
+		this_type = table + this_state;
+	      }
+	    else
+	      break;
+	}
+      else
+	{
+	  while ((next_state = this_type->rlx_more) != 0)
+	    {
+	      /* Grow to next state.  */
+	      this_state = next_state;
+	      this_type = table + this_state;
+	      if (aim <= this_type->rlx_forward)
+		break;
+	    }
+	}
     }
 
   growth = this_type->rlx_length - start_type->rlx_length;
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.450
diff -u -p -r1.450 tc-i386.c
--- gas/config/tc-i386.c	16 Sep 2010 23:55:10 -0000	1.450
+++ gas/config/tc-i386.c	18 Oct 2010 13:27:39 -0000
@@ -529,37 +529,38 @@ const relax_typeS md_relax_table[] =
      1) most positive reach of this state,
      2) most negative reach of this state,
      3) how many bytes this mode will have in the variable part of the frag
-     4) which index into the table to try if we can't fit into this one.  */
+     4) which index into the table to try if we can't fit into this one.
+     5) previous smaller index.  */
 
   /* UNCOND_JUMP states.  */
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG)},
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16)},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG), -1},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (UNCOND_JUMP, BIG16), -1},
   /* dword jmp adds 4 bytes to frag:
      0 extra opcode bytes, 4 displacement bytes.  */
-  {0, 0, 4, 0},
+  {0, 0, 4, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL)},
   /* word jmp adds 2 byte2 to frag:
      0 extra opcode bytes, 2 displacement bytes.  */
-  {0, 0, 2, 0},
+  {0, 0, 2, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, SMALL16)},
 
   /* COND_JUMP states.  */
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG)},
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16)},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG), -1},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP, BIG16), -1},
   /* dword conditionals adds 5 bytes to frag:
      1 extra opcode byte, 4 displacement bytes.  */
-  {0, 0, 5, 0},
+  {0, 0, 5, 0, ENCODE_RELAX_STATE (COND_JUMP, SMALL)},
   /* word conditionals add 3 bytes to frag:
      1 extra opcode byte, 2 displacement bytes.  */
-  {0, 0, 3, 0},
+  {0, 0, 3, 0, ENCODE_RELAX_STATE (COND_JUMP, SMALL16)},
 
   /* COND_JUMP86 states.  */
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG)},
-  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16)},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG), -1},
+  {127 + 1, -128 + 1, 1, ENCODE_RELAX_STATE (COND_JUMP86, BIG16), -1},
   /* dword conditionals adds 5 bytes to frag:
      1 extra opcode byte, 4 displacement bytes.  */
-  {0, 0, 5, 0},
+  {0, 0, 5, 0, ENCODE_RELAX_STATE (COND_JUMP86, SMALL)},
   /* word conditionals add 4 bytes to frag:
      1 displacement byte and a 3 byte long branch insn.  */
-  {0, 0, 4, 0}
+  {0, 0, 4, 0, ENCODE_RELAX_STATE (COND_JUMP86, SMALL16)}
 };
 
 static const arch_entry cpu_arch[] =

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]