Skip to content

Commit 5e5f37e

Browse files
committed
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 83d94ae. 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.
1 parent d4de8fe commit 5e5f37e

28 files changed

+61
-36
lines changed

gas/config/tc-aarch64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ struct aarch64_frag_type
181181
#define HANDLE_ALIGN(sec, fragp) aarch64_handle_align (fragp)
182182
/* Max space for a rs_align_code fragment is 3 unaligned bytes
183183
(fr_fix) plus 4 bytes to contain the repeating NOP (fr_var). */
184-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
184+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
185185

186186
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
187187
if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg)) \

gas/config/tc-alpha.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ extern void alpha_cons_align (int);
111111
#define HANDLE_ALIGN(sec, fragp) alpha_handle_align (fragp)
112112
extern void alpha_handle_align (struct frag *);
113113

114-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4 + 8)
114+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4 + 8)
115115

116116
#ifdef OBJ_ECOFF
117117
#define tc_frob_file_before_adjust() alpha_frob_file_before_adjust ()

gas/config/tc-arc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ extern const char *arc_target_format;
106106
/* [ ] is index operator. */
107107
#define NEED_INDEX_OPERATOR
108108

109-
#define MAX_MEM_FOR_RS_ALIGN_CODE (1+2)
109+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2)
110110

111111
/* HANDLE_ALIGN called after all the assembly has been done,
112112
so we can fill in all the rs_align_code type frags with

gas/config/tc-arm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ arm_min (int am_p1, int am_p2)
228228
#define TC_FRAG_INIT(fragp, max_bytes) arm_init_frag (fragp, max_bytes)
229229
#define TC_ALIGN_ZERO_IS_DEFAULT 1
230230
#define HANDLE_ALIGN(sec, fragp) arm_handle_align (fragp)
231-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
231+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
232232
/* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section(). */
233233
#ifndef TE_PE
234234
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) \

gas/config/tc-epiphany.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ extern int epiphany_cgen_parse_fix_exp (int, expressionS *);
7474

7575
#define HANDLE_ALIGN(s, f) epiphany_handle_align (f)
7676
extern void epiphany_handle_align (fragS *);
77-
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
77+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (1 + 2)
7878

7979
#define TARGET_FORMAT "elf32-epiphany"
8080

gas/config/tc-frv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ extern void frv_frob_file (void);
9898
code actually happens to run, but this is probably too much effort
9999
for little gain. This code is not meant to be run anyway, so just
100100
emit nops. */
101-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
101+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
102102
#define HANDLE_ALIGN(SEC, FRAGP) do \
103103
if ((FRAGP)->fr_type == rs_align_code) \
104104
{ \

gas/config/tc-i386.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,21 +376,43 @@ extern void i386_generate_nops (fragS *, char *, offsetT, int);
376376
#define md_generate_nops(frag, where, amount, control) \
377377
i386_generate_nops ((frag), (where), (amount), (control))
378378

379-
#define HANDLE_ALIGN(sec, fragP) \
379+
#define HANDLE_ALIGN(sec, fragP) \
380380
if (fragP->fr_type == rs_align_code) \
381381
{ \
382382
offsetT __count = (fragP->fr_next->fr_address \
383383
- fragP->fr_address \
384384
- fragP->fr_fix); \
385385
if (__count > 0) \
386-
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
387-
__count, 0); \
386+
{ \
387+
know (fragP->tc_frag_data.max_bytes >= (valueT) __count \
388+
|| (fragP->tc_frag_data.max_bytes \
389+
>= MAX_MEM_FOR_RS_ALIGN_CODE (fragP->fr_offset, \
390+
fragP->fr_subtype))); \
391+
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
392+
__count, 0); \
393+
} \
388394
}
389395
/* Possible plain nop, branch, twice largest nop less 1.
390396
Yes, the branch might be one byte longer in CODE_16BIT but then the
391397
largest nop is smaller. */
392-
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 5 + 2 * 15 - 1)
393-
#define MAX_MEM_FOR_RS_SPACE_NOP MAX_MEM_FOR_RS_ALIGN_CODE
398+
#define MAX_MEM_FOR_RS_SPACE_NOP (1 + 5 + 2 * 15 - 1)
399+
400+
static inline unsigned int
401+
max_mem_for_rs_align_code (unsigned int p2align, unsigned int max)
402+
{
403+
unsigned int bytes = 1;
404+
if (p2align != 0)
405+
{
406+
bytes = MAX_MEM_FOR_RS_SPACE_NOP;
407+
if (bytes > (1ull << p2align) - 1)
408+
bytes = (1ull << p2align) - 1;
409+
if (max != 0 && bytes > max)
410+
bytes = max;
411+
}
412+
return bytes;
413+
}
414+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) \
415+
max_mem_for_rs_align_code (p2align, max)
394416

395417
/* We want .cfi_* pseudo-ops for generating unwind info. */
396418
#define TARGET_USE_CFIPOP 1

gas/config/tc-ia64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ void ia64_vms_note (void);
176176
as_bad_where ((FRAGP)->fr_file, (FRAGP)->fr_line, \
177177
_("instruction address is not a multiple of 16"));
178178

179-
#define MAX_MEM_FOR_RS_ALIGN_CODE (15 + 16)
179+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (15 + 16)
180180

181181
#define WORKING_DOT_WORD /* don't do broken word processing for now */
182182

gas/config/tc-kvx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ extern void kvx_cons_fix_new (fragS *f, int where, int nbytes,
297297
/* Enable special handling for the alignment directive. */
298298
extern void kvx_handle_align (fragS *);
299299
#define HANDLE_ALIGN(s, f) kvx_handle_align (f)
300-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 12 + 16)
300+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 12 + 16)
301301

302302
#ifdef OBJ_ELF
303303

gas/config/tc-loongarch.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ extern void loongarch_pre_output_hook (void);
141141

142142
#define HANDLE_ALIGN(sec, fragp) loongarch_handle_align (fragp)
143143
extern void loongarch_handle_align (struct frag *);
144-
#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4)
144+
#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) (3 + 4)
145145

146146
#define elf_tc_final_processing loongarch_elf_final_processing
147147
extern void loongarch_elf_final_processing (void);

0 commit comments

Comments
 (0)