From d8699a0b89a3588ba049befa2249cd65f00fa195 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.tools@gmail.com> Date: Sun, 10 Feb 2019 04:34:10 -0800 Subject: [PATCH] gas: Pass max_bytes to TC_FRAG_INIT ommit 3ae729d5a4f63740ed9a778960b17c2912b0bbdd 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 * 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): Track max_chars in max_bytes. (HANDLE_ALIGN): Replace MAX_MEM_FOR_RS_ALIGN_CODE with fragP->tc_frag_data.max_bytes. (cherry picked from commit db22231044df03bbcb987496f3f29f0462b2e9ee) --- gas/config/tc-i386.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index f10b00df9c..fcb87e83a8 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -206,7 +206,7 @@ if ((n) \ 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 *); #define tc_print_statistics i386_print_statistics @@ -251,6 +251,7 @@ struct i386_tc_frag_data enum processor_type isa; i386_cpu_flags isa_flags; enum processor_type tune; + unsigned int max_bytes; }; /* We need to emit the right NOP pattern in .align frags. This is @@ -258,12 +259,14 @@ struct i386_tc_frag_data the isa/tune settings at the time the .align was assembled. */ #define TC_FRAG_TYPE struct i386_tc_frag_data +/* NB: max_chars is a local variable in frag_var_init. */ #define TC_FRAG_INIT(FRAGP) \ do \ { \ (FRAGP)->tc_frag_data.isa = cpu_arch_isa; \ (FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags; \ (FRAGP)->tc_frag_data.tune = cpu_arch_tune; \ + (FRAGP)->tc_frag_data.max_bytes = max_chars; \ } \ while (0) @@ -280,7 +283,8 @@ if (fragP->fr_type == rs_align_code) \ offsetT __count = (fragP->fr_next->fr_address \ - fragP->fr_address \ - 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, \ __count, 0); \ } -- 2.20.1