public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH, gcc-7] Add riscv -mstrict-align option.
@ 2017-11-29  4:11 Jim Wilson
  0 siblings, 0 replies; only message in thread
From: Jim Wilson @ 2017-11-29  4:11 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jim Wilson

This patch is necessary for proper support of targets that don't directly
implement unaligned accesses.

Tested with a linux+busybox build and boot, and a gcc testsuite run.  There
were no regressions.  Also tested by hand on some small testcases to verify
that it was doing something useful.  Committed.

	gcc/
	Backport from mainline
	2017-11-04  Andrew Waterman  <andrew@sifive.com>

	* config/riscv/riscv.c (riscv_option_override): Conditionally set
	TARGET_STRICT_ALIGN based upon -mtune argument.

	Backport from mainline
	2017-05-04  Andrew Waterman  <andrew@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/config/riscv/riscv.c   | 24 +++++++++++++++++++++---
 gcc/config/riscv/riscv.h   | 10 ++++++----
 gcc/config/riscv/riscv.opt |  4 ++++
 gcc/doc/invoke.texi        |  6 ++++++
 4 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 6cb7113..7331271 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 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 6d02832..9b1857c 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.
-- 
2.7.4

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2017-11-29  0:01 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-29  4:11 [PATCH, gcc-7] Add riscv -mstrict-align option Jim Wilson

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).