gas: Pass max_bytes to TC_FRAG_INIT
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 10 Feb 2019 12:34:10 +0000 (04:34 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 10 Feb 2019 12:34:22 +0000 (04:34 -0800)
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
* 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.

17 files changed:
gas/ChangeLog
gas/config/tc-aarch64.h
gas/config/tc-arm.h
gas/config/tc-avr.h
gas/config/tc-i386.h
gas/config/tc-ia64.h
gas/config/tc-mmix.h
gas/config/tc-nds32.h
gas/config/tc-ns32k.h
gas/config/tc-rl78.h
gas/config/tc-rx.h
gas/config/tc-score.h
gas/config/tc-tic54x.h
gas/config/tc-tic6x.h
gas/config/tc-xtensa.h
gas/doc/internals.texi
gas/frags.c

index aadf6e148bdc77d155b0e2f2116292b97fa82f19..04ad383e89dcc44f78566fa9f43c119ac5be1733 100644 (file)
@@ -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>
 
        * config/tc-riscv.c (validate_riscv_insn) <'C'>: Add 'z' support.
index 50b76d30191339d792601a92928c5350f1c94db4..b54907218cf2cbe4ac72b875305d500fb4a46fbd 100644 (file)
@@ -173,8 +173,7 @@ 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)    aarch64_init_frag (fragp, max_chars)
+#define TC_FRAG_INIT(fragp, max_bytes) aarch64_init_frag (fragp, max_bytes)
 #define HANDLE_ALIGN(fragp)    aarch64_handle_align (fragp)
 
 #define md_do_align(N, FILL, LEN, MAX, LABEL)                                  \
index f095d0a892ecbb76775ce9d04ce678ee4a8804dd..0d5e79c7ad9fe9a8c416d6f95609a0e2596eba26 100644 (file)
@@ -229,8 +229,7 @@ arm_min (int am_p1, int am_p2)
 }
 
 #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)    arm_init_frag (fragp, max_chars)
+#define TC_FRAG_INIT(fragp, max_bytes) arm_init_frag (fragp, max_bytes)
 #define TC_ALIGN_ZERO_IS_DEFAULT 1
 #define HANDLE_ALIGN(fragp)    arm_handle_align (fragp)
 /* PR gas/19276: COFF/PE segment alignment is already handled in coff_frob_section().  */
index efbf8ddba75d057c8e181fdbaf06a641fa951f09..d58222ec7757b6e6c5fc14769e7f5b0c17c0609f 100644 (file)
@@ -243,5 +243,5 @@ struct avr_frag_data
   unsigned int prev_opcode;
 };
 #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 *);
index f10b00df9c6a56dbb015dd5530194ab98eec3335..1f740e419ced068b4ff3467dabcf27e8f97d784a 100644 (file)
@@ -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,13 @@ 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
 
-#define TC_FRAG_INIT(FRAGP)                                    \
+#define TC_FRAG_INIT(FRAGP, MAX_BYTES)                         \
  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_BYTES);            \
    }                                                           \
  while (0)
 
@@ -280,7 +282,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);                                    \
   }
index f221b20d8f609a5c95bf4a62f845c768d8f78079..b478532549a9b93586347880794829fefd290490 100644 (file)
@@ -166,7 +166,7 @@ void ia64_vms_note (void);
 
 /* Record if an alignment frag should end with a stop bit.  */
 #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
    boundary.  */
index b44749c583c265606981e9fa374043bb7c965bcd..c984f7ae080f8f38c32ed8806e99b3af7f849d82 100644 (file)
@@ -179,7 +179,7 @@ extern long md_pcrel_from_section (struct fix *, segT);
 
 extern fragS *mmix_opcode_frag;
 #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
    for that section/segment and sorted on offset, between the point where
index 22e940604ccd048eff8f356eb7fc71614cfac487..4d4da274d256119ed24d3f92e5bed95cd08499db 100644 (file)
@@ -191,7 +191,7 @@ struct nds32_frag_type
 extern void nds32_frag_init (fragS *);
 
 #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.  */
 extern void nds32_elf_frame_initial_instructions (void);
index 4cb8e85f8bb297340f4d8374bc7af32d17a9b02d..a53ef976e44f8c71af0d64b9f7e8da787b7f007a 100644 (file)
@@ -73,7 +73,7 @@ extern const struct relax_type md_relax_table[];
       char         fr_bsr;                     \
     }
 
-#define TC_FRAG_INIT(X)                                \
+#define TC_FRAG_INIT(X, MAX_BYTES)             \
   do                                           \
      {                                         \
        frag_opcode_frag (X) = NULL;            \
index 738484b69c3359c181ec2931f8a7658369730c1a..315bd7e7d367a6e05db81e56c0f7e3192481aebe 100644 (file)
@@ -53,7 +53,7 @@ extern void rl78_md_end (void);
 extern int rl78_relax_frag (segT, fragS *, long);
 
 #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 *);
 
 /* Call md_pcrel_from_section(), not md_pcrel_from().  */
index 7dca68c8d4924dafb8b899fb4105fe0748eae322..09c50f94718195443cc44cca087d5c03963be6c0 100644 (file)
@@ -58,7 +58,7 @@ extern void rx_md_end (void);
 extern int rx_relax_frag (segT, fragS *, long);
 
 #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 *);
 
 /* Call md_pcrel_from_section(), not md_pcrel_from().  */
index 4da0be9a5552c13d0cb65efd31283910a47fc6c7..34cf5fdcd2aa1bddf92afe47de7c0b2954636f25 100644 (file)
@@ -62,7 +62,7 @@ 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 \
     { \
       (FRAGP)->tc_frag_data.is_insn = (((FRAGP)->fr_type == rs_machine_dependent) ? 1 : 0); \
index 5409d704dcbd5bd93c39effe834b0f3d8a79750c..0eda39603ebfd5c463019a3e23d344830e6baa1a 100644 (file)
@@ -62,7 +62,7 @@ struct bit_info
 
 /* We sometimes need to keep track of bit offsets within words */
 #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 */
 #define TC_START_LABEL_WITHOUT_COLON(NUL_CHAR, NEXT_CHAR) \
index 735cddb178d304e60f7680064c4ede4faa237874..fbca6376c207cb6fcc6b71f8d7e67ca1281f16c4 100644 (file)
@@ -130,7 +130,7 @@ typedef struct
   bfd_boolean can_cross_fp_boundary;
 } 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);
 
 typedef struct
index ed7b08da13cba7278778e5a7cdce19a756b010f0..6889d92a4fb668a35e14899aeb05ee5ba4c4eef2 100644 (file)
@@ -356,7 +356,7 @@ extern void xtensa_init (int, char **);
 #define TC_FIX_TYPE                    xtensa_fix_data
 #define TC_INIT_FIX_DATA(x)            xtensa_init_fix_data (x)
 #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_SUB_SAME(fix, seg) \
   (GENERIC_FORCE_RELOCATION_SUB_SAME (fix, seg)        \
index 00083679bcbba02bcb8adffe4946f1c1c92e0acb..a50880d635ff44293dfaedf908895c8b1b57a98f 100644 (file)
@@ -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
 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
-A C statement to initialize the target specific fields of frag @var{fragp}.
-These fields are defined with the @code{TC_FRAG_TYPE} macro.
+A C statement to initialize the target specific fields of frag @var{fragp}
+with maximum number of bytes @var{max_bytes}.  These fields are defined
+with the @code{TC_FRAG_TYPE} macro.
 
 @item md_number_to_chars
 @cindex md_number_to_chars
index 0ee31078ca8e45bfc1b65200b1bfa5ee0d1fddae..90096ff696d7b4809a487b3f4d73fc1a7d1fe6cb 100644 (file)
@@ -238,7 +238,7 @@ frag_var_init (relax_stateT type, size_t max_chars, size_t var,
   frag_now->fr_cgen.opinfo = 0;
 #endif
 #ifdef TC_FRAG_INIT
-  TC_FRAG_INIT (frag_now);
+  TC_FRAG_INIT (frag_now, max_chars);
 #endif
   frag_now->fr_file = as_where (&frag_now->fr_line);