On Thu, 04 May 2017 05:40:35 PDT (-0700), Palmer Dabbelt wrote: > From: Andrew Waterman <and...@sifive.com> > > The RISC-V user ISA permits misaligned accesses, but they may trap > and be emulated. That emulation software needs to be compiled assuming > strict alignment. > > Even when strict alignment is not required, set SLOW_UNALIGNED_ACCESS > based upon -mtune to avoid a performance pitfall. > > gcc/ChangeLog: > > 2017-05-04 Andrew Waterman <and...@sifive.com> > > * 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. > --- > gcc/ChangeLog | 16 ++++++++++++++++ > gcc/config/riscv/riscv.c | 20 +++++++++++++++++--- > gcc/config/riscv/riscv.h | 10 ++++++---- > gcc/config/riscv/riscv.opt | 4 ++++ > gcc/doc/invoke.texi | 6 ++++++ > 5 files changed, 49 insertions(+), 7 deletions(-) > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index fc85689..6b82034 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,19 @@ > +2017-05-04 Andrew Waterman <and...@sifive.com> > + > + * 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. > + > 2017-05-04 Kito Cheng <kito.ch...@gmail.com> > > * config/riscv/riscv.md: Unify indentation. > diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c > index d5928c3..f7fec4b 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; > @@ -3773,6 +3781,12 @@ 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. */ > + riscv_slow_unaligned_access = (cpu->tune_info->slow_unaligned_access > + || TARGET_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 8d4c75e..c5d134c 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 0466bb2..cfd0335 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 68a558e..d40f46f 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} > > @@ -20913,6 +20914,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.
Committed.