diff mbox

[ARM] : PR67745: Fix function alignment after __attribute__ 2/2

Message ID 562105DA.6070005@st.com
State New
Headers show

Commit Message

Christian Bruel Oct. 16, 2015, 2:12 p.m. UTC
committed patch attached.
with the default_relayout_function replaced by hook_void_tree as 
suggested by Ramana,
diff mbox

Patch

Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 228903)
+++ gcc/ChangeLog	(revision 228904)
@@ -1,3 +1,13 @@ 
+2015-10-16  Christian Bruel  <christian.bruel@st.com>
+
+	PR target/67745
+	* config/arm/arm.h (FUNCTION_BOUNDARY): Move optimize_size condition to:
+	* config/arm/arm.c (arm_option_override_internal): Call
+	arm_override_options_after_change_1.
+	(arm_override_options_after_change): New function.
+	(arm_override_options_after_change_1): Likewise.
+	(TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define hook.
+
 2015-10-11  Jan Hubicka  <hubicka@ucw.cz>
 
 	Revert:
Index: gcc/testsuite/gcc.target/arm/attr-align1.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr-align1.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/attr-align1.c	(revision 228904)
@@ -0,0 +1,27 @@ 
+/* PR target/67745
+   Verify alignment when both attribute optimize and target are used.  */
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+
+void
+__attribute__ ((target ("arm")))
+bar()
+{
+}
+
+void
+__attribute__ ((target ("thumb")))
+__attribute__ ((optimize ("Os")))
+foo()
+{
+}
+
+void
+__attribute__ ((target ("thumb")))
+__attribute__ ((optimize ("O2")))
+rab()
+{
+}
+
+/* { dg-final { scan-assembler-times ".align\[ \t]2" 2 } } */
+/* { dg-final { scan-assembler ".align\[ \t]1" } } */
Index: gcc/testsuite/gcc.target/arm/no-align.c
===================================================================
--- gcc/testsuite/gcc.target/arm/no-align.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/no-align.c	(revision 228904)
@@ -0,0 +1,12 @@ 
+/* PR target/67745
+   Verify that -mthumb code is not aligned.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mthumb -fno-align-functions" }  */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+
+void
+foo()
+{
+}
+
+/* { dg-final { scan-assembler-not ".align\[ \t]2" } } */
Index: gcc/testsuite/gcc.target/arm/attr-align2.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr-align2.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/attr-align2.c	(revision 228904)
@@ -0,0 +1,15 @@ 
+/* PR target/67745
+   Verify alignment when attribute optimize is used.  */
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+/* { dg-options "-O2 -mthumb" }  */
+
+/* Check that thumb code is always 2 bytes aligned for -Os.  */
+
+void
+__attribute__ ((optimize("Os")))
+foo()
+{
+}
+
+/* { dg-final { scan-assembler ".align\[ \t]1" } } */
Index: gcc/testsuite/gcc.target/arm/attr-align3.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr-align3.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/attr-align3.c	(revision 228904)
@@ -0,0 +1,13 @@ 
+/* PR target/67745
+   Verify alignment when attribute target is used.  */
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { arm_thumb1_ok || arm_thumb2_ok } } } */
+/* { dg-options "-Os -mthumb" }  */
+
+/* Check that arm code is always 4 bytes aligned.  */
+void  __attribute__ ((target ("arm")))
+c(void)
+{
+}
+
+/* { dg-final { scan-assembler-not ".align\[ \t]1" } } */
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 228903)
+++ gcc/testsuite/ChangeLog	(revision 228904)
@@ -1,3 +1,11 @@ 
+2015-10-16  Christian Bruel  <christian.bruel@st.com>
+
+	PR target/67745
+        * gcc.target/arm/no-align.c: New test.
+        * gcc.target/arm/attr-align1.c: New test.
+        * gcc.target/arm/attr-align2.c: New test.
+        * gcc.target/arm/attr-align3.c: New test.
+
 2015-10-11  Jan Hubicka  <hubicka@ucw.cz>
 
 	* gcc.c-torture/compile/icfmatch.c: Add testcase
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 228903)
+++ gcc/config/arm/arm.c	(revision 228904)
@@ -246,6 +246,7 @@ 
 static void arm_expand_builtin_va_start (tree, rtx);
 static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 static void arm_option_override (void);
+static void arm_override_options_after_change (void);
 static void arm_option_print (FILE *, int, struct cl_target_option *);
 static void arm_set_current_function (tree);
 static bool arm_can_inline_p (tree, tree);
@@ -407,6 +408,9 @@ 
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE arm_option_override
 
+#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE arm_override_options_after_change
+
 #undef TARGET_OPTION_PRINT
 #define TARGET_OPTION_PRINT arm_option_print
 
@@ -2810,11 +2814,29 @@ 
 /* Options after initial target override.  */
 static GTY(()) tree init_optimize;
 
+static void
+arm_override_options_after_change_1 (struct gcc_options *opts)
+{
+  if (opts->x_align_functions <= 0)
+    opts->x_align_functions = TARGET_THUMB_P (opts->x_target_flags)
+      && opts->x_optimize_size ? 2 : 4;
+}
+
+/* Implement targetm.override_options_after_change.  */
+
+static void
+arm_override_options_after_change (void)
+{
+  arm_override_options_after_change_1 (&global_options);
+}
+
 /* Reset options between modes that the user has specified.  */
 static void
 arm_option_override_internal (struct gcc_options *opts,
 			      struct gcc_options *opts_set)
 {
+  arm_override_options_after_change_1 (opts);
+
   if (TARGET_THUMB_P (opts->x_target_flags)
       && !(ARM_FSET_HAS_CPU1 (insn_flags, FL_THUMB)))
     {
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 228903)
+++ gcc/config/arm/arm.h	(revision 228904)
@@ -565,7 +565,7 @@ 
 #define PREFERRED_STACK_BOUNDARY \
     (arm_abi == ARM_ABI_ATPCS ? 64 : STACK_BOUNDARY)
 
-#define FUNCTION_BOUNDARY  ((TARGET_THUMB && optimize_size) ? 16 : 32)
+#define FUNCTION_BOUNDARY           (TARGET_THUMB ? 16 : 32)
 
 /* The lowest bit is used to indicate Thumb-mode functions, so the
    vbit must go into the delta field of pointers to member
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 228911)
+++ gcc/doc/tm.texi	(revision 228912)
@@ -9985,6 +9985,10 @@ 
 specific target options and the caller does not use the same options.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_RELAYOUT_FUNCTION (tree @var{fndecl})
+This target hook fixes function @var{fndecl} after attributes are processed. Default does nothing. On ARM, the default function's alignment is updated with the attribute target.
+@end deftypefn
+
 @node Emulated TLS
 @section Emulating TLS
 @cindex Emulated TLS
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 228911)
+++ gcc/doc/tm.texi.in	(revision 228912)
@@ -7274,6 +7274,8 @@ 
 
 @hook TARGET_CAN_INLINE_P
 
+@hook TARGET_RELAYOUT_FUNCTION
+
 @node Emulated TLS
 @section Emulating TLS
 @cindex Emulated TLS
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 228911)
+++ gcc/target.def	(revision 228912)
@@ -5620,6 +5620,12 @@ 
  bool, (tree caller, tree callee),
  default_target_can_inline_p)
 
+DEFHOOK
+(relayout_function,
+"This target hook fixes function @var{fndecl} after attributes are processed. Default does nothing. On ARM, the default function's alignment is updated with the attribute target.",
+ void, (tree fndecl),
+ hook_void_tree)
+
 HOOK_VECTOR_END (target_option)
 
 /* For targets that need to mark extra registers as live on entry to
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 228911)
+++ gcc/ChangeLog	(revision 228912)
@@ -1,5 +1,18 @@ 
 2015-10-16  Christian Bruel  <christian.bruel@st.com>
 
+ 	PR target/67745
+ 	* config/arm/arm.h (FUNCTION_BOUNDARY): Use FUNCTION_BOUNDARY_P.
+ 	(FUNCTION_BOUNDARY_P): New macro:
+ 	* config/arm/arm.c (TARGET_RELAYOUT_FUNCTION, arm_relayout_function): 
+ 	New hook.
+ 	* doc/tm.texi.in (TARGET_RELAYOUT_FUNCTION): Document.
+ 	* doc/tm.texi (TARGET_RELAYOUT_FUNCTION): New hook.
+ 	* gcc/target.def (TARGET_RELAYOUT_FUNCTION): Likewise.
+ 	* gcc/function.c (allocate_struct_function): Call relayout_function hook.
+ 	* gcc/passes.c (rest_of_decl_compilation): Likewise.
+
+2015-10-16  Christian Bruel  <christian.bruel@st.com>
+
 	PR target/67745
 	* config/arm/arm.h (FUNCTION_BOUNDARY): Move optimize_size condition to:
 	* config/arm/arm.c (arm_option_override_internal): Call
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 228911)
+++ gcc/function.c	(revision 228912)
@@ -4840,6 +4840,9 @@ 
 	  for (tree parm = DECL_ARGUMENTS (fndecl); parm;
 	       parm = DECL_CHAIN (parm))
 	    relayout_decl (parm);
+
+	  /* Similarly relayout the function decl.  */
+	  targetm.target_option.relayout_function (fndecl);
 	}
 
       if (!abstract_p && aggregate_value_p (result, fndecl))
Index: gcc/passes.c
===================================================================
--- gcc/passes.c	(revision 228911)
+++ gcc/passes.c	(revision 228912)
@@ -253,6 +253,11 @@ 
 	}
 #endif
 
+      /* Now that we have activated any function-specific attributes
+	 that might affect function decl, particularly align, relayout it.  */
+      if (TREE_CODE (decl) == FUNCTION_DECL)
+	targetm.target_option.relayout_function (decl);
+
       timevar_pop (TV_VARCONST);
     }
   else if (TREE_CODE (decl) == TYPE_DECL
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 228911)
+++ gcc/config/arm/arm.c	(revision 228912)
@@ -250,6 +250,7 @@ 
 static void arm_option_print (FILE *, int, struct cl_target_option *);
 static void arm_set_current_function (tree);
 static bool arm_can_inline_p (tree, tree);
+static void arm_relayout_function (tree);
 static bool arm_valid_target_attribute_p (tree, tree, tree, int);
 static unsigned HOST_WIDE_INT arm_shift_truncation_mask (machine_mode);
 static bool arm_macro_fusion_p (void);
@@ -405,6 +406,9 @@ 
 #undef TARGET_CAN_INLINE_P
 #define TARGET_CAN_INLINE_P arm_can_inline_p
 
+#undef TARGET_RELAYOUT_FUNCTION
+#define TARGET_RELAYOUT_FUNCTION arm_relayout_function
+
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE arm_option_override
 
@@ -29825,6 +29829,23 @@ 
   return true;
 }
 
+/* Hook to fix function's alignment affected by target attribute.  */
+
+static void
+arm_relayout_function (tree fndecl)
+{
+  if (DECL_USER_ALIGN (fndecl))
+    return;
+
+  tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+  if (!callee_tree)
+    callee_tree = target_option_default_node;
+
+  DECL_ALIGN (fndecl) =
+    FUNCTION_BOUNDARY_P (TREE_TARGET_OPTION (callee_tree)->x_target_flags);
+}
+
 /* Inner function to process the attribute((target(...))), take an argument and
    set the current options from the argument.  If we have a list, recursively
    go over the list.  */
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 228911)
+++ gcc/config/arm/arm.h	(revision 228912)
@@ -565,7 +565,8 @@ 
 #define PREFERRED_STACK_BOUNDARY \
     (arm_abi == ARM_ABI_ATPCS ? 64 : STACK_BOUNDARY)
 
-#define FUNCTION_BOUNDARY           (TARGET_THUMB ? 16 : 32)
+#define FUNCTION_BOUNDARY_P(flags)  (TARGET_THUMB_P (flags) ? 16 : 32)
+#define FUNCTION_BOUNDARY           (FUNCTION_BOUNDARY_P (target_flags))
 
 /* The lowest bit is used to indicate Thumb-mode functions, so the
    vbit must go into the delta field of pointers to member