diff mbox

[ARM] attribute target (thumb,arm) [6/6] -> [7/7]

Message ID 5492E5B9.6070503@st.com
State New
Headers show

Commit Message

Christian Bruel Dec. 18, 2014, 2:33 p.m. UTC
Hello Ramana,

I don't know if you have started to look at it, but the attribute 
support fails after upgrading.

This patch aims to catch up on the changes around the fipa_ra 
-masm-syntax-unified options since the initial posting. They were not 
tested/supported with the attribute, and of course generated new 
failures after an update, as they needs resetting depending on thumb mode.

It also fixes various minor thinkos, one that prevented global flags 
(e.g -fschedule_insns) depending on thumb mode to be correctly reset on 
situation were -mthumb was passed on the command line and thumb/arm 
attribute was used alternatively. The other is around the -mflip-thumb 
option setting.

Last, a minor fix in the test attr_arm-err.c that had false failures 
with conflicting -march.

Aside, a funny thing: The ACLE doc 
(https://gcc.gnu.org/onlinedocs/gcc/ARM-C-Language-Extensions-_0028ACLE_0029.html#ARM-C-Language-Extensions-_0028ACLE_0029) 
already as a visionary description of the attribute. I might have missed 
something but this time the doc comes earlier than the implementation 
:-) without the historical background.

Best Regards

Christian
diff mbox

Patch

2014-12-14  Christian Bruel  <christian.bruel@st.com>

	* config/arm/arm.c (arm_option_override_internal): add opts_set param. Use it to set 
	restrict_it. Handle flag_ipa_ra and inline_asm_unified.
	(arm_valid_target_attribute_tree): Add opts_set param.
	Initialize init_optimize.
	(init_optimize): New static variable.
	(thumb_flipper): Set.
	( arm_valid_target_attribute_p): Rewrite.
	config/arm/arm-protos.h	(arm_valid_target_attribute_tree): New opts_set param
	* config/arm/arm-c.c (arm_pragma_target_parse): Likewiese.
	* config/arm/arm.opt (inline_asm_unified): Save.

2014-12-14  Christian Bruel  <christian.bruel@st.com>

        * gcc.target/arm/attr_arm-err.c: Check conflicting -march options.

diff '--exclude=*~' '--exclude=.svn' -ru a/gcc/gcc/config/arm/arm.c b/gcc/gcc/config/arm/arm.c
--- a/gcc/gcc/config/arm/arm.c	2014-12-18 14:36:06.000000000 +0100
+++ b/gcc/gcc/config/arm/arm.c	2014-12-18 14:35:12.000000000 +0100
@@ -2625,9 +2625,16 @@ 
     }
 }
 
+/* True if -mflip-thumb should next add an attribute for the default
+   mode, false if it should next add an attribute for the opposite mode.  */
+static GTY(()) bool thumb_flipper;
+
+static GTY(()) tree init_optimize;
+
 /* Reset options between modes that the user has specified.  */
 static void
-arm_option_override_internal (struct gcc_options *opts)
+arm_option_override_internal (struct gcc_options *opts,
+			      struct gcc_options *opts_set)
 {
   if (TREE_TARGET_THUMB (opts) && !(insn_flags & FL_THUMB))
     {
@@ -2646,13 +2653,13 @@ 
   if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING)
     opts->x_target_flags |= MASK_INTERWORK;
 
-  if (restrict_default)
+  if (! opts_set->x_arm_restrict_it)
     opts->x_arm_restrict_it = arm_arch8;
 
   if (!TREE_TARGET_THUMB2 (opts))
     opts->x_arm_restrict_it = 0;
 
-  if (TREE_TARGET_THUMB1 (opts) && opts->x_flag_schedule_insns)
+  if (TREE_TARGET_THUMB1 (opts))
     {
       /* Don't warn since it's on by default in -O2.  */
       opts->x_flag_schedule_insns = 0;
@@ -2663,9 +2670,21 @@ 
   if (optimize_function_for_size_p (cfun) && TREE_TARGET_THUMB2 (opts))
     opts->x_flag_shrink_wrap = false;
 
+  /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
+     - epilogue_insns - does not accurately model the corresponding insns
+     emitted in the asm file.  In particular, see the comment in thumb_exit
+     'Find out how many of the (return) argument registers we can corrupt'.
+     As a consequence, the epilogue may clobber registers without fipa-ra
+     finding out about it.  Therefore, disable fipa-ra in Thumb1 mode.
+     TODO: Accurately model clobbers for epilogue_insns and reenable
+     fipa-ra.  */
+  if (TREE_TARGET_THUMB1 (opts))
+    opts->x_flag_ipa_ra = 0;
+
   /* Thumb2 inline assembly code should always use unified syntax.
      This will apply to ARM and Thumb1 eventually.  */
-  opts->x_inline_asm_unified = TREE_TARGET_THUMB2 (opts);
+  if (TREE_TARGET_THUMB2 (opts))
+      opts->x_inline_asm_unified = 1;
 }
 
 /* Fix up any incompatible options that the user has specified.  */
@@ -3127,27 +3146,17 @@ 
   if (target_slow_flash_data)
     arm_disable_literal_pool = true;
 
-  /* Override flags, but not the user's one.  */
-  restrict_default = (arm_restrict_it == 2);
-
   /* Disable scheduling fusion by default if it's not armv7 processor
      or doesn't prefer ldrd/strd.  */
   if (flag_schedule_fusion == 2
       && (!arm_arch7 || !current_tune->prefer_ldrd_strd))
     flag_schedule_fusion = 0;
 
-  /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
-     - epilogue_insns - does not accurately model the corresponding insns
-     emitted in the asm file.  In particular, see the comment in thumb_exit
-     'Find out how many of the (return) argument registers we can corrupt'.
-     As a consequence, the epilogue may clobber registers without fipa-ra
-     finding out about it.  Therefore, disable fipa-ra in Thumb1 mode.
-     TODO: Accurately model clobbers for epilogue_insns and reenable
-     fipa-ra.  */
-  if (TARGET_THUMB1)
-    flag_ipa_ra = 0;
+  /* Need to remember initial options before they are overriden
+     for default mode.  */
+  init_optimize = build_optimization_node (&global_options);
 
-  arm_option_override_internal (&global_options);
+  arm_option_override_internal (&global_options, &global_options_set);
   arm_option_check_internal (&global_options);
   arm_option_params_internal (&global_options);
 
@@ -3158,6 +3167,9 @@ 
      options.  */
   target_option_default_node = target_option_current_node
     = build_target_option_node (&global_options);
+
+  /* Init initial mode for testing.  */
+  thumb_flipper = TARGET_THUMB;
 }
 
 static void
@@ -29398,25 +29410,22 @@ 
 /* Return a TARGET_OPTION_NODE tree of the target options listed or NULL.  */
 
 tree
-arm_valid_target_attribute_tree (tree args, struct gcc_options *opts)
+arm_valid_target_attribute_tree (tree args, struct gcc_options *opts,
+				 struct gcc_options *opts_set)
 {
   tree t = NULL_TREE;
 
   if (!arm_valid_target_attribute_rec (args, opts))
     return NULL_TREE;
 
- t = build_target_option_node (opts);
-
   /* Do any overrides, such as global options arch=xxx.  */
-  arm_option_override_internal (opts);
+  arm_option_override_internal (opts, opts_set);
+
+  t = build_target_option_node (opts);
 
   return t;
 }
 
-/* True if -mflip-thumb should next add an attribute for the default
-   mode, false if it should next add an attribute for the opposite mode.  */
-static GTY(()) bool thumb_flipper = TARGET_THUMB;
-
 static void 
 add_attribute  (const char * mode, tree *attributes)
 {
@@ -29438,6 +29447,9 @@ 
 {
   const char *mode;
 
+  if (! TARGET_FLIP_THUMB)
+    return;
+
   if (TREE_CODE (fndecl) != FUNCTION_DECL || DECL_EXTERNAL(fndecl)
       || DECL_BUILT_IN (fndecl) || DECL_ARTIFICIAL (fndecl))
    return;
@@ -29450,9 +29462,6 @@ 
      return;
    }
 
-  if (! TARGET_FLIP_THUMB)
-    return;
-
   /* If there is already a setting don't change it.  */
   if (lookup_attribute ("target", *attributes) != NULL)
     return;
@@ -29469,17 +29478,18 @@ 
 arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
 			      tree args, int ARG_UNUSED (flags))
 {
-  tree cur_tree, new_optimize;
+  bool ret = true;
   struct gcc_options func_options;
+  tree cur_tree, new_optimize;
   gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
 
-  tree old_optimize = build_optimization_node (&global_options);
-
   /* Get the optimization options of the current function.  */
   tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
 
+  /* If the function changed the optimization levels as well as setting target
+     options, start with the optimizations specified.  */
   if (!func_optimize)
-    func_optimize = old_optimize;
+    func_optimize = init_optimize;
 
   /* Init func_options.  */
   memset (&func_options, 0, sizeof (func_options));
@@ -29490,26 +29500,20 @@ 
   cl_optimization_restore (&func_options,
 			   TREE_OPTIMIZATION (func_optimize));
 
-  cl_target_option_restore (&func_options,
-			    TREE_TARGET_OPTION (target_option_default_node));
-
   /* Set func_options flags with new target mode.  */
-  cur_tree = arm_valid_target_attribute_tree (args, &func_options);
+  cur_tree = arm_valid_target_attribute_tree (args, &func_options,
+					      &global_options_set);
 
   if (cur_tree == NULL_TREE)
-    return false;
+    ret = false;
 
   new_optimize = build_optimization_node (&func_options);
 
-  if (fndecl)
-    {
-      DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+  DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
 
-      if (old_optimize != new_optimize)
-	DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
-    }
+  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
 
-  return true;
+  return ret;
 }
 
 void
diff '--exclude=*~' '--exclude=.svn' -ru a/gcc/gcc/config/arm/arm-c.c b/gcc/gcc/config/arm/arm-c.c
--- a/gcc/gcc/config/arm/arm-c.c	2014-12-18 14:36:01.000000000 +0100
+++ b/gcc/gcc/config/arm/arm-c.c	2014-12-18 09:02:52.000000000 +0100
@@ -135,7 +135,8 @@ 
     }
   else
     {
-      cur_tree = arm_valid_target_attribute_tree (args,  &global_options);
+      cur_tree = arm_valid_target_attribute_tree (args,  &global_options,
+						  &global_options_set);
       if (cur_tree == NULL_TREE)
 	{
 	  cl_target_option_restore (&global_options,
diff '--exclude=*~' '--exclude=.svn' -ru a/gcc/gcc/config/arm/arm.opt b/gcc/gcc/config/arm/arm.opt
--- a/gcc/gcc/config/arm/arm.opt	2014-12-18 14:36:06.000000000 +0100
+++ b/gcc/gcc/config/arm/arm.opt	2014-12-18 14:19:16.000000000 +0100
@@ -277,5 +277,5 @@ 
 Assume loading data from flash is slower than fetching instructions.
 
 masm-syntax-unified
-Target Report Var(inline_asm_unified) Init(0)
+Target Report Var(inline_asm_unified) Init(0) Save
 Assume unified syntax for Thumb inline assembly code.
diff '--exclude=*~' '--exclude=.svn' -ru a/gcc/gcc/config/arm/arm-protos.h b/gcc/gcc/config/arm/arm-protos.h
--- a/gcc/gcc/config/arm/arm-protos.h	2014-12-18 14:36:01.000000000 +0100
+++ b/gcc/gcc/config/arm/arm-protos.h	2014-12-18 08:57:42.000000000 +0100
@@ -215,7 +215,8 @@ 
 extern void arm_mark_dllexport (tree);
 extern void arm_mark_dllimport (tree);
 extern bool arm_change_mode_p (tree);
-extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *);
+extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
+					     struct gcc_options *);
 #endif
 
 extern void arm_pr_long_calls (struct cpp_reader *);
diff '--exclude=*~' '--exclude=.svn' -ru a/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c b/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- a/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c	2014-12-18 14:35:58.000000000 +0100
+++ b/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c	2014-12-18 14:45:10.000000000 +0100
@@ -1,6 +1,7 @@ 
 /* Check that attribute target arm is rejected for M profile.  */
 /* { dg-do compile } */
 /* { dg-require-effective-target arm_arm_ok } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */
 /* { dg-add-options arm_arch_v6m } */
 
 int __attribute__((target("arm")))