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.
@@ -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
@@ -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,
@@ -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.
@@ -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 *);
@@ -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")))