From c45915392bc2fe76d792553c697ca7adeda0f728 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Wed, 29 Nov 2017 00:00:01 +0000 Subject: [PATCH] Add riscv -mstrict-align option. gcc/ Backport from mainline 2017-11-04 Andrew Waterman * config/riscv/riscv.c (riscv_option_override): Conditionally set TARGET_STRICT_ALIGN based upon -mtune argument. Backport from mainline 2017-05-04 Andrew Waterman * config/riscv/riscv.opt (mstrict-align): New option. * config/riscv/riscv.h (STRICT_ALIGNMENT): Use it. Update comment. (SLOW_UNALIGNED_ACCESS): Define. (riscv_slow_unaligned_access): Declare. * config/riscv/riscv.c (riscv_tune_info): Add slow_unaligned_access field. (riscv_slow_unaligned_access): New variable. (rocket_tune_info): Set slow_unaligned_access to true. (optimize_size_tune_info): Set slow_unaligned_access to false. (riscv_cpu_info_table): Add entry for optimize_size_tune_info. (riscv_valid_lo_sum_p): Use TARGET_STRICT_ALIGN. (riscv_option_override): Set riscv_slow_unaligned_access. * doc/invoke.texi: Add -mstrict-align to RISC-V. From-SVN: r255221 --- gcc/ChangeLog | 23 +++++++++++++++++++++++ gcc/config/riscv/riscv.c | 24 +++++++++++++++++++++--- gcc/config/riscv/riscv.h | 10 ++++++---- gcc/config/riscv/riscv.opt | 4 ++++ gcc/doc/invoke.texi | 6 ++++++ 5 files changed, 60 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8472920d54b..c9e7c4a195c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,28 @@ 2017-11-28 Jim Wilson + Backport from mainline + 2017-11-04 Andrew Waterman + + * config/riscv/riscv.c (riscv_option_override): Conditionally set + TARGET_STRICT_ALIGN based upon -mtune argument. + + Backport from mainline + 2017-05-04 Andrew Waterman + + * config/riscv/riscv.opt (mstrict-align): New option. + * config/riscv/riscv.h (STRICT_ALIGNMENT): Use it. Update comment. + (SLOW_UNALIGNED_ACCESS): Define. + (riscv_slow_unaligned_access): Declare. + * config/riscv/riscv.c (riscv_tune_info): Add slow_unaligned_access + field. + (riscv_slow_unaligned_access): New variable. + (rocket_tune_info): Set slow_unaligned_access to true. + (optimize_size_tune_info): Set slow_unaligned_access to false. + (riscv_cpu_info_table): Add entry for optimize_size_tune_info. + (riscv_valid_lo_sum_p): Use TARGET_STRICT_ALIGN. + (riscv_option_override): Set riscv_slow_unaligned_access. + * doc/invoke.texi: Add -mstrict-align to RISC-V. + Backport from mainline 2017-11-07 Michael Clark diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 6cb7113dcd3..73312712d33 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -255,6 +255,7 @@ struct riscv_tune_info unsigned short issue_rate; unsigned short branch_cost; unsigned short memory_cost; + bool slow_unaligned_access; }; /* Information about one CPU we know about. */ @@ -268,6 +269,9 @@ struct riscv_cpu_info { /* Global variables for machine-dependent things. */ +/* Whether unaligned accesses execute very slowly. */ +bool riscv_slow_unaligned_access; + /* Which tuning parameters to use. */ static const struct riscv_tune_info *tune_info; @@ -301,7 +305,8 @@ static const struct riscv_tune_info rocket_tune_info = { {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */ 1, /* issue_rate */ 3, /* branch_cost */ - 5 /* memory_cost */ + 5, /* memory_cost */ + true, /* slow_unaligned_access */ }; /* Costs to use when optimizing for size. */ @@ -313,12 +318,14 @@ static const struct riscv_tune_info optimize_size_tune_info = { {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* int_div */ 1, /* issue_rate */ 1, /* branch_cost */ - 2 /* memory_cost */ + 2, /* memory_cost */ + false, /* slow_unaligned_access */ }; /* A table describing all the processors GCC knows about. */ static const struct riscv_cpu_info riscv_cpu_info_table[] = { { "rocket", &rocket_tune_info }, + { "size", &optimize_size_tune_info }, }; /* Return the riscv_cpu_info entry for the given name string. */ @@ -726,7 +733,8 @@ riscv_valid_lo_sum_p (enum riscv_symbol_type sym_type, enum machine_mode mode) /* We may need to split multiword moves, so make sure that each word can be accessed without inducing a carry. */ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD - && GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode)) + && (!TARGET_STRICT_ALIGN + || GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode))) return false; return true; @@ -3789,6 +3797,16 @@ riscv_option_override (void) RISCV_TUNE_STRING_DEFAULT); tune_info = optimize_size ? &optimize_size_tune_info : cpu->tune_info; + /* Use -mtune's setting for slow_unaligned_access, even when optimizing + for size. For architectures that trap and emulate unaligned accesses, + the performance cost is too great, even for -Os. Similarly, if + -m[no-]strict-align is left unspecified, heed -mtune's advice. */ + riscv_slow_unaligned_access = (cpu->tune_info->slow_unaligned_access + || TARGET_STRICT_ALIGN); + if ((target_flags_explicit & MASK_STRICT_ALIGN) == 0 + && cpu->tune_info->slow_unaligned_access) + target_flags |= MASK_STRICT_ALIGN; + /* If the user hasn't specified a branch cost, use the processor's default. */ if (riscv_branch_cost == 0) diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 8d4c75e6770..c5d134cbe57 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -126,10 +126,11 @@ along with GCC; see the file COPYING3. If not see /* There is no point aligning anything to a rounder boundary than this. */ #define BIGGEST_ALIGNMENT 128 -/* The user-level ISA permits misaligned accesses, but they may execute - extremely slowly and non-atomically. Some privileged architectures - do not permit them at all. It is best to enforce strict alignment. */ -#define STRICT_ALIGNMENT 1 +/* The user-level ISA permits unaligned accesses, but they are not required + of the privileged architecture. */ +#define STRICT_ALIGNMENT TARGET_STRICT_ALIGN + +#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) riscv_slow_unaligned_access /* Define this if you wish to imitate the way many other C compilers handle alignment of bitfields and the structures that contain @@ -864,6 +865,7 @@ while (0) #ifndef USED_FOR_TARGET extern const enum reg_class riscv_regno_to_class[]; extern bool riscv_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; +extern bool riscv_slow_unaligned_access; #endif #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \ diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 0466bb29d14..cfd0335d082 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -84,6 +84,10 @@ mcmodel= Target Report RejectNegative Joined Enum(code_model) Var(riscv_cmodel) Init(TARGET_DEFAULT_CMODEL) Specify the code model. +mstrict-align +Target Report Mask(STRICT_ALIGN) Save +Do not generate unaligned memory accesses. + Enum Name(code_model) Type(enum riscv_code_model) Known code models (for use with the -mcmodel= option): diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6d0283298c6..9b1857c1f39 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -975,6 +975,7 @@ See RS/6000 and PowerPC Options. -mtune=@var{processor-string} @gol -msmall-data-limit=@var{N-bytes} @gol -msave-restore -mno-save-restore @gol +-mstrict-align -mno-strict-align @gol -mcmodel=@var{code-model} @gol -mexplicit-relocs -mno-explicit-relocs @gol} @@ -20931,6 +20932,11 @@ Put global and static data smaller than @var{n} bytes into a special section @opindex msave-restore Use smaller but slower prologue and epilogue code. +@item -mstrict-align +@itemx -mno-strict-align +@opindex mstrict-align +Do not generate unaligned memory accesses. + @item -mcmodel=@var{code-model} @opindex mcmodel Specify the code model.