forked from Imagelibrary/binutils-gdb
Reduce rs_align_code memory for small alignments
On x86, MAX_MEM_FOR_RS_ALIGN_CODE is 35, when the most common
alignment is 2**3 or 2**4, where the max memory required for the
alignment nops is 7 and 15 bytes respectively. So there is some
memory wasted since commit 83d94ae428. It's not a large amount,
especially considering that frag overhead on x86_46 is 144 bytes,
but even so I'd rather not be blamed for increasing gas memory usage.
So to reduce the memory we'd like to take the alignment into
consideration when initialising an rs_align_code frag. The only
difficulty here is start_bundle making an rs_align_code frag with an
alignment of zero initially, then later increasing the alignment. We
change that to use the bundle alignment when setting up the frag. I
think that is sufficient as bundle_align_p2 can't change in the middle
of a start_bundle/finish_bundle sequence.
I haven't modified any targets other than x86 in this patch. Most
won't benefit much due to using fairly small MAX_MEM_FOR_RS_ALIGN_CODE.
* read.c (start_bundle): Create rs_align_code frag with
bundle_align_p2 alignment, then set to zero alignment.
(finish_bundle): Adjust comment.
* frags.c (MAX_MEM_FOR_RS_ALIGN_CODE): Pass p2align and max
to macro.
* config/tc-i386.h (HANDLE_ALIGN): Assert that max_bytes is
sufficient for nop padding.
(max_mem_for_rs_align_code): New inline function.
(MAX_MEM_FOR_RS_ALIGN_CODE): Use it.
* config/tc-aarch64.h: Adjust MAX_MEM_FOR_RS_ALIGN_CODE.
* config/tc-alpha.h: Likewise.
* config/tc-arc.h: Likewise.
* config/tc-arm.h: Likewise.
* config/tc-epiphany.h: Likewise.
* config/tc-frv.h: Likewise.
* config/tc-ia64.h: Likewise.
* config/tc-kvx.h: Likewise.
* config/tc-loongarch.h: Likewise.
* config/tc-m32r.h: Likewise.
* config/tc-metag.h: Likewise.
* config/tc-mips.h: Likewise.
* config/tc-nds32.h: Likewise.
* config/tc-ppc.h: Likewise.
* config/tc-riscv.h: Likewise.
* config/tc-rl78.h: Likewise.
* config/tc-rx.h: Likewise.
* config/tc-score.h: Likewise.
* config/tc-sh.h: Likewise.
* config/tc-sparc.h: Likewise.
* config/tc-spu.h: Likewise.
* config/tc-tilegx.h: Likewise.
* config/tc-tilepro.h: Likewise.
* config/tc-visium.h: Likewise.
* config/tc-xtensa.h: Likewise.
This commit is contained in:
@@ -181,7 +181,7 @@ struct aarch64_frag_type
|
||||
#define HANDLE_ALIGN(sec, fragp) aarch64_handle_align (fragp)
|
||||
/* Max space for a rs_align_code fragment is 3 unaligned bytes
|
||||
(fr_fix) plus 4 bytes to contain the repeating NOP (fr_var). */
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
|
||||
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
||||
if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg)) \
|
||||
|
||||
@@ -111,7 +111,7 @@ extern void alpha_cons_align (int);
|
||||
#define HANDLE_ALIGN(sec, fragp) alpha_handle_align (fragp)
|
||||
extern void alpha_handle_align (struct frag *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 8)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4 + 8)
|
||||
|
||||
#ifdef OBJ_ECOFF
|
||||
#define tc_frob_file_before_adjust() alpha_frob_file_before_adjust ()
|
||||
|
||||
@@ -106,7 +106,7 @@ extern const char *arc_target_format;
|
||||
/* [ ] is index operator. */
|
||||
#define NEED_INDEX_OPERATOR
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1+2)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2)
|
||||
|
||||
/* HANDLE_ALIGN called after all the assembly has been done,
|
||||
so we can fill in all the rs_align_code type frags with
|
||||
|
||||
@@ -228,7 +228,7 @@ arm_min (int am_p1, int am_p2)
|
||||
#define TC_FRAG_INIT(fragp, max_bytes) arm_init_frag (fragp, max_bytes)
|
||||
#define TC_ALIGN_ZERO_IS_DEFAULT 1
|
||||
#define HANDLE_ALIGN(sec, fragp) arm_handle_align (fragp)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
/* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section(). */
|
||||
#ifndef TE_PE
|
||||
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \
|
||||
|
||||
@@ -74,7 +74,7 @@ extern int epiphany_cgen_parse_fix_exp (int, expressionS *);
|
||||
|
||||
#define HANDLE_ALIGN(s, f) epiphany_handle_align (f)
|
||||
extern void epiphany_handle_align (fragS *);
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2)
|
||||
|
||||
#define TARGET_FORMAT "elf32-epiphany"
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ extern void frv_frob_file (void);
|
||||
code actually happens to run, but this is probably too much effort
|
||||
for little gain. This code is not meant to be run anyway, so just
|
||||
emit nops. */
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
#define HANDLE_ALIGN(SEC, FRAGP) do \
|
||||
if ((FRAGP)->fr_type == rs_align_code) \
|
||||
{ \
|
||||
|
||||
@@ -376,21 +376,43 @@ extern void i386_generate_nops (fragS *, char *, offsetT, int);
|
||||
#define md_generate_nops(frag, where, amount, control) \
|
||||
i386_generate_nops ((frag), (where), (amount), (control))
|
||||
|
||||
#define HANDLE_ALIGN(sec, fragP) \
|
||||
#define HANDLE_ALIGN(sec, fragP) \
|
||||
if (fragP->fr_type == rs_align_code) \
|
||||
{ \
|
||||
offsetT __count = (fragP->fr_next->fr_address \
|
||||
- fragP->fr_address \
|
||||
- fragP->fr_fix); \
|
||||
if (__count > 0) \
|
||||
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
|
||||
__count, 0); \
|
||||
{ \
|
||||
know (fragP->tc_frag_data.max_bytes >= (valueT) __count \
|
||||
|| (fragP->tc_frag_data.max_bytes \
|
||||
>= MAX_MEM_FOR_RS_ALIGN_CODE (fragP->fr_offset, \
|
||||
fragP->fr_subtype))); \
|
||||
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
|
||||
__count, 0); \
|
||||
} \
|
||||
}
|
||||
/* Possible plain nop, branch, twice largest nop less 1.
|
||||
Yes, the branch might be one byte longer in CODE_16BIT but then the
|
||||
largest nop is smaller. */
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 5 + 2 * 15 - 1)
|
||||
#define MAX_MEM_FOR_RS_SPACE_NOP MAX_MEM_FOR_RS_ALIGN_CODE
|
||||
#define MAX_MEM_FOR_RS_SPACE_NOP (1 + 5 + 2 * 15 - 1)
|
||||
|
||||
static inline unsigned int
|
||||
max_mem_for_rs_align_code (unsigned int p2align, unsigned int max)
|
||||
{
|
||||
unsigned int bytes = 1;
|
||||
if (p2align != 0)
|
||||
{
|
||||
bytes = MAX_MEM_FOR_RS_SPACE_NOP;
|
||||
if (bytes > (1ull << p2align) - 1)
|
||||
bytes = (1ull << p2align) - 1;
|
||||
if (max != 0 && bytes > max)
|
||||
bytes = max;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) \
|
||||
max_mem_for_rs_align_code (p2align, max)
|
||||
|
||||
/* We want .cfi_* pseudo-ops for generating unwind info. */
|
||||
#define TARGET_USE_CFIPOP 1
|
||||
|
||||
@@ -176,7 +176,7 @@ void ia64_vms_note (void);
|
||||
as_bad_where ((FRAGP)->fr_file, (FRAGP)->fr_line, \
|
||||
_("instruction address is not a multiple of 16"));
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (15 + 16)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (15 + 16)
|
||||
|
||||
#define WORKING_DOT_WORD /* don't do broken word processing for now */
|
||||
|
||||
|
||||
@@ -297,7 +297,7 @@ extern void kvx_cons_fix_new (fragS *f, int where, int nbytes,
|
||||
/* Enable special handling for the alignment directive. */
|
||||
extern void kvx_handle_align (fragS *);
|
||||
#define HANDLE_ALIGN(s, f) kvx_handle_align (f)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 12 + 16)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 12 + 16)
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ extern void loongarch_pre_output_hook (void);
|
||||
|
||||
#define HANDLE_ALIGN(sec, fragp) loongarch_handle_align (fragp)
|
||||
extern void loongarch_handle_align (struct frag *);
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
|
||||
#define elf_tc_final_processing loongarch_elf_final_processing
|
||||
extern void loongarch_elf_final_processing (void);
|
||||
|
||||
@@ -65,7 +65,7 @@ extern long m32r_relax_frag (segT, fragS *, long);
|
||||
extern void m32r_handle_align (fragS *);
|
||||
#define HANDLE_ALIGN(s, f) m32r_handle_align (f)
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2 + 4)
|
||||
|
||||
/* Values passed to md_apply_fix don't include the symbol value. */
|
||||
#define MD_APPLY_SYM_VALUE(FIX) 0
|
||||
|
||||
@@ -52,7 +52,7 @@ extern int metag_force_relocation (struct fix *);
|
||||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
||||
#define MD_PCREL_FROM_SECTION(FIX, SEC) md_pcrel_from_section (FIX, SEC)
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
#define HANDLE_ALIGN(sec, fragp) metag_handle_align (fragp)
|
||||
extern void metag_handle_align (struct frag *);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ extern char mips_nop_opcode (void);
|
||||
extern void mips_handle_align (struct frag *);
|
||||
#define HANDLE_ALIGN(sec, fragp) mips_handle_align (fragp)
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
|
||||
struct insn_label_list;
|
||||
struct mips_segment_info {
|
||||
|
||||
@@ -112,7 +112,7 @@ extern void tc_nds32_frame_initial_instructions (void);
|
||||
#define GAS_SORT_RELOCS 1
|
||||
/* Values passed to md_apply_fix don't include the symbol value. */
|
||||
#define MD_APPLY_SYM_VALUE(FIX) 0
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2 + 4)
|
||||
#define HANDLE_ALIGN(s, f) nds32_handle_align (f)
|
||||
#undef DIFF_EXPR_OK /* They should be fixed in linker. */
|
||||
#define md_relax_frag(segment, fragP, stretch) nds32_relax_frag (segment, fragP, stretch)
|
||||
|
||||
@@ -72,7 +72,7 @@ extern const char *ppc_target_format (void);
|
||||
/* We don't need to handle .word strangely. */
|
||||
#define WORKING_DOT_WORD
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE 8
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) 8
|
||||
#define HANDLE_ALIGN(SEC, FRAGP) \
|
||||
if ((FRAGP)->fr_type == rs_align_code) \
|
||||
ppc_handle_align (SEC, FRAGP);
|
||||
|
||||
@@ -64,7 +64,7 @@ extern bool riscv_frag_align_code (int);
|
||||
extern void riscv_handle_align (fragS *);
|
||||
#define HANDLE_ALIGN(s, f) riscv_handle_align (f)
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
|
||||
/* The ISA of the target may change based on command-line arguments. */
|
||||
#define TARGET_FORMAT riscv_target_format ()
|
||||
|
||||
@@ -75,7 +75,7 @@ extern void rl78_cons_fix_new (fragS *, int, int, expressionS *);
|
||||
#define RELOC_EXPANSION_POSSIBLE 1
|
||||
#define MAX_RELOC_EXPANSION 8
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE 8
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) 8
|
||||
#define HANDLE_ALIGN(SEC, FRAG) rl78_handle_align (FRAG)
|
||||
extern void rl78_handle_align (fragS *);
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ extern void rx_cons_fix_new (fragS *, int, int, expressionS *,
|
||||
goto around; \
|
||||
}
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE 8
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) 8
|
||||
#define HANDLE_ALIGN(SEC, FRAG) rx_handle_align (FRAG)
|
||||
extern void rx_handle_align (fragS *);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define DIFF_EXPR_OK
|
||||
#define RELOC_EXPANSION_POSSIBLE
|
||||
#define MAX_RELOC_EXPANSION 2
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
|
||||
|
||||
#define md_undefined_symbol(name) NULL
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ extern int sh_optimize_expr (expressionS *, operatorT, expressionS *);
|
||||
#define HANDLE_ALIGN(sec, frag) sh_handle_align (frag)
|
||||
extern void sh_handle_align (fragS *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2)
|
||||
|
||||
/* We need to force out some relocations when relaxing. */
|
||||
#define TC_FORCE_RELOCATION(fix) sh_force_relocation (fix)
|
||||
|
||||
@@ -78,7 +78,7 @@ extern void sparc_cons_align (int);
|
||||
#define HANDLE_ALIGN(sec, fragp) sparc_handle_align (fragp)
|
||||
extern void sparc_handle_align (struct frag *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 4)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4 + 4)
|
||||
|
||||
#define DIFF_EXPR_OK /* foo-. gets turned into PC relative relocs */
|
||||
|
||||
|
||||
@@ -104,6 +104,6 @@ extern symbolS *section_symbol (asection *);
|
||||
extern void spu_handle_align (fragS *);
|
||||
#define HANDLE_ALIGN(sec, frag) spu_handle_align (frag)
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (7 + 8)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (7 + 8)
|
||||
|
||||
#endif /* TC_SPU */
|
||||
|
||||
@@ -42,7 +42,7 @@ extern const char * tilegx_target_format (void);
|
||||
#define HANDLE_ALIGN(sec, fragp) tilegx_handle_align (fragp)
|
||||
extern void tilegx_handle_align (struct frag *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (7 + 8)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (7 + 8)
|
||||
|
||||
struct tilegx_operand;
|
||||
#define TC_FIX_TYPE const struct tilegx_operand *
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#define HANDLE_ALIGN(sec, fragp) tilepro_handle_align (fragp)
|
||||
extern void tilepro_handle_align (struct frag *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (7 + 8)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (7 + 8)
|
||||
|
||||
struct tilepro_operand;
|
||||
#define TC_FIX_TYPE const struct tilepro_operand *
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
#define tc_fix_adjustable(FIXP) visium_fix_adjustable (FIXP)
|
||||
extern bool visium_fix_adjustable (struct fix *);
|
||||
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (4 + 1)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (4 + 1)
|
||||
#define HANDLE_ALIGN(SEC, FRAGP) \
|
||||
if ((FRAGP)->fr_type == rs_align_code) \
|
||||
visium_handle_align (FRAGP);
|
||||
|
||||
@@ -379,7 +379,7 @@ extern void xtensa_init (int, char **);
|
||||
#define DATA_SECTION_NAME xtensa_section_rename (".data")
|
||||
#define BSS_SECTION_NAME xtensa_section_rename (".bss")
|
||||
#define HANDLE_ALIGN(sec, fragP) xtensa_handle_align (fragP)
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE 1
|
||||
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) 1
|
||||
|
||||
|
||||
/* The renumber_section function must be mapped over all the sections
|
||||
|
||||
@@ -359,7 +359,7 @@ frag_align_pattern (int alignment, const char *fill_pattern,
|
||||
the alignment code. Needs to be large enough to hold any fixed size
|
||||
prologue plus the replicating portion. */
|
||||
#ifndef MAX_MEM_FOR_RS_ALIGN_CODE
|
||||
# define MAX_MEM_FOR_RS_ALIGN_CODE 1
|
||||
# define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) 1
|
||||
#endif
|
||||
|
||||
void
|
||||
@@ -367,7 +367,7 @@ frag_align_code (int alignment, int max)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE, 1,
|
||||
p = frag_var (rs_align_code, MAX_MEM_FOR_RS_ALIGN_CODE (alignment, max), 1,
|
||||
(relax_substateT) max, (symbolS *) 0,
|
||||
(offsetT) alignment, (char *) 0);
|
||||
*p = NOP_OPCODE;
|
||||
|
||||
11
gas/read.c
11
gas/read.c
@@ -667,13 +667,16 @@ start_bundle (void)
|
||||
{
|
||||
fragS *frag = frag_now;
|
||||
|
||||
frag_align_code (0, 0);
|
||||
frag_align_code (bundle_align_p2, 0);
|
||||
|
||||
while (frag->fr_type != rs_align_code)
|
||||
frag = frag->fr_next;
|
||||
|
||||
gas_assert (frag != frag_now);
|
||||
|
||||
/* Set initial alignment to zero. */
|
||||
frag->fr_offset = 0;
|
||||
|
||||
return frag;
|
||||
}
|
||||
|
||||
@@ -720,9 +723,9 @@ finish_bundle (fragS *frag, unsigned int size)
|
||||
|
||||
if (size > 1)
|
||||
{
|
||||
/* If there is more than a single byte, then we need to set up the
|
||||
alignment frag. Otherwise we leave it at its initial state from
|
||||
calling frag_align_code (0, 0), so that it does nothing. */
|
||||
/* If there is more than a single byte, then we need to set up
|
||||
the alignment frag. Otherwise we leave it at its initial
|
||||
state with zero alignment so that it does nothing. */
|
||||
frag->fr_offset = bundle_align_p2;
|
||||
frag->fr_subtype = size - 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user