This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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