mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
gas: Pass max_bytes to TC_FRAG_INIT
ommit 3ae729d5a4
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Mar 7 04:18:45 2018 -0800
x86: Rewrite NOP generation for fill and alignment
increased MAX_MEM_FOR_RS_ALIGN_CODE to 4095 which resulted in increase
of assembler time and memory usage by 5 times for inputs with many
.p2align directives, which is typical for LTO output. This patch passes
max_bytes to TC_FRAG_INIT so that MAX_MEM_FOR_RS_ALIGN_CODE can be set
as needed and tracked by backend it so that HANDLE_ALIGN can check the
maximum alignment for each rs_align_code frag. Wall time to assemble
the same cc1plus.s:
before:
423.78user 0.89system 7:05.71elapsed 99%CPU
after:
102.35user 0.27system 1:42.89elapsed 99%CPU
PR gas/24165
* frags.c (frag_var_init): Pass max_chars to TC_FRAG_INIT as
max_bytes.
* config/tc-aarch64.h (TC_FRAG_INIT): Add and pass max_bytes to
aarch64_init_frag.
* /config/tc-arm.h (TC_FRAG_INIT): And and pass max_bytes to
arm_init_frag.
* config/tc-avr.h (TC_FRAG_INIT): And and ignore max_bytes.
* config/tc-ia64.h (TC_FRAG_INIT): Likewise.
* config/tc-mmix.h (TC_FRAG_INIT): Likewise.
* config/tc-nds32.h (TC_FRAG_INIT): Likewise.
* config/tc-ns32k.h (TC_FRAG_INIT): Likewise.
* config/tc-rl78.h (TC_FRAG_INIT): Likewise.
* config/tc-rx.h (TC_FRAG_INIT): Likewise.
* config/tc-score.h (TC_FRAG_INIT): Likewise.
* config/tc-tic54x.h (TC_FRAG_INIT): Likewise.
* config/tc-tic6x.h (TC_FRAG_INIT): Likewise.
* config/tc-xtensa.h (TC_FRAG_INIT): Likewise.
* config/tc-i386.h (MAX_MEM_FOR_RS_ALIGN_CODE): Set to
(alignment ? ((1 << alignment) - 1) : 1)
(i386_tc_frag_data): Add max_bytes.
(TC_FRAG_INIT): Add and track max_bytes.
(HANDLE_ALIGN): Replace MAX_MEM_FOR_RS_ALIGN_CODE with
fragP->tc_frag_data.max_bytes.
* doc/internals.texi: Update TC_FRAG_TYPE with max_bytes.
This commit is contained in:
@@ -1,3 +1,31 @@
|
|||||||
|
2019-02-10 H.J. Lu <hongjiu.lu@intel.com>
|
||||||
|
|
||||||
|
PR gas/24165
|
||||||
|
* frags.c (frag_var_init): Pass max_chars to TC_FRAG_INIT as
|
||||||
|
max_bytes.
|
||||||
|
* config/tc-aarch64.h (TC_FRAG_INIT): Add and pass max_bytes to
|
||||||
|
aarch64_init_frag.
|
||||||
|
* /config/tc-arm.h (TC_FRAG_INIT): And and pass max_bytes to
|
||||||
|
arm_init_frag.
|
||||||
|
* config/tc-avr.h (TC_FRAG_INIT): And and ignore max_bytes.
|
||||||
|
* config/tc-ia64.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-mmix.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-nds32.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-ns32k.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-rl78.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-rx.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-score.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-tic54x.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-tic6x.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-xtensa.h (TC_FRAG_INIT): Likewise.
|
||||||
|
* config/tc-i386.h (MAX_MEM_FOR_RS_ALIGN_CODE): Set to
|
||||||
|
(alignment ? ((1 << alignment) - 1) : 1)
|
||||||
|
(i386_tc_frag_data): Add max_bytes.
|
||||||
|
(TC_FRAG_INIT): Add and track max_bytes.
|
||||||
|
(HANDLE_ALIGN): Replace MAX_MEM_FOR_RS_ALIGN_CODE with
|
||||||
|
fragP->tc_frag_data.max_bytes.
|
||||||
|
* doc/internals.texi: Update TC_FRAG_TYPE with max_bytes.
|
||||||
|
|
||||||
2019-02-08 Jim Wilson <jimw@sifive.com>
|
2019-02-08 Jim Wilson <jimw@sifive.com>
|
||||||
|
|
||||||
* config/tc-riscv.c (validate_riscv_insn) <'C'>: Add 'z' support.
|
* config/tc-riscv.c (validate_riscv_insn) <'C'>: Add 'z' support.
|
||||||
|
|||||||
@@ -173,8 +173,7 @@ struct aarch64_frag_type
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define TC_FRAG_TYPE struct aarch64_frag_type
|
#define TC_FRAG_TYPE struct aarch64_frag_type
|
||||||
/* NOTE: max_chars is a local variable from frag_var / frag_variant. */
|
#define TC_FRAG_INIT(fragp, max_bytes) aarch64_init_frag (fragp, max_bytes)
|
||||||
#define TC_FRAG_INIT(fragp) aarch64_init_frag (fragp, max_chars)
|
|
||||||
#define HANDLE_ALIGN(fragp) aarch64_handle_align (fragp)
|
#define HANDLE_ALIGN(fragp) aarch64_handle_align (fragp)
|
||||||
|
|
||||||
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
|
||||||
|
|||||||
@@ -229,8 +229,7 @@ arm_min (int am_p1, int am_p2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define TC_FRAG_TYPE struct arm_frag_type
|
#define TC_FRAG_TYPE struct arm_frag_type
|
||||||
/* NOTE: max_chars is a local variable from frag_var / frag_variant. */
|
#define TC_FRAG_INIT(fragp, max_bytes) arm_init_frag (fragp, max_bytes)
|
||||||
#define TC_FRAG_INIT(fragp) arm_init_frag (fragp, max_chars)
|
|
||||||
#define TC_ALIGN_ZERO_IS_DEFAULT 1
|
#define TC_ALIGN_ZERO_IS_DEFAULT 1
|
||||||
#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
|
#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
|
||||||
/* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section(). */
|
/* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section(). */
|
||||||
|
|||||||
@@ -243,5 +243,5 @@ struct avr_frag_data
|
|||||||
unsigned int prev_opcode;
|
unsigned int prev_opcode;
|
||||||
};
|
};
|
||||||
#define TC_FRAG_TYPE struct avr_frag_data
|
#define TC_FRAG_TYPE struct avr_frag_data
|
||||||
#define TC_FRAG_INIT(frag) avr_frag_init (frag)
|
#define TC_FRAG_INIT(frag, max_bytes) avr_frag_init (frag)
|
||||||
extern void avr_frag_init (fragS *);
|
extern void avr_frag_init (fragS *);
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ if ((n) \
|
|||||||
goto around; \
|
goto around; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_MEM_FOR_RS_ALIGN_CODE 4095
|
#define MAX_MEM_FOR_RS_ALIGN_CODE (alignment ? ((1 << alignment) - 1) : 1)
|
||||||
|
|
||||||
void i386_print_statistics (FILE *);
|
void i386_print_statistics (FILE *);
|
||||||
#define tc_print_statistics i386_print_statistics
|
#define tc_print_statistics i386_print_statistics
|
||||||
@@ -251,6 +251,7 @@ struct i386_tc_frag_data
|
|||||||
enum processor_type isa;
|
enum processor_type isa;
|
||||||
i386_cpu_flags isa_flags;
|
i386_cpu_flags isa_flags;
|
||||||
enum processor_type tune;
|
enum processor_type tune;
|
||||||
|
unsigned int max_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* We need to emit the right NOP pattern in .align frags. This is
|
/* We need to emit the right NOP pattern in .align frags. This is
|
||||||
@@ -258,12 +259,13 @@ struct i386_tc_frag_data
|
|||||||
the isa/tune settings at the time the .align was assembled. */
|
the isa/tune settings at the time the .align was assembled. */
|
||||||
#define TC_FRAG_TYPE struct i386_tc_frag_data
|
#define TC_FRAG_TYPE struct i386_tc_frag_data
|
||||||
|
|
||||||
#define TC_FRAG_INIT(FRAGP) \
|
#define TC_FRAG_INIT(FRAGP, MAX_BYTES) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
(FRAGP)->tc_frag_data.isa = cpu_arch_isa; \
|
(FRAGP)->tc_frag_data.isa = cpu_arch_isa; \
|
||||||
(FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags; \
|
(FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags; \
|
||||||
(FRAGP)->tc_frag_data.tune = cpu_arch_tune; \
|
(FRAGP)->tc_frag_data.tune = cpu_arch_tune; \
|
||||||
|
(FRAGP)->tc_frag_data.max_bytes = (MAX_BYTES); \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
@@ -280,7 +282,8 @@ if (fragP->fr_type == rs_align_code) \
|
|||||||
offsetT __count = (fragP->fr_next->fr_address \
|
offsetT __count = (fragP->fr_next->fr_address \
|
||||||
- fragP->fr_address \
|
- fragP->fr_address \
|
||||||
- fragP->fr_fix); \
|
- fragP->fr_fix); \
|
||||||
if (__count > 0 && __count <= MAX_MEM_FOR_RS_ALIGN_CODE) \
|
if (__count > 0 \
|
||||||
|
&& (unsigned int) __count <= fragP->tc_frag_data.max_bytes) \
|
||||||
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
|
md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \
|
||||||
__count, 0); \
|
__count, 0); \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ void ia64_vms_note (void);
|
|||||||
|
|
||||||
/* Record if an alignment frag should end with a stop bit. */
|
/* Record if an alignment frag should end with a stop bit. */
|
||||||
#define TC_FRAG_TYPE int
|
#define TC_FRAG_TYPE int
|
||||||
#define TC_FRAG_INIT(FRAGP) do {(FRAGP)->tc_frag_data = 0;}while (0)
|
#define TC_FRAG_INIT(FRAGP, MAX_BYTES) do {(FRAGP)->tc_frag_data = 0;}while (0)
|
||||||
|
|
||||||
/* Give an error if a frag containing code is not aligned to a 16 byte
|
/* Give an error if a frag containing code is not aligned to a 16 byte
|
||||||
boundary. */
|
boundary. */
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ extern long md_pcrel_from_section (struct fix *, segT);
|
|||||||
|
|
||||||
extern fragS *mmix_opcode_frag;
|
extern fragS *mmix_opcode_frag;
|
||||||
#define TC_FRAG_TYPE fragS *
|
#define TC_FRAG_TYPE fragS *
|
||||||
#define TC_FRAG_INIT(frag) (frag)->tc_frag_data = mmix_opcode_frag
|
#define TC_FRAG_INIT(frag, max_bytes) (frag)->tc_frag_data = mmix_opcode_frag
|
||||||
|
|
||||||
/* We need to associate each section symbol with a list of GREGs defined
|
/* We need to associate each section symbol with a list of GREGs defined
|
||||||
for that section/segment and sorted on offset, between the point where
|
for that section/segment and sorted on offset, between the point where
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ struct nds32_frag_type
|
|||||||
extern void nds32_frag_init (fragS *);
|
extern void nds32_frag_init (fragS *);
|
||||||
|
|
||||||
#define TC_FRAG_TYPE struct nds32_frag_type
|
#define TC_FRAG_TYPE struct nds32_frag_type
|
||||||
#define TC_FRAG_INIT(fragP) nds32_frag_init (fragP)
|
#define TC_FRAG_INIT(fragP, max_bytes) nds32_frag_init (fragP)
|
||||||
|
|
||||||
/* CFI directive. */
|
/* CFI directive. */
|
||||||
extern void nds32_elf_frame_initial_instructions (void);
|
extern void nds32_elf_frame_initial_instructions (void);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ extern const struct relax_type md_relax_table[];
|
|||||||
char fr_bsr; \
|
char fr_bsr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TC_FRAG_INIT(X) \
|
#define TC_FRAG_INIT(X, MAX_BYTES) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
frag_opcode_frag (X) = NULL; \
|
frag_opcode_frag (X) = NULL; \
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ extern void rl78_md_end (void);
|
|||||||
extern int rl78_relax_frag (segT, fragS *, long);
|
extern int rl78_relax_frag (segT, fragS *, long);
|
||||||
|
|
||||||
#define TC_FRAG_TYPE struct rl78_bytesT *
|
#define TC_FRAG_TYPE struct rl78_bytesT *
|
||||||
#define TC_FRAG_INIT rl78_frag_init
|
#define TC_FRAG_INIT(fragp, max_bytes) rl78_frag_init (fragp)
|
||||||
extern void rl78_frag_init (fragS *);
|
extern void rl78_frag_init (fragS *);
|
||||||
|
|
||||||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ extern void rx_md_end (void);
|
|||||||
extern int rx_relax_frag (segT, fragS *, long);
|
extern int rx_relax_frag (segT, fragS *, long);
|
||||||
|
|
||||||
#define TC_FRAG_TYPE struct rx_bytesT *
|
#define TC_FRAG_TYPE struct rx_bytesT *
|
||||||
#define TC_FRAG_INIT rx_frag_init
|
#define TC_FRAG_INIT(fragp, max_bytes) rx_frag_init (fragp)
|
||||||
extern void rx_frag_init (fragS *);
|
extern void rx_frag_init (fragS *);
|
||||||
|
|
||||||
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
/* Call md_pcrel_from_section(), not md_pcrel_from(). */
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct score_tc_frag_data
|
|||||||
|
|
||||||
#define TC_FRAG_TYPE struct score_tc_frag_data
|
#define TC_FRAG_TYPE struct score_tc_frag_data
|
||||||
|
|
||||||
#define TC_FRAG_INIT(FRAGP) \
|
#define TC_FRAG_INIT(FRAGP, MAX_BYTES) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
(FRAGP)->tc_frag_data.is_insn = (((FRAGP)->fr_type == rs_machine_dependent) ? 1 : 0); \
|
(FRAGP)->tc_frag_data.is_insn = (((FRAGP)->fr_type == rs_machine_dependent) ? 1 : 0); \
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct bit_info
|
|||||||
|
|
||||||
/* We sometimes need to keep track of bit offsets within words */
|
/* We sometimes need to keep track of bit offsets within words */
|
||||||
#define TC_FRAG_TYPE int
|
#define TC_FRAG_TYPE int
|
||||||
#define TC_FRAG_INIT(FRAGP) do {(FRAGP)->tc_frag_data = 0;}while (0)
|
#define TC_FRAG_INIT(FRAGP, MAX_BYTES) do {(FRAGP)->tc_frag_data = 0;}while (0)
|
||||||
|
|
||||||
/* tell GAS whether the given token is indeed a code label */
|
/* tell GAS whether the given token is indeed a code label */
|
||||||
#define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \
|
#define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ typedef struct
|
|||||||
bfd_boolean can_cross_fp_boundary;
|
bfd_boolean can_cross_fp_boundary;
|
||||||
} tic6x_frag_info;
|
} tic6x_frag_info;
|
||||||
#define TC_FRAG_TYPE tic6x_frag_info
|
#define TC_FRAG_TYPE tic6x_frag_info
|
||||||
#define TC_FRAG_INIT(fragP) tic6x_frag_init (fragP)
|
#define TC_FRAG_INIT(fragP, max_bytes) tic6x_frag_init (fragP)
|
||||||
extern void tic6x_frag_init (fragS *fragp);
|
extern void tic6x_frag_init (fragS *fragp);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -356,7 +356,7 @@ extern void xtensa_init (int, char **);
|
|||||||
#define TC_FIX_TYPE xtensa_fix_data
|
#define TC_FIX_TYPE xtensa_fix_data
|
||||||
#define TC_INIT_FIX_DATA(x) xtensa_init_fix_data (x)
|
#define TC_INIT_FIX_DATA(x) xtensa_init_fix_data (x)
|
||||||
#define TC_FRAG_TYPE struct xtensa_frag_type
|
#define TC_FRAG_TYPE struct xtensa_frag_type
|
||||||
#define TC_FRAG_INIT(frag) xtensa_frag_init (frag)
|
#define TC_FRAG_INIT(frag, max_bytes) xtensa_frag_init (frag)
|
||||||
#define TC_FORCE_RELOCATION(fix) xtensa_force_relocation (fix)
|
#define TC_FORCE_RELOCATION(fix) xtensa_force_relocation (fix)
|
||||||
#define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \
|
#define TC_FORCE_RELOCATION_SUB_SAME(fix, seg) \
|
||||||
(GENERIC_FORCE_RELOCATION_SUB_SAME (fix, seg) \
|
(GENERIC_FORCE_RELOCATION_SUB_SAME (fix, seg) \
|
||||||
|
|||||||
@@ -1118,10 +1118,11 @@ These fields are defined with the @code{TC_FIX_TYPE} macro.
|
|||||||
A C statement to output target specific debugging information for
|
A C statement to output target specific debugging information for
|
||||||
fixup @var{fixp} to @var{stream}. This macro is called by @code{print_fixup}.
|
fixup @var{fixp} to @var{stream}. This macro is called by @code{print_fixup}.
|
||||||
|
|
||||||
@item TC_FRAG_INIT (@var{fragp})
|
@item TC_FRAG_INIT (@var{fragp}, @var{max_bytes})
|
||||||
@cindex TC_FRAG_INIT
|
@cindex TC_FRAG_INIT
|
||||||
A C statement to initialize the target specific fields of frag @var{fragp}.
|
A C statement to initialize the target specific fields of frag @var{fragp}
|
||||||
These fields are defined with the @code{TC_FRAG_TYPE} macro.
|
with maximum number of bytes @var{max_bytes}. These fields are defined
|
||||||
|
with the @code{TC_FRAG_TYPE} macro.
|
||||||
|
|
||||||
@item md_number_to_chars
|
@item md_number_to_chars
|
||||||
@cindex md_number_to_chars
|
@cindex md_number_to_chars
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ frag_var_init (relax_stateT type, size_t max_chars, size_t var,
|
|||||||
frag_now->fr_cgen.opinfo = 0;
|
frag_now->fr_cgen.opinfo = 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef TC_FRAG_INIT
|
#ifdef TC_FRAG_INIT
|
||||||
TC_FRAG_INIT (frag_now);
|
TC_FRAG_INIT (frag_now, max_chars);
|
||||||
#endif
|
#endif
|
||||||
frag_now->fr_file = as_where (&frag_now->fr_line);
|
frag_now->fr_file = as_where (&frag_now->fr_line);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user