* [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures
@ 2024-03-30 8:43 Yang Yujie
2024-03-30 8:45 ` Yang Yujie
2024-04-01 1:17 ` [pushed][PATCH " chenglulu
0 siblings, 2 replies; 3+ messages in thread
From: Yang Yujie @ 2024-03-30 8:43 UTC (permalink / raw)
To: gcc-patches; +Cc: chenglulu, xuchenghua, Yang Yujie
gcc/ChangeLog:
* config/loongarch/genopts/loongarch.opt.in: Mark -m[no-]recip as
aliases to -mrecip={all,none}, respectively.
* config/loongarch/loongarch.opt: Regenerate.
* config/loongarch/loongarch-def.h (ABI_FPU_64): Rename to...
(ABI_FPU64_P): ...this.
(ABI_FPU_32): Rename to...
(ABI_FPU32_P): ...this.
(ABI_FPU_NONE): Rename to...
(ABI_NOFPU_P): ...this.
(ABI_LP64_P): Define.
* config/loongarch/loongarch.cc (loongarch_init_print_operand_punct):
Merged into loongarch_global_init.
(loongarch_cpu_option_override): Renamed to
loongarch_target_option_override.
(loongarch_option_override_internal): Move the work after
loongarch_config_target into loongarch_target_option_override.
(loongarch_global_init): Define.
(INIT_TARGET_FLAG): Move to loongarch-opts.cc.
(loongarch_option_override): Call loongarch_global_init
separately.
* config/loongarch/loongarch-opts.cc (loongarch_parse_mrecip_scheme):
Split the parsing of -mrecip=<string> from
loongarch_option_override_internal.
(loongarch_generate_mrecip_scheme): Define. Split from
loongarch_option_override_internal.
(loongarch_target_option_override): Define. Renamed from
loongarch_cpu_option_override.
(loongarch_init_misc_options): Define. Split from
loongarch_option_override_internal.
(INIT_TARGET_FLAG): Move from loongarch.cc.
* config/loongarch/loongarch-opts.h (loongarch_target_option_override):
New prototype.
(loongarch_parse_mrecip_scheme): New prototype.
(loongarch_init_misc_options): New prototype.
(TARGET_ABI_LP64): Simplify with ABI_LP64_P.
* config/loongarch/loongarch.h (TARGET_RECIP_DIV): Simplify.
Do not reference specific CPU architecture (LA664).
(TARGET_RECIP_SQRT): Same.
(TARGET_RECIP_RSQRT): Same.
(TARGET_RECIP_VEC_DIV): Same.
(TARGET_RECIP_VEC_SQRT): Same.
(TARGET_RECIP_VEC_RSQRT): Same.
---
gcc/config/loongarch/genopts/loongarch.opt.in | 8 +-
gcc/config/loongarch/loongarch-def.h | 11 +-
gcc/config/loongarch/loongarch-opts.cc | 253 ++++++++++++++++++
gcc/config/loongarch/loongarch-opts.h | 27 +-
gcc/config/loongarch/loongarch.cc | 253 +++---------------
gcc/config/loongarch/loongarch.h | 18 +-
gcc/config/loongarch/loongarch.opt | 8 +-
7 files changed, 342 insertions(+), 236 deletions(-)
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 02f918053f5..a77893d31d9 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -197,14 +197,14 @@ mexplicit-relocs
Target Alias(mexplicit-relocs=, always, none)
Use %reloc() assembly operators (for backward compatibility).
-mrecip
-Target RejectNegative Var(la_recip) Save
-Generate approximate reciprocal divide and square root for better throughput.
-
mrecip=
Target RejectNegative Joined Var(la_recip_name) Save
Control generation of reciprocal estimates.
+mrecip
+Target Alias(mrecip=, all, none)
+Generate approximate reciprocal divide and square root for better throughput.
+
; The code model option names for -mcmodel.
Enum
Name(cmodel) Type(int)
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index 2dbf006d013..0cbf9476690 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -90,11 +90,16 @@ extern loongarch_def_array<const char *, N_ABI_BASE_TYPES>
#define TO_LP64_ABI_BASE(C) (C)
-#define ABI_FPU_64(abi_base) \
+#define ABI_LP64_P(abi_base) \
+ (abi_base == ABI_BASE_LP64D \
+ || abi_base == ABI_BASE_LP64F \
+ || abi_base == ABI_BASE_LP64S)
+
+#define ABI_FPU64_P(abi_base) \
(abi_base == ABI_BASE_LP64D)
-#define ABI_FPU_32(abi_base) \
+#define ABI_FPU32_P(abi_base) \
(abi_base == ABI_BASE_LP64F)
-#define ABI_FPU_NONE(abi_base) \
+#define ABI_NOFPU_P(abi_base) \
(abi_base == ABI_BASE_LP64S)
diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
index 627f9148adf..e600f08f03b 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tm.h"
#include "obstack.h"
+#include "opts.h"
#include "diagnostic-core.h"
#include "loongarch-cpu.h"
@@ -32,8 +33,12 @@ along with GCC; see the file COPYING3. If not see
#include "loongarch-str.h"
#include "loongarch-def.h"
+/* Target configuration */
struct loongarch_target la_target;
+/* RTL cost information */
+const struct loongarch_rtx_cost_data *loongarch_cost;
+
/* ABI-related configuration. */
#define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
static const struct loongarch_abi
@@ -795,3 +800,251 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
/* ISA evolution features */
opts->x_la_isa_evolution = target->isa.evolution;
}
+
+/* -mrecip=<str> handling */
+static struct
+ {
+ const char *string; /* option name. */
+ unsigned int mask; /* mask bits to set. */
+ }
+const recip_options[] = {
+ { "all", RECIP_MASK_ALL },
+ { "none", RECIP_MASK_NONE },
+ { "div", RECIP_MASK_DIV },
+ { "sqrt", RECIP_MASK_SQRT },
+ { "rsqrt", RECIP_MASK_RSQRT },
+ { "vec-div", RECIP_MASK_VEC_DIV },
+ { "vec-sqrt", RECIP_MASK_VEC_SQRT },
+ { "vec-rsqrt", RECIP_MASK_VEC_RSQRT },
+};
+
+/* Parser for -mrecip=<recip_string>. */
+unsigned int
+loongarch_parse_mrecip_scheme (const char *recip_string)
+{
+ unsigned int result_mask = RECIP_MASK_NONE;
+
+ if (recip_string)
+ {
+ char *p = ASTRDUP (recip_string);
+ char *q;
+ unsigned int mask, i;
+ bool invert;
+
+ while ((q = strtok (p, ",")) != NULL)
+ {
+ p = NULL;
+ if (*q == '!')
+ {
+ invert = true;
+ q++;
+ }
+ else
+ invert = false;
+
+ if (!strcmp (q, "default"))
+ mask = RECIP_MASK_ALL;
+ else
+ {
+ for (i = 0; i < ARRAY_SIZE (recip_options); i++)
+ if (!strcmp (q, recip_options[i].string))
+ {
+ mask = recip_options[i].mask;
+ break;
+ }
+
+ if (i == ARRAY_SIZE (recip_options))
+ {
+ error ("unknown option for %<-mrecip=%s%>", q);
+ invert = false;
+ mask = RECIP_MASK_NONE;
+ }
+ }
+
+ if (invert)
+ result_mask &= ~mask;
+ else
+ result_mask |= mask;
+ }
+ }
+ return result_mask;
+}
+
+/* Generate -mrecip= argument based on the mask. */
+const char*
+loongarch_generate_mrecip_scheme (unsigned int mask)
+{
+ static char recip_scheme_str[128];
+ int p = 0, tmp;
+
+ switch (mask)
+ {
+ case RECIP_MASK_ALL:
+ return "all";
+
+ case RECIP_MASK_NONE:
+ return "none";
+ }
+
+ for (unsigned long i = 2; i < ARRAY_SIZE (recip_options); i++)
+ {
+ if (mask & recip_options[i].mask)
+ {
+ if ((tmp = strlen (recip_options[i].string) + 1) >= 127 - p)
+ gcc_unreachable ();
+
+ recip_scheme_str[p] = ',';
+ strcpy (recip_scheme_str + p + 1, recip_options[i].string);
+ p += tmp;
+ }
+ }
+ recip_scheme_str[p] = '\0';
+ return recip_scheme_str + 1;
+}
+
+
+
+/* Refresh the switches acccording to the resolved loongarch_target struct. */
+void
+loongarch_target_option_override (struct loongarch_target *target,
+ struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ loongarch_update_gcc_opt_status (target, opts, opts_set);
+
+ /* alignments */
+ if (opts->x_flag_align_functions && !opts->x_str_align_functions)
+ opts->x_str_align_functions
+ = loongarch_cpu_align[target->cpu_tune].function;
+
+ if (opts->x_flag_align_labels && !opts->x_str_align_labels)
+ opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
+
+ /* Set up parameters to be used in prefetching algorithm. */
+ int simultaneous_prefetches
+ = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
+
+ SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
+ simultaneous_prefetches);
+
+ SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
+ loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
+
+ SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
+ loongarch_cpu_cache[target->cpu_tune].l1d_size);
+
+ SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
+ loongarch_cpu_cache[target->cpu_tune].l2d_size);
+
+ /* Other arch-specific overrides. */
+ switch (target->cpu_arch)
+ {
+ case CPU_LA664:
+ /* Enable -mrecipe=all for LA664 by default. */
+ if (!opts_set->x_recip_mask)
+ {
+ opts->x_recip_mask = RECIP_MASK_ALL;
+ opts_set->x_recip_mask = 1;
+ }
+ }
+
+ /* -mrecip= */
+ opts->x_la_recip_name
+ = loongarch_generate_mrecip_scheme (opts->x_recip_mask);
+
+ /* Decide which rtx_costs structure to use. */
+ if (opts->x_optimize_size)
+ loongarch_cost = &loongarch_rtx_cost_optimize_size;
+ else
+ loongarch_cost = &loongarch_cpu_rtx_cost_data[target->cpu_tune];
+
+ /* If the user hasn't specified a branch cost, use the processor's
+ default. */
+ if (!opts_set->x_la_branch_cost)
+ opts->x_la_branch_cost = loongarch_cost->branch_cost;
+
+ /* other stuff */
+ if (ABI_LP64_P (target->abi.base))
+ opts->x_flag_pcc_struct_return = 0;
+
+ switch (target->cmodel)
+ {
+ case CMODEL_EXTREME:
+ if (opts->x_flag_plt)
+ {
+ if (opts_set->x_flag_plt)
+ error ("code model %qs is not compatible with %s",
+ "extreme", "-fplt");
+ opts->x_flag_plt = 0;
+ }
+ break;
+
+ case CMODEL_TINY_STATIC:
+ case CMODEL_MEDIUM:
+ case CMODEL_NORMAL:
+ case CMODEL_TINY:
+ case CMODEL_LARGE:
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+
+/* Resolve options that's not covered by la_target. */
+void
+loongarch_init_misc_options (struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ if (opts->x_flag_pic)
+ opts->x_g_switch_value = 0;
+
+ /* -mrecip options. */
+ opts->x_recip_mask = loongarch_parse_mrecip_scheme (opts->x_la_recip_name);
+
+#define INIT_TARGET_FLAG(NAME, INIT) \
+ { \
+ if (!(opts_set->x_target_flags & MASK_##NAME)) \
+ { \
+ if (INIT) \
+ opts->x_target_flags |= MASK_##NAME; \
+ else \
+ opts->x_target_flags &= ~MASK_##NAME; \
+ } \
+ }
+
+ /* Enable conditional moves for int and float by default. */
+ INIT_TARGET_FLAG (COND_MOVE_INT, 1)
+ INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1)
+
+ /* Set mrelax default. */
+ INIT_TARGET_FLAG (LINKER_RELAXATION,
+ HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION)
+
+#undef INIT_TARGET_FLAG
+
+ /* Set mexplicit-relocs default. */
+ if (opts->x_la_opt_explicit_relocs == M_OPT_UNSET)
+ opts->x_la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS
+ ? (TARGET_LINKER_RELAXATION
+ ? EXPLICIT_RELOCS_AUTO
+ : EXPLICIT_RELOCS_ALWAYS)
+ : EXPLICIT_RELOCS_NONE);
+
+ /* Enable sw prefetching at -O3 and higher. */
+ if (opts->x_flag_prefetch_loop_arrays < 0
+ && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
+ && !opts->x_optimize_size)
+ opts->x_flag_prefetch_loop_arrays = 1;
+
+ if (TARGET_DIRECT_EXTERN_ACCESS_OPTS_P (opts) && opts->x_flag_shlib)
+ error ("%qs cannot be used for compiling a shared library",
+ "-mdirect-extern-access");
+
+ /* Enforce that interval is the same size as size so the mid-end does the
+ right thing. */
+ SET_OPTION_IF_UNSET (opts, opts_set,
+ param_stack_clash_protection_probe_interval,
+ param_stack_clash_protection_guard_size);
+}
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index 586e67e65ee..2d9f59296e7 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -30,6 +30,10 @@ along with GCC; see the file COPYING3. If not see
/* Target configuration */
extern struct loongarch_target la_target;
+/* RTL cost information */
+extern const struct loongarch_rtx_cost_data *loongarch_cost;
+
+
/* Initialize loongarch_target from separate option variables. */
void
loongarch_init_target (struct loongarch_target *target,
@@ -46,11 +50,30 @@ loongarch_config_target (struct loongarch_target *target,
struct loongarch_flags *flags,
int follow_multilib_list_p);
+
+/* Refresh the switches acccording to the resolved loongarch_target struct. */
+void
+loongarch_target_option_override (struct loongarch_target *target,
+ struct gcc_options *opts,
+ struct gcc_options *opts_set);
+
+
/* option status feedback for "gcc --help=target -Q" */
void
loongarch_update_gcc_opt_status (struct loongarch_target *target,
struct gcc_options *opts,
struct gcc_options *opts_set);
+
+
+/* Parser for -mrecip=<recip_string>. */
+unsigned int
+loongarch_parse_mrecip_scheme (const char *recip_string);
+
+
+/* Resolve options that's not covered by la_target. */
+void
+loongarch_init_misc_options (struct gcc_options *opts,
+ struct gcc_options *opts_set);
#endif
/* Flag status */
@@ -80,9 +103,7 @@ struct loongarch_flags {
#define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D)
#define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64)
-#define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \
- || la_target.abi.base == ABI_BASE_LP64F \
- || la_target.abi.base == ABI_BASE_LP64S)
+#define TARGET_ABI_LP64 ABI_LP64_P(la_target.abi.base)
#define ISA_HAS_LSX \
(la_target.isa.simd == ISA_EXT_SIMD_LSX \
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 030957db4e7..a69a203fbe6 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -208,9 +208,6 @@ const enum reg_class loongarch_regno_to_class[FIRST_PSEUDO_REGISTER] = {
FRAME_REGS, FRAME_REGS
};
-/* Which cost information to use. */
-static const struct loongarch_rtx_cost_data *loongarch_cost;
-
/* Information about a single argument. */
struct loongarch_arg_info
{
@@ -5911,17 +5908,6 @@ loongarch_print_operand_punctuation (FILE *file, int ch)
}
}
-/* Initialize loongarch_print_operand_punct. */
-
-static void
-loongarch_init_print_operand_punct (void)
-{
- const char *p;
-
- for (p = ".$"; *p; p++)
- loongarch_print_operand_punct[(unsigned char) *p] = true;
-}
-
/* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
associated with condition CODE. Print the condition part of the
opcode to FILE. */
@@ -7625,118 +7611,15 @@ loongarch_init_machine_status (void)
}
static void
-loongarch_cpu_option_override (struct loongarch_target *target,
- struct gcc_options *opts,
- struct gcc_options *opts_set)
-{
- /* alignments */
- if (opts->x_flag_align_functions && !opts->x_str_align_functions)
- opts->x_str_align_functions
- = loongarch_cpu_align[target->cpu_tune].function;
-
- if (opts->x_flag_align_labels && !opts->x_str_align_labels)
- opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
-
- /* Set up parameters to be used in prefetching algorithm. */
- int simultaneous_prefetches
- = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
-
- SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
- simultaneous_prefetches);
-
- SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
- loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
-
- SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
- loongarch_cpu_cache[target->cpu_tune].l1d_size);
-
- SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
- loongarch_cpu_cache[target->cpu_tune].l2d_size);
-}
-
-static void
-loongarch_option_override_internal (struct gcc_options *opts,
- struct gcc_options *opts_set)
+loongarch_global_init (void)
{
- int i, regno, mode;
-
- if (flag_pic)
- g_switch_value = 0;
-
- loongarch_init_target (&la_target,
- la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
- la_opt_simd, la_opt_abi_base, la_opt_abi_ext,
- la_opt_cmodel, opts->x_la_isa_evolution,
- opts_set->x_la_isa_evolution);
-
- /* Handle target-specific options: compute defaults/conflicts etc. */
- loongarch_config_target (&la_target, NULL, 0);
-
- loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
- loongarch_cpu_option_override (&la_target, opts, opts_set);
-
- if (TARGET_ABI_LP64)
- flag_pcc_struct_return = 0;
-
- /* Decide which rtx_costs structure to use. */
- if (optimize_size)
- loongarch_cost = &loongarch_rtx_cost_optimize_size;
- else
- loongarch_cost = &loongarch_cpu_rtx_cost_data[la_target.cpu_tune];
-
- /* If the user hasn't specified a branch cost, use the processor's
- default. */
- if (la_branch_cost == 0)
- la_branch_cost = loongarch_cost->branch_cost;
-
- /* Enable sw prefetching at -O3 and higher. */
- if (opts->x_flag_prefetch_loop_arrays < 0
- && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
- && !opts->x_optimize_size)
- opts->x_flag_prefetch_loop_arrays = 1;
-
- if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
- error ("%qs cannot be used for compiling a shared library",
- "-mdirect-extern-access");
-
- switch (la_target.cmodel)
- {
- case CMODEL_EXTREME:
- if (opts->x_flag_plt)
- {
- if (global_options_set.x_flag_plt)
- error ("code model %qs is not compatible with %s",
- "extreme", "-fplt");
- opts->x_flag_plt = 0;
- }
- break;
-
- case CMODEL_TINY_STATIC:
- case CMODEL_MEDIUM:
- case CMODEL_NORMAL:
- case CMODEL_TINY:
- case CMODEL_LARGE:
- break;
-
- default:
- gcc_unreachable ();
- }
-
- /* Validate the guard size. */
- int guard_size = param_stack_clash_protection_guard_size;
-
- /* Enforce that interval is the same size as size so the mid-end does the
- right thing. */
- SET_OPTION_IF_UNSET (opts, &global_options_set,
- param_stack_clash_protection_probe_interval,
- guard_size);
-
- loongarch_init_print_operand_punct ();
+ /* Initialize loongarch_print_operand_punct. */
+ for (const char *p = ".$"; *p; p++)
+ loongarch_print_operand_punct[(unsigned char) *p] = true;
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (GP_REG_P (i) || FP_REG_P (i))
loongarch_dwarf_regno[i] = i;
@@ -7745,115 +7628,53 @@ loongarch_option_override_internal (struct gcc_options *opts,
}
/* Set up loongarch_hard_regno_mode_ok. */
- for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ for (int mode = 0; mode < MAX_MACHINE_MODE; mode++)
+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
loongarch_hard_regno_mode_ok_p[mode][regno]
= loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
/* Function to allocate machine-dependent function status. */
init_machine_status = &loongarch_init_machine_status;
+};
- /* -mrecip options. */
- static struct
- {
- const char *string; /* option name. */
- unsigned int mask; /* mask bits to set. */
- }
- const recip_options[] = {
- { "all", RECIP_MASK_ALL },
- { "none", RECIP_MASK_NONE },
- { "div", RECIP_MASK_DIV },
- { "sqrt", RECIP_MASK_SQRT },
- { "rsqrt", RECIP_MASK_RSQRT },
- { "vec-div", RECIP_MASK_VEC_DIV },
- { "vec-sqrt", RECIP_MASK_VEC_SQRT },
- { "vec-rsqrt", RECIP_MASK_VEC_RSQRT },
- };
-
- if (la_recip_name)
- {
- char *p = ASTRDUP (la_recip_name);
- char *q;
- unsigned int mask, i;
- bool invert;
-
- while ((q = strtok (p, ",")) != NULL)
- {
- p = NULL;
- if (*q == '!')
- {
- invert = true;
- q++;
- }
- else
- invert = false;
-
- if (!strcmp (q, "default"))
- mask = RECIP_MASK_ALL;
- else
- {
- for (i = 0; i < ARRAY_SIZE (recip_options); i++)
- if (!strcmp (q, recip_options[i].string))
- {
- mask = recip_options[i].mask;
- break;
- }
-
- if (i == ARRAY_SIZE (recip_options))
- {
- error ("unknown option for %<-mrecip=%s%>", q);
- invert = false;
- mask = RECIP_MASK_NONE;
- }
- }
-
- if (invert)
- recip_mask &= ~mask;
- else
- recip_mask |= mask;
- }
- }
- if (la_recip)
- recip_mask |= RECIP_MASK_ALL;
- if (!ISA_HAS_FRECIPE)
- recip_mask = RECIP_MASK_NONE;
-
-#define INIT_TARGET_FLAG(NAME, INIT) \
- { \
- if (!(target_flags_explicit & MASK_##NAME)) \
- { \
- if (INIT) \
- target_flags |= MASK_##NAME; \
- else \
- target_flags &= ~MASK_##NAME; \
- } \
- }
-
- /* Enable conditional moves for int and float by default. */
- INIT_TARGET_FLAG (COND_MOVE_INT, 1)
- INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1)
-
- /* Set mrelax default. */
- INIT_TARGET_FLAG (LINKER_RELAXATION,
- HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION)
+static void
+loongarch_option_override_internal (struct loongarch_target *target,
+ struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ /* Handle options not covered by struct loongarch_target. */
+ loongarch_init_misc_options (opts, opts_set);
+
+ /* Resolve the target struct. */
+ loongarch_init_target (target,
+ opts->x_la_opt_cpu_arch,
+ opts->x_la_opt_cpu_tune,
+ opts->x_la_opt_fpu,
+ opts->x_la_opt_simd,
+ opts->x_la_opt_abi_base,
+ opts->x_la_opt_abi_ext,
+ opts->x_la_opt_cmodel,
+ opts->x_la_isa_evolution,
+ opts_set->x_la_isa_evolution);
-#undef INIT_TARGET_FLAG
+ loongarch_config_target (target, NULL, 0);
- if (la_opt_explicit_relocs == M_OPT_UNSET)
- la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS
- ? (TARGET_LINKER_RELAXATION
- ? EXPLICIT_RELOCS_AUTO
- : EXPLICIT_RELOCS_ALWAYS)
- : EXPLICIT_RELOCS_NONE);
+ /* Override some options according to the resolved target. */
+ loongarch_target_option_override (target, opts, opts_set);
}
-
/* Implement TARGET_OPTION_OVERRIDE. */
static void
loongarch_option_override (void)
{
- loongarch_option_override_internal (&global_options, &global_options_set);
+ /* Setting up the target configuration. */
+ loongarch_option_override_internal (&la_target,
+ &global_options,
+ &global_options_set);
+
+ /* Global initializations. */
+ loongarch_global_init ();
}
/* Implement TARGET_OPTION_SAVE. */
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index 888a633961d..23bb3254883 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -710,12 +710,18 @@ enum reg_class
| RECIP_MASK_RSQRT | RECIP_MASK_VEC_SQRT \
| RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_RSQRT)
-#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0 || TARGET_uARCH_LA664)
-#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0 || TARGET_uARCH_LA664)
-#define TARGET_RECIP_RSQRT ((recip_mask & RECIP_MASK_RSQRT) != 0 || TARGET_uARCH_LA664)
-#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0 || TARGET_uARCH_LA664)
-#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 || TARGET_uARCH_LA664)
-#define TARGET_RECIP_VEC_RSQRT ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 || TARGET_uARCH_LA664)
+#define TARGET_RECIP_DIV \
+ ((recip_mask & RECIP_MASK_DIV) != 0 && ISA_HAS_FRECIPE)
+#define TARGET_RECIP_SQRT \
+ ((recip_mask & RECIP_MASK_SQRT) != 0 && ISA_HAS_FRECIPE)
+#define TARGET_RECIP_RSQRT \
+ ((recip_mask & RECIP_MASK_RSQRT) != 0 && ISA_HAS_FRECIPE)
+#define TARGET_RECIP_VEC_DIV \
+ ((recip_mask & RECIP_MASK_VEC_DIV) != 0 && ISA_HAS_FRECIPE)
+#define TARGET_RECIP_VEC_SQRT \
+ ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 && ISA_HAS_FRECIPE)
+#define TARGET_RECIP_VEC_RSQRT \
+ ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 && ISA_HAS_FRECIPE)
/* 1 if N is a possible register number for function argument passing.
We have no FP argument registers when soft-float. */
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index f10fcdd968c..317cd11a67c 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -205,14 +205,14 @@ mexplicit-relocs
Target Alias(mexplicit-relocs=, always, none)
Use %reloc() assembly operators (for backward compatibility).
-mrecip
-Target RejectNegative Var(la_recip) Save
-Generate approximate reciprocal divide and square root for better throughput.
-
mrecip=
Target RejectNegative Joined Var(la_recip_name) Save
Control generation of reciprocal estimates.
+mrecip
+Target Alias(mrecip=, all, none)
+Generate approximate reciprocal divide and square root for better throughput.
+
; The code model option names for -mcmodel.
Enum
Name(cmodel) Type(int)
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures
2024-03-30 8:43 [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures Yang Yujie
@ 2024-03-30 8:45 ` Yang Yujie
2024-04-01 1:17 ` [pushed][PATCH " chenglulu
1 sibling, 0 replies; 3+ messages in thread
From: Yang Yujie @ 2024-03-30 8:45 UTC (permalink / raw)
To: gcc-patches; +Cc: chenglulu, xuchenghua, Yang Yujie
v1 -> v2:
- Rebased to master.
- Specifies "(void)" for the empty parameter list of loongarch_global_init.
v2 -> v3:
- Keep the original option-processing behavior (-march=la664 enables -mrecip=all)
and fix the ICE when -mfrecipe is not passed with -mrecip.
v3 -> v4:
- Rewrite changelog.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [pushed][PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures
2024-03-30 8:43 [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures Yang Yujie
2024-03-30 8:45 ` Yang Yujie
@ 2024-04-01 1:17 ` chenglulu
1 sibling, 0 replies; 3+ messages in thread
From: chenglulu @ 2024-04-01 1:17 UTC (permalink / raw)
To: Yang Yujie, gcc-patches; +Cc: xuchenghua
Pushed to r14-9737.
在 2024/3/30 下午4:43, Yang Yujie 写道:
> gcc/ChangeLog:
>
> * config/loongarch/genopts/loongarch.opt.in: Mark -m[no-]recip as
> aliases to -mrecip={all,none}, respectively.
> * config/loongarch/loongarch.opt: Regenerate.
> * config/loongarch/loongarch-def.h (ABI_FPU_64): Rename to...
> (ABI_FPU64_P): ...this.
> (ABI_FPU_32): Rename to...
> (ABI_FPU32_P): ...this.
> (ABI_FPU_NONE): Rename to...
> (ABI_NOFPU_P): ...this.
> (ABI_LP64_P): Define.
> * config/loongarch/loongarch.cc (loongarch_init_print_operand_punct):
> Merged into loongarch_global_init.
> (loongarch_cpu_option_override): Renamed to
> loongarch_target_option_override.
> (loongarch_option_override_internal): Move the work after
> loongarch_config_target into loongarch_target_option_override.
> (loongarch_global_init): Define.
> (INIT_TARGET_FLAG): Move to loongarch-opts.cc.
> (loongarch_option_override): Call loongarch_global_init
> separately.
> * config/loongarch/loongarch-opts.cc (loongarch_parse_mrecip_scheme):
> Split the parsing of -mrecip=<string> from
> loongarch_option_override_internal.
> (loongarch_generate_mrecip_scheme): Define. Split from
> loongarch_option_override_internal.
> (loongarch_target_option_override): Define. Renamed from
> loongarch_cpu_option_override.
> (loongarch_init_misc_options): Define. Split from
> loongarch_option_override_internal.
> (INIT_TARGET_FLAG): Move from loongarch.cc.
> * config/loongarch/loongarch-opts.h (loongarch_target_option_override):
> New prototype.
> (loongarch_parse_mrecip_scheme): New prototype.
> (loongarch_init_misc_options): New prototype.
> (TARGET_ABI_LP64): Simplify with ABI_LP64_P.
> * config/loongarch/loongarch.h (TARGET_RECIP_DIV): Simplify.
> Do not reference specific CPU architecture (LA664).
> (TARGET_RECIP_SQRT): Same.
> (TARGET_RECIP_RSQRT): Same.
> (TARGET_RECIP_VEC_DIV): Same.
> (TARGET_RECIP_VEC_SQRT): Same.
> (TARGET_RECIP_VEC_RSQRT): Same.
> ---
> gcc/config/loongarch/genopts/loongarch.opt.in | 8 +-
> gcc/config/loongarch/loongarch-def.h | 11 +-
> gcc/config/loongarch/loongarch-opts.cc | 253 ++++++++++++++++++
> gcc/config/loongarch/loongarch-opts.h | 27 +-
> gcc/config/loongarch/loongarch.cc | 253 +++---------------
> gcc/config/loongarch/loongarch.h | 18 +-
> gcc/config/loongarch/loongarch.opt | 8 +-
> 7 files changed, 342 insertions(+), 236 deletions(-)
>
> diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
> index 02f918053f5..a77893d31d9 100644
> --- a/gcc/config/loongarch/genopts/loongarch.opt.in
> +++ b/gcc/config/loongarch/genopts/loongarch.opt.in
> @@ -197,14 +197,14 @@ mexplicit-relocs
> Target Alias(mexplicit-relocs=, always, none)
> Use %reloc() assembly operators (for backward compatibility).
>
> -mrecip
> -Target RejectNegative Var(la_recip) Save
> -Generate approximate reciprocal divide and square root for better throughput.
> -
> mrecip=
> Target RejectNegative Joined Var(la_recip_name) Save
> Control generation of reciprocal estimates.
>
> +mrecip
> +Target Alias(mrecip=, all, none)
> +Generate approximate reciprocal divide and square root for better throughput.
> +
> ; The code model option names for -mcmodel.
> Enum
> Name(cmodel) Type(int)
> diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
> index 2dbf006d013..0cbf9476690 100644
> --- a/gcc/config/loongarch/loongarch-def.h
> +++ b/gcc/config/loongarch/loongarch-def.h
> @@ -90,11 +90,16 @@ extern loongarch_def_array<const char *, N_ABI_BASE_TYPES>
>
> #define TO_LP64_ABI_BASE(C) (C)
>
> -#define ABI_FPU_64(abi_base) \
> +#define ABI_LP64_P(abi_base) \
> + (abi_base == ABI_BASE_LP64D \
> + || abi_base == ABI_BASE_LP64F \
> + || abi_base == ABI_BASE_LP64S)
> +
> +#define ABI_FPU64_P(abi_base) \
> (abi_base == ABI_BASE_LP64D)
> -#define ABI_FPU_32(abi_base) \
> +#define ABI_FPU32_P(abi_base) \
> (abi_base == ABI_BASE_LP64F)
> -#define ABI_FPU_NONE(abi_base) \
> +#define ABI_NOFPU_P(abi_base) \
> (abi_base == ABI_BASE_LP64S)
>
>
> diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
> index 627f9148adf..e600f08f03b 100644
> --- a/gcc/config/loongarch/loongarch-opts.cc
> +++ b/gcc/config/loongarch/loongarch-opts.cc
> @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
> #include "coretypes.h"
> #include "tm.h"
> #include "obstack.h"
> +#include "opts.h"
> #include "diagnostic-core.h"
>
> #include "loongarch-cpu.h"
> @@ -32,8 +33,12 @@ along with GCC; see the file COPYING3. If not see
> #include "loongarch-str.h"
> #include "loongarch-def.h"
>
> +/* Target configuration */
> struct loongarch_target la_target;
>
> +/* RTL cost information */
> +const struct loongarch_rtx_cost_data *loongarch_cost;
> +
> /* ABI-related configuration. */
> #define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
> static const struct loongarch_abi
> @@ -795,3 +800,251 @@ loongarch_update_gcc_opt_status (struct loongarch_target *target,
> /* ISA evolution features */
> opts->x_la_isa_evolution = target->isa.evolution;
> }
> +
> +/* -mrecip=<str> handling */
> +static struct
> + {
> + const char *string; /* option name. */
> + unsigned int mask; /* mask bits to set. */
> + }
> +const recip_options[] = {
> + { "all", RECIP_MASK_ALL },
> + { "none", RECIP_MASK_NONE },
> + { "div", RECIP_MASK_DIV },
> + { "sqrt", RECIP_MASK_SQRT },
> + { "rsqrt", RECIP_MASK_RSQRT },
> + { "vec-div", RECIP_MASK_VEC_DIV },
> + { "vec-sqrt", RECIP_MASK_VEC_SQRT },
> + { "vec-rsqrt", RECIP_MASK_VEC_RSQRT },
> +};
> +
> +/* Parser for -mrecip=<recip_string>. */
> +unsigned int
> +loongarch_parse_mrecip_scheme (const char *recip_string)
> +{
> + unsigned int result_mask = RECIP_MASK_NONE;
> +
> + if (recip_string)
> + {
> + char *p = ASTRDUP (recip_string);
> + char *q;
> + unsigned int mask, i;
> + bool invert;
> +
> + while ((q = strtok (p, ",")) != NULL)
> + {
> + p = NULL;
> + if (*q == '!')
> + {
> + invert = true;
> + q++;
> + }
> + else
> + invert = false;
> +
> + if (!strcmp (q, "default"))
> + mask = RECIP_MASK_ALL;
> + else
> + {
> + for (i = 0; i < ARRAY_SIZE (recip_options); i++)
> + if (!strcmp (q, recip_options[i].string))
> + {
> + mask = recip_options[i].mask;
> + break;
> + }
> +
> + if (i == ARRAY_SIZE (recip_options))
> + {
> + error ("unknown option for %<-mrecip=%s%>", q);
> + invert = false;
> + mask = RECIP_MASK_NONE;
> + }
> + }
> +
> + if (invert)
> + result_mask &= ~mask;
> + else
> + result_mask |= mask;
> + }
> + }
> + return result_mask;
> +}
> +
> +/* Generate -mrecip= argument based on the mask. */
> +const char*
> +loongarch_generate_mrecip_scheme (unsigned int mask)
> +{
> + static char recip_scheme_str[128];
> + int p = 0, tmp;
> +
> + switch (mask)
> + {
> + case RECIP_MASK_ALL:
> + return "all";
> +
> + case RECIP_MASK_NONE:
> + return "none";
> + }
> +
> + for (unsigned long i = 2; i < ARRAY_SIZE (recip_options); i++)
> + {
> + if (mask & recip_options[i].mask)
> + {
> + if ((tmp = strlen (recip_options[i].string) + 1) >= 127 - p)
> + gcc_unreachable ();
> +
> + recip_scheme_str[p] = ',';
> + strcpy (recip_scheme_str + p + 1, recip_options[i].string);
> + p += tmp;
> + }
> + }
> + recip_scheme_str[p] = '\0';
> + return recip_scheme_str + 1;
> +}
> +
> +
> +
> +/* Refresh the switches acccording to the resolved loongarch_target struct. */
> +void
> +loongarch_target_option_override (struct loongarch_target *target,
> + struct gcc_options *opts,
> + struct gcc_options *opts_set)
> +{
> + loongarch_update_gcc_opt_status (target, opts, opts_set);
> +
> + /* alignments */
> + if (opts->x_flag_align_functions && !opts->x_str_align_functions)
> + opts->x_str_align_functions
> + = loongarch_cpu_align[target->cpu_tune].function;
> +
> + if (opts->x_flag_align_labels && !opts->x_str_align_labels)
> + opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
> +
> + /* Set up parameters to be used in prefetching algorithm. */
> + int simultaneous_prefetches
> + = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
> +
> + SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
> + simultaneous_prefetches);
> +
> + SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
> + loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
> +
> + SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
> + loongarch_cpu_cache[target->cpu_tune].l1d_size);
> +
> + SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
> + loongarch_cpu_cache[target->cpu_tune].l2d_size);
> +
> + /* Other arch-specific overrides. */
> + switch (target->cpu_arch)
> + {
> + case CPU_LA664:
> + /* Enable -mrecipe=all for LA664 by default. */
> + if (!opts_set->x_recip_mask)
> + {
> + opts->x_recip_mask = RECIP_MASK_ALL;
> + opts_set->x_recip_mask = 1;
> + }
> + }
> +
> + /* -mrecip= */
> + opts->x_la_recip_name
> + = loongarch_generate_mrecip_scheme (opts->x_recip_mask);
> +
> + /* Decide which rtx_costs structure to use. */
> + if (opts->x_optimize_size)
> + loongarch_cost = &loongarch_rtx_cost_optimize_size;
> + else
> + loongarch_cost = &loongarch_cpu_rtx_cost_data[target->cpu_tune];
> +
> + /* If the user hasn't specified a branch cost, use the processor's
> + default. */
> + if (!opts_set->x_la_branch_cost)
> + opts->x_la_branch_cost = loongarch_cost->branch_cost;
> +
> + /* other stuff */
> + if (ABI_LP64_P (target->abi.base))
> + opts->x_flag_pcc_struct_return = 0;
> +
> + switch (target->cmodel)
> + {
> + case CMODEL_EXTREME:
> + if (opts->x_flag_plt)
> + {
> + if (opts_set->x_flag_plt)
> + error ("code model %qs is not compatible with %s",
> + "extreme", "-fplt");
> + opts->x_flag_plt = 0;
> + }
> + break;
> +
> + case CMODEL_TINY_STATIC:
> + case CMODEL_MEDIUM:
> + case CMODEL_NORMAL:
> + case CMODEL_TINY:
> + case CMODEL_LARGE:
> + break;
> +
> + default:
> + gcc_unreachable ();
> + }
> +}
> +
> +
> +/* Resolve options that's not covered by la_target. */
> +void
> +loongarch_init_misc_options (struct gcc_options *opts,
> + struct gcc_options *opts_set)
> +{
> + if (opts->x_flag_pic)
> + opts->x_g_switch_value = 0;
> +
> + /* -mrecip options. */
> + opts->x_recip_mask = loongarch_parse_mrecip_scheme (opts->x_la_recip_name);
> +
> +#define INIT_TARGET_FLAG(NAME, INIT) \
> + { \
> + if (!(opts_set->x_target_flags & MASK_##NAME)) \
> + { \
> + if (INIT) \
> + opts->x_target_flags |= MASK_##NAME; \
> + else \
> + opts->x_target_flags &= ~MASK_##NAME; \
> + } \
> + }
> +
> + /* Enable conditional moves for int and float by default. */
> + INIT_TARGET_FLAG (COND_MOVE_INT, 1)
> + INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1)
> +
> + /* Set mrelax default. */
> + INIT_TARGET_FLAG (LINKER_RELAXATION,
> + HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION)
> +
> +#undef INIT_TARGET_FLAG
> +
> + /* Set mexplicit-relocs default. */
> + if (opts->x_la_opt_explicit_relocs == M_OPT_UNSET)
> + opts->x_la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS
> + ? (TARGET_LINKER_RELAXATION
> + ? EXPLICIT_RELOCS_AUTO
> + : EXPLICIT_RELOCS_ALWAYS)
> + : EXPLICIT_RELOCS_NONE);
> +
> + /* Enable sw prefetching at -O3 and higher. */
> + if (opts->x_flag_prefetch_loop_arrays < 0
> + && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
> + && !opts->x_optimize_size)
> + opts->x_flag_prefetch_loop_arrays = 1;
> +
> + if (TARGET_DIRECT_EXTERN_ACCESS_OPTS_P (opts) && opts->x_flag_shlib)
> + error ("%qs cannot be used for compiling a shared library",
> + "-mdirect-extern-access");
> +
> + /* Enforce that interval is the same size as size so the mid-end does the
> + right thing. */
> + SET_OPTION_IF_UNSET (opts, opts_set,
> + param_stack_clash_protection_probe_interval,
> + param_stack_clash_protection_guard_size);
> +}
> diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
> index 586e67e65ee..2d9f59296e7 100644
> --- a/gcc/config/loongarch/loongarch-opts.h
> +++ b/gcc/config/loongarch/loongarch-opts.h
> @@ -30,6 +30,10 @@ along with GCC; see the file COPYING3. If not see
> /* Target configuration */
> extern struct loongarch_target la_target;
>
> +/* RTL cost information */
> +extern const struct loongarch_rtx_cost_data *loongarch_cost;
> +
> +
> /* Initialize loongarch_target from separate option variables. */
> void
> loongarch_init_target (struct loongarch_target *target,
> @@ -46,11 +50,30 @@ loongarch_config_target (struct loongarch_target *target,
> struct loongarch_flags *flags,
> int follow_multilib_list_p);
>
> +
> +/* Refresh the switches acccording to the resolved loongarch_target struct. */
> +void
> +loongarch_target_option_override (struct loongarch_target *target,
> + struct gcc_options *opts,
> + struct gcc_options *opts_set);
> +
> +
> /* option status feedback for "gcc --help=target -Q" */
> void
> loongarch_update_gcc_opt_status (struct loongarch_target *target,
> struct gcc_options *opts,
> struct gcc_options *opts_set);
> +
> +
> +/* Parser for -mrecip=<recip_string>. */
> +unsigned int
> +loongarch_parse_mrecip_scheme (const char *recip_string);
> +
> +
> +/* Resolve options that's not covered by la_target. */
> +void
> +loongarch_init_misc_options (struct gcc_options *opts,
> + struct gcc_options *opts_set);
> #endif
>
> /* Flag status */
> @@ -80,9 +103,7 @@ struct loongarch_flags {
> #define TARGET_DOUBLE_FLOAT_ABI (la_target.abi.base == ABI_BASE_LP64D)
>
> #define TARGET_64BIT (la_target.isa.base == ISA_BASE_LA64)
> -#define TARGET_ABI_LP64 (la_target.abi.base == ABI_BASE_LP64D \
> - || la_target.abi.base == ABI_BASE_LP64F \
> - || la_target.abi.base == ABI_BASE_LP64S)
> +#define TARGET_ABI_LP64 ABI_LP64_P(la_target.abi.base)
>
> #define ISA_HAS_LSX \
> (la_target.isa.simd == ISA_EXT_SIMD_LSX \
> diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
> index 030957db4e7..a69a203fbe6 100644
> --- a/gcc/config/loongarch/loongarch.cc
> +++ b/gcc/config/loongarch/loongarch.cc
> @@ -208,9 +208,6 @@ const enum reg_class loongarch_regno_to_class[FIRST_PSEUDO_REGISTER] = {
> FRAME_REGS, FRAME_REGS
> };
>
> -/* Which cost information to use. */
> -static const struct loongarch_rtx_cost_data *loongarch_cost;
> -
> /* Information about a single argument. */
> struct loongarch_arg_info
> {
> @@ -5911,17 +5908,6 @@ loongarch_print_operand_punctuation (FILE *file, int ch)
> }
> }
>
> -/* Initialize loongarch_print_operand_punct. */
> -
> -static void
> -loongarch_init_print_operand_punct (void)
> -{
> - const char *p;
> -
> - for (p = ".$"; *p; p++)
> - loongarch_print_operand_punct[(unsigned char) *p] = true;
> -}
> -
> /* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
> associated with condition CODE. Print the condition part of the
> opcode to FILE. */
> @@ -7625,118 +7611,15 @@ loongarch_init_machine_status (void)
> }
>
> static void
> -loongarch_cpu_option_override (struct loongarch_target *target,
> - struct gcc_options *opts,
> - struct gcc_options *opts_set)
> -{
> - /* alignments */
> - if (opts->x_flag_align_functions && !opts->x_str_align_functions)
> - opts->x_str_align_functions
> - = loongarch_cpu_align[target->cpu_tune].function;
> -
> - if (opts->x_flag_align_labels && !opts->x_str_align_labels)
> - opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
> -
> - /* Set up parameters to be used in prefetching algorithm. */
> - int simultaneous_prefetches
> - = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
> -
> - SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
> - simultaneous_prefetches);
> -
> - SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
> - loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
> -
> - SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
> - loongarch_cpu_cache[target->cpu_tune].l1d_size);
> -
> - SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
> - loongarch_cpu_cache[target->cpu_tune].l2d_size);
> -}
> -
> -static void
> -loongarch_option_override_internal (struct gcc_options *opts,
> - struct gcc_options *opts_set)
> +loongarch_global_init (void)
> {
> - int i, regno, mode;
> -
> - if (flag_pic)
> - g_switch_value = 0;
> -
> - loongarch_init_target (&la_target,
> - la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
> - la_opt_simd, la_opt_abi_base, la_opt_abi_ext,
> - la_opt_cmodel, opts->x_la_isa_evolution,
> - opts_set->x_la_isa_evolution);
> -
> - /* Handle target-specific options: compute defaults/conflicts etc. */
> - loongarch_config_target (&la_target, NULL, 0);
> -
> - loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
> - loongarch_cpu_option_override (&la_target, opts, opts_set);
> -
> - if (TARGET_ABI_LP64)
> - flag_pcc_struct_return = 0;
> -
> - /* Decide which rtx_costs structure to use. */
> - if (optimize_size)
> - loongarch_cost = &loongarch_rtx_cost_optimize_size;
> - else
> - loongarch_cost = &loongarch_cpu_rtx_cost_data[la_target.cpu_tune];
> -
> - /* If the user hasn't specified a branch cost, use the processor's
> - default. */
> - if (la_branch_cost == 0)
> - la_branch_cost = loongarch_cost->branch_cost;
> -
> - /* Enable sw prefetching at -O3 and higher. */
> - if (opts->x_flag_prefetch_loop_arrays < 0
> - && (opts->x_optimize >= 3 || opts->x_flag_profile_use)
> - && !opts->x_optimize_size)
> - opts->x_flag_prefetch_loop_arrays = 1;
> -
> - if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
> - error ("%qs cannot be used for compiling a shared library",
> - "-mdirect-extern-access");
> -
> - switch (la_target.cmodel)
> - {
> - case CMODEL_EXTREME:
> - if (opts->x_flag_plt)
> - {
> - if (global_options_set.x_flag_plt)
> - error ("code model %qs is not compatible with %s",
> - "extreme", "-fplt");
> - opts->x_flag_plt = 0;
> - }
> - break;
> -
> - case CMODEL_TINY_STATIC:
> - case CMODEL_MEDIUM:
> - case CMODEL_NORMAL:
> - case CMODEL_TINY:
> - case CMODEL_LARGE:
> - break;
> -
> - default:
> - gcc_unreachable ();
> - }
> -
> - /* Validate the guard size. */
> - int guard_size = param_stack_clash_protection_guard_size;
> -
> - /* Enforce that interval is the same size as size so the mid-end does the
> - right thing. */
> - SET_OPTION_IF_UNSET (opts, &global_options_set,
> - param_stack_clash_protection_probe_interval,
> - guard_size);
> -
> - loongarch_init_print_operand_punct ();
> + /* Initialize loongarch_print_operand_punct. */
> + for (const char *p = ".$"; *p; p++)
> + loongarch_print_operand_punct[(unsigned char) *p] = true;
>
> /* Set up array to map GCC register number to debug register number.
> Ignore the special purpose register numbers. */
> -
> - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> + for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> {
> if (GP_REG_P (i) || FP_REG_P (i))
> loongarch_dwarf_regno[i] = i;
> @@ -7745,115 +7628,53 @@ loongarch_option_override_internal (struct gcc_options *opts,
> }
>
> /* Set up loongarch_hard_regno_mode_ok. */
> - for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
> - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> + for (int mode = 0; mode < MAX_MACHINE_MODE; mode++)
> + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> loongarch_hard_regno_mode_ok_p[mode][regno]
> = loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
>
> /* Function to allocate machine-dependent function status. */
> init_machine_status = &loongarch_init_machine_status;
> +};
>
> - /* -mrecip options. */
> - static struct
> - {
> - const char *string; /* option name. */
> - unsigned int mask; /* mask bits to set. */
> - }
> - const recip_options[] = {
> - { "all", RECIP_MASK_ALL },
> - { "none", RECIP_MASK_NONE },
> - { "div", RECIP_MASK_DIV },
> - { "sqrt", RECIP_MASK_SQRT },
> - { "rsqrt", RECIP_MASK_RSQRT },
> - { "vec-div", RECIP_MASK_VEC_DIV },
> - { "vec-sqrt", RECIP_MASK_VEC_SQRT },
> - { "vec-rsqrt", RECIP_MASK_VEC_RSQRT },
> - };
> -
> - if (la_recip_name)
> - {
> - char *p = ASTRDUP (la_recip_name);
> - char *q;
> - unsigned int mask, i;
> - bool invert;
> -
> - while ((q = strtok (p, ",")) != NULL)
> - {
> - p = NULL;
> - if (*q == '!')
> - {
> - invert = true;
> - q++;
> - }
> - else
> - invert = false;
> -
> - if (!strcmp (q, "default"))
> - mask = RECIP_MASK_ALL;
> - else
> - {
> - for (i = 0; i < ARRAY_SIZE (recip_options); i++)
> - if (!strcmp (q, recip_options[i].string))
> - {
> - mask = recip_options[i].mask;
> - break;
> - }
> -
> - if (i == ARRAY_SIZE (recip_options))
> - {
> - error ("unknown option for %<-mrecip=%s%>", q);
> - invert = false;
> - mask = RECIP_MASK_NONE;
> - }
> - }
> -
> - if (invert)
> - recip_mask &= ~mask;
> - else
> - recip_mask |= mask;
> - }
> - }
> - if (la_recip)
> - recip_mask |= RECIP_MASK_ALL;
> - if (!ISA_HAS_FRECIPE)
> - recip_mask = RECIP_MASK_NONE;
> -
> -#define INIT_TARGET_FLAG(NAME, INIT) \
> - { \
> - if (!(target_flags_explicit & MASK_##NAME)) \
> - { \
> - if (INIT) \
> - target_flags |= MASK_##NAME; \
> - else \
> - target_flags &= ~MASK_##NAME; \
> - } \
> - }
> -
> - /* Enable conditional moves for int and float by default. */
> - INIT_TARGET_FLAG (COND_MOVE_INT, 1)
> - INIT_TARGET_FLAG (COND_MOVE_FLOAT, 1)
> -
> - /* Set mrelax default. */
> - INIT_TARGET_FLAG (LINKER_RELAXATION,
> - HAVE_AS_MRELAX_OPTION && HAVE_AS_COND_BRANCH_RELAXATION)
> +static void
> +loongarch_option_override_internal (struct loongarch_target *target,
> + struct gcc_options *opts,
> + struct gcc_options *opts_set)
> +{
> + /* Handle options not covered by struct loongarch_target. */
> + loongarch_init_misc_options (opts, opts_set);
> +
> + /* Resolve the target struct. */
> + loongarch_init_target (target,
> + opts->x_la_opt_cpu_arch,
> + opts->x_la_opt_cpu_tune,
> + opts->x_la_opt_fpu,
> + opts->x_la_opt_simd,
> + opts->x_la_opt_abi_base,
> + opts->x_la_opt_abi_ext,
> + opts->x_la_opt_cmodel,
> + opts->x_la_isa_evolution,
> + opts_set->x_la_isa_evolution);
>
> -#undef INIT_TARGET_FLAG
> + loongarch_config_target (target, NULL, 0);
>
> - if (la_opt_explicit_relocs == M_OPT_UNSET)
> - la_opt_explicit_relocs = (HAVE_AS_EXPLICIT_RELOCS
> - ? (TARGET_LINKER_RELAXATION
> - ? EXPLICIT_RELOCS_AUTO
> - : EXPLICIT_RELOCS_ALWAYS)
> - : EXPLICIT_RELOCS_NONE);
> + /* Override some options according to the resolved target. */
> + loongarch_target_option_override (target, opts, opts_set);
> }
>
> -
> /* Implement TARGET_OPTION_OVERRIDE. */
>
> static void
> loongarch_option_override (void)
> {
> - loongarch_option_override_internal (&global_options, &global_options_set);
> + /* Setting up the target configuration. */
> + loongarch_option_override_internal (&la_target,
> + &global_options,
> + &global_options_set);
> +
> + /* Global initializations. */
> + loongarch_global_init ();
> }
>
> /* Implement TARGET_OPTION_SAVE. */
> diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
> index 888a633961d..23bb3254883 100644
> --- a/gcc/config/loongarch/loongarch.h
> +++ b/gcc/config/loongarch/loongarch.h
> @@ -710,12 +710,18 @@ enum reg_class
> | RECIP_MASK_RSQRT | RECIP_MASK_VEC_SQRT \
> | RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_RSQRT)
>
> -#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0 || TARGET_uARCH_LA664)
> -#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0 || TARGET_uARCH_LA664)
> -#define TARGET_RECIP_RSQRT ((recip_mask & RECIP_MASK_RSQRT) != 0 || TARGET_uARCH_LA664)
> -#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0 || TARGET_uARCH_LA664)
> -#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 || TARGET_uARCH_LA664)
> -#define TARGET_RECIP_VEC_RSQRT ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 || TARGET_uARCH_LA664)
> +#define TARGET_RECIP_DIV \
> + ((recip_mask & RECIP_MASK_DIV) != 0 && ISA_HAS_FRECIPE)
> +#define TARGET_RECIP_SQRT \
> + ((recip_mask & RECIP_MASK_SQRT) != 0 && ISA_HAS_FRECIPE)
> +#define TARGET_RECIP_RSQRT \
> + ((recip_mask & RECIP_MASK_RSQRT) != 0 && ISA_HAS_FRECIPE)
> +#define TARGET_RECIP_VEC_DIV \
> + ((recip_mask & RECIP_MASK_VEC_DIV) != 0 && ISA_HAS_FRECIPE)
> +#define TARGET_RECIP_VEC_SQRT \
> + ((recip_mask & RECIP_MASK_VEC_SQRT) != 0 && ISA_HAS_FRECIPE)
> +#define TARGET_RECIP_VEC_RSQRT \
> + ((recip_mask & RECIP_MASK_VEC_RSQRT) != 0 && ISA_HAS_FRECIPE)
>
> /* 1 if N is a possible register number for function argument passing.
> We have no FP argument registers when soft-float. */
> diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
> index f10fcdd968c..317cd11a67c 100644
> --- a/gcc/config/loongarch/loongarch.opt
> +++ b/gcc/config/loongarch/loongarch.opt
> @@ -205,14 +205,14 @@ mexplicit-relocs
> Target Alias(mexplicit-relocs=, always, none)
> Use %reloc() assembly operators (for backward compatibility).
>
> -mrecip
> -Target RejectNegative Var(la_recip) Save
> -Generate approximate reciprocal divide and square root for better throughput.
> -
> mrecip=
> Target RejectNegative Joined Var(la_recip_name) Save
> Control generation of reciprocal estimates.
>
> +mrecip
> +Target Alias(mrecip=, all, none)
> +Generate approximate reciprocal divide and square root for better throughput.
> +
> ; The code model option names for -mcmodel.
> Enum
> Name(cmodel) Type(int)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-04-01 1:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-30 8:43 [PATCH v4] LoongArch: Split loongarch_option_override_internal into smaller procedures Yang Yujie
2024-03-30 8:45 ` Yang Yujie
2024-04-01 1:17 ` [pushed][PATCH " chenglulu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).