* [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th)
@ 2015-05-06 14:25 Christian Bruel
2015-05-06 23:04 ` Sandra Loosemore
2015-05-07 8:13 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
0 siblings, 2 replies; 15+ messages in thread
From: Christian Bruel @ 2015-05-06 14:25 UTC (permalink / raw)
To: gcc-patches, Ramana Radhakrishnan, Richard Earnshaw, Nicholas Clifton
[-- Attachment #1: Type: text/plain, Size: 373 bytes --]
Implements and document the hooks to support target_attributes.
The emission of blx is handled directly for armv5 to overcome a bug with
the current binutils that fails with calls to a static symbol in a
different section. (e.g .text -> .text.startup) in different modes.
(ref https://sourceware.org/bugzilla/show_bug.cgi?id=17505)
Regtests included
Thanks
Christian
[-- Attachment #2: p4.patch --]
[-- Type: text/x-patch, Size: 21142 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
* config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
(arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
(SWITCHABLE_TARGET): Define.
* config/arm/arm.c (arm_reset_previous_fndecl): New functions.
(arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
(arm_valid_target_attribute_p): Likewise.
(arm_set_current_function, arm_can_inline_p): Likewise.
(arm_valid_target_attribute_rec): Likewise.
(arm_previous_fndecl): New variable.
(TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
(TARGET_CAN_INLINE_P): Define.
(arm_asm_trampoline_template): Emit mode.
(arm_file_start): Don't set unified syntax.
(arm_declare_function_name): Set unified syntax and mode.
(arm_option_override): Init target_option_default_node.
and target_option_current_node.
* config/arm/arm.md (*call_value_symbol): Set mode when possible.
(*call_symbol): Likewise.
* doc/extend.texi: Document ARM target and pragma attribute.
* doc/invoke.texi: Likewise.
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.c gnu_trunk.p4/gcc/gcc/config/arm/arm.c
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.c 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.c 2015-05-06 15:03:29.393992051 +0200
@@ -94,6 +94,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -264,6 +265,9 @@
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_set_current_function (tree);
+static bool arm_can_inline_p (tree, 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);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -412,6 +416,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -430,6 +437,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2750,6 +2763,9 @@
}
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2772,6 +2788,10 @@
if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
@@ -2779,15 +2799,17 @@
opts->x_arm_restrict_it = 0;
if (TREE_TARGET_THUMB1 (opts))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* Disable shrink-wrap when optimizing function for size, since it tends to
generate additional returns. */
if (optimize_function_for_size_p (cfun) && TREE_TARGET_THUMB2 (opts))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2799,6 +2821,8 @@
fipa-ra. */
if (TREE_TARGET_THUMB1 (opts))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3291,12 +3315,20 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3450,13 +3482,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -23903,6 +23942,23 @@
return 0;
}
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+ return (TREE_TARGET_THUMB (callee_opts) != TARGET_THUMB);
+}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -25518,9 +25574,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29271,9 +29324,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* 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. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strcmp (argstr, "thumb"))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strcmp (argstr, "arm"))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* 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,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* 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 = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ 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,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29285,6 +29525,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.h gnu_trunk.p4/gcc/gcc/config/arm/arm.h
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.h 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.h 2015-05-06 14:36:32.227213416 +0200
@@ -2332,4 +2332,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.md gnu_trunk.p4/gcc/gcc/config/arm/arm.md
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.md 2015-05-06 14:31:40.678713158 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.md 2015-05-06 14:36:32.231213422 +0200
@@ -7722,6 +7722,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7739,6 +7746,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.opt gnu_trunk.p4/gcc/gcc/config/arm/arm.opt
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.opt 2015-03-30 10:44:52.901327167 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.opt 2015-05-06 14:36:32.231213422 +0200
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -246,7 +246,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -275,5 +275,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=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm-protos.h gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h
--- gnu_trunk.p3/gcc/gcc/config/arm/arm-protos.h 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h 2015-05-06 14:36:32.231213422 +0200
@@ -210,6 +210,9 @@
extern int arm_dllimport_p (tree);
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 *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -317,6 +320,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/extend.texi gnu_trunk.p4/gcc/gcc/doc/extend.texi
--- gnu_trunk.p3/gcc/gcc/doc/extend.texi 2015-05-06 09:00:31.232943164 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/extend.texi 2015-05-06 14:50:05.632612233 +0200
@@ -3419,6 +3419,25 @@
the compiler rejects attempts to specify an alternative.
@end table
+@item target (@var{options})
+@cindex @code{target} function attribute
+As discussed in @ref{Common Function Attributes}, this attribute
+allows specification of target-specific compilation options.
+
+On ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} function attribute, ARM
+Force Thumb1 Thumb2 code generation depending on the architecture.
+
+@item arm
+@cindex @code{target("arm")} function attribute, ARM
+Force ARM code generation.
+@end table
+
+Functions from different modes can be inlined using the caller mode.
+
@node AVR Function Attributes
@subsection AVR Function Attributes
@@ -18436,8 +18455,9 @@
@xref{Function Attributes}, for more information about the
@code{target} attribute and the attribute syntax.
-The @code{#pragma GCC target} pragma is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{#pragma GCC target} pragma is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
@end table
@table @code
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/invoke.texi gnu_trunk.p4/gcc/gcc/doc/invoke.texi
--- gnu_trunk.p3/gcc/gcc/doc/invoke.texi 2015-05-06 09:00:31.232943164 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/invoke.texi 2015-05-06 14:36:32.331213593 +0200
@@ -13434,6 +13434,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* 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")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th)
2015-05-06 14:25 [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
@ 2015-05-06 23:04 ` Sandra Loosemore
2015-05-08 8:31 ` Ramana Radhakrishnan
2015-05-07 8:13 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
1 sibling, 1 reply; 15+ messages in thread
From: Sandra Loosemore @ 2015-05-06 23:04 UTC (permalink / raw)
To: Christian Bruel
Cc: gcc-patches, Ramana Radhakrishnan, Richard Earnshaw, Nicholas Clifton
On 05/06/2015 08:24 AM, Christian Bruel wrote:
> diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/extend.texi gnu_trunk.p4/gcc/gcc/doc/extend.texi
> --- gnu_trunk.p3/gcc/gcc/doc/extend.texi 2015-05-06 09:00:31.232943164 +0200
> +++ gnu_trunk.p4/gcc/gcc/doc/extend.texi 2015-05-06 14:50:05.632612233 +0200
> @@ -3419,6 +3419,25 @@
> the compiler rejects attempts to specify an alternative.
> @end table
>
> +@item target (@var{options})
> +@cindex @code{target} function attribute
> +As discussed in @ref{Common Function Attributes}, this attribute
> +allows specification of target-specific compilation options.
> +
> +On ARM, the following options are allowed:
> +
> +@table @samp
> +@item thumb
> +@cindex @code{target("thumb")} function attribute, ARM
> +Force Thumb1 Thumb2 code generation depending on the architecture.
"Force Thumb or Thumb-2 code generation, depending on the architecture."
(I believe that's ARM's official terminology, rather than "Thumb1" or
"Thumb2".)
> +
> +@item arm
> +@cindex @code{target("arm")} function attribute, ARM
> +Force ARM code generation.
> +@end table
> +
> +Functions from different modes can be inlined using the caller mode.
"...the caller's mode."
> +
> @node AVR Function Attributes
> @subsection AVR Function Attributes
>
> @@ -18436,8 +18455,9 @@
> @xref{Function Attributes}, for more information about the
> @code{target} attribute and the attribute syntax.
>
> -The @code{#pragma GCC target} pragma is presently implemented for
> -x86, PowerPC, and Nios II targets only.
> +The @code{#pragma GCC target} pragma is implemented for
> +ARM, x86, PowerPC, and Nios II targets.
> +
> @end table
>
> @table @code
Please also add a cross-reference to ARM Function Attributes in the main
entry for @item target in Common Function Attributes, in this paragraph:
The options supported are specific to each target; refer to @ref{x86
Function Attributes}, @ref{PowerPC Function Attributes}, and
@ref{Nios II Function Attributes}, for details.
> diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/invoke.texi gnu_trunk.p4/gcc/gcc/doc/invoke.texi
> --- gnu_trunk.p3/gcc/gcc/doc/invoke.texi 2015-05-06 09:00:31.232943164 +0200
> +++ gnu_trunk.p4/gcc/gcc/doc/invoke.texi 2015-05-06 14:36:32.331213593 +0200
> @@ -13434,6 +13434,10 @@
> configuring GCC with the @option{--with-mode=}@var{state}
> configure option.
>
> +You can also override the ARM and Thumb mode for each function
> +by using the @code{target("thumb")} and @code{target("arm")} function attributes
> +(@pxref{Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
You can make the first reference point at the ARM Function Attributes
node, now that it exists, instead of the generic Function Attributes
section.
> +
> @item -mtpcs-frame
> @opindex mtpcs-frame
> Generate a stack frame that is compliant with the Thumb Procedure Call
-Sandra
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th)
2015-05-06 14:25 [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
2015-05-06 23:04 ` Sandra Loosemore
@ 2015-05-07 8:13 ` Christian Bruel
1 sibling, 0 replies; 15+ messages in thread
From: Christian Bruel @ 2015-05-07 8:13 UTC (permalink / raw)
To: gcc-patches, Ramana Radhakrishnan, Richard Earnshaw,
Nicholas Clifton, sandra
[-- Attachment #1: Type: text/plain, Size: 523 bytes --]
+ Sandra's doc review fixes.
tested with make doc pdf
thanks
Christian
On 05/06/2015 04:24 PM, Christian Bruel wrote:
> Implements and document the hooks to support target_attributes.
>
> The emission of blx is handled directly for armv5 to overcome a bug with
> the current binutils that fails with calls to a static symbol in a
> different section. (e.g .text -> .text.startup) in different modes.
>
> (ref https://sourceware.org/bugzilla/show_bug.cgi?id=17505)
>
> Regtests included
>
> Thanks
>
> Christian
>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: p4.patch --]
[-- Type: text/x-patch; name="p4.patch", Size: 22542 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
* config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
(arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
(SWITCHABLE_TARGET): Define.
* config/arm/arm.c (arm_reset_previous_fndecl): New functions.
(arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
(arm_valid_target_attribute_p): Likewise.
(arm_set_current_function, arm_can_inline_p): Likewise.
(arm_valid_target_attribute_rec): Likewise.
(arm_previous_fndecl): New variable.
(TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
(TARGET_CAN_INLINE_P): Define.
(arm_asm_trampoline_template): Emit mode.
(arm_file_start): Don't set unified syntax.
(arm_declare_function_name): Set unified syntax and mode.
(arm_option_override): Init target_option_default_node.
and target_option_current_node.
* config/arm/arm.md (*call_value_symbol): Set mode when possible.
(*call_symbol): Likewise.
* doc/extend.texi: Document ARM target and pragma attribute.
* doc/invoke.texi: Likewise.
2014-09-23 Christian Bruel <christian.bruel@st.com>
* gcc.target/arm/attr_arm.c: New test
* gcc.target/arm/attr_arm-err.c: New test
* gcc.target/arm/attr_thumb.c: New test
* gcc.target/arm/attr_thumb-static.c: New test
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.c gnu_trunk.p4/gcc/gcc/config/arm/arm.c
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.c 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.c 2015-05-06 15:03:29.393992051 +0200
@@ -94,6 +94,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -264,6 +265,9 @@
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_set_current_function (tree);
+static bool arm_can_inline_p (tree, 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);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -412,6 +416,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -430,6 +437,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2750,6 +2763,9 @@
}
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2772,6 +2788,10 @@
if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
@@ -2779,15 +2799,17 @@
opts->x_arm_restrict_it = 0;
if (TREE_TARGET_THUMB1 (opts))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* Disable shrink-wrap when optimizing function for size, since it tends to
generate additional returns. */
if (optimize_function_for_size_p (cfun) && TREE_TARGET_THUMB2 (opts))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2799,6 +2821,8 @@
fipa-ra. */
if (TREE_TARGET_THUMB1 (opts))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3291,12 +3315,20 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3450,13 +3482,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -23903,6 +23942,23 @@
return 0;
}
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+ return (TREE_TARGET_THUMB (callee_opts) != TARGET_THUMB);
+}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -25518,9 +25574,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29271,9 +29324,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* 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. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strcmp (argstr, "thumb"))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strcmp (argstr, "arm"))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* 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,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* 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 = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ 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,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29285,6 +29525,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.h gnu_trunk.p4/gcc/gcc/config/arm/arm.h
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.h 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.h 2015-05-06 14:36:32.227213416 +0200
@@ -2332,4 +2332,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.md gnu_trunk.p4/gcc/gcc/config/arm/arm.md
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.md 2015-05-06 14:31:40.678713158 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.md 2015-05-06 14:36:32.231213422 +0200
@@ -7722,6 +7722,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7739,6 +7746,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm.opt gnu_trunk.p4/gcc/gcc/config/arm/arm.opt
--- gnu_trunk.p3/gcc/gcc/config/arm/arm.opt 2015-03-30 10:44:52.901327167 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.opt 2015-05-06 14:36:32.231213422 +0200
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -246,7 +246,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -275,5 +275,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=.svn' -ruN gnu_trunk.p3/gcc/gcc/config/arm/arm-protos.h gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h
--- gnu_trunk.p3/gcc/gcc/config/arm/arm-protos.h 2015-05-06 14:31:48.750726995 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h 2015-05-06 14:36:32.231213422 +0200
@@ -210,6 +210,9 @@
extern int arm_dllimport_p (tree);
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 *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -317,6 +320,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/extend.texi gnu_trunk.p4/gcc/gcc/doc/extend.texi
--- gnu_trunk.p3/gcc/gcc/doc/extend.texi 2015-05-06 09:00:31.232943164 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/extend.texi 2015-05-07 09:43:01.087775682 +0200
@@ -3067,8 +3067,9 @@
or separate the options with a comma (@samp{,}) within a single string.
The options supported are specific to each target; refer to @ref{x86
-Function Attributes}, @ref{PowerPC Function Attributes}, and
-@ref{Nios II Function Attributes}, for details.
+Function Attributes}, @ref{PowerPC Function Attributes},
+@ref{ARM Function Attributes},and @ref{Nios II Function Attributes},
+for details.
@item unused
@cindex @code{unused} function attribute
@@ -3417,6 +3418,26 @@
Variadic functions always use the @code{"aapcs"} calling convention and
the compiler rejects attempts to specify an alternative.
+
+@item target (@var{options})
+@cindex @code{target} function attribute
+As discussed in @ref{Common Function Attributes}, this attribute
+allows specification of target-specific compilation options.
+
+On ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} function attribute, ARM
+Force Thumb Thumb-2 code generation, depending on the architecture.
+
+@item arm
+@cindex @code{target("arm")} function attribute, ARM
+Force ARM code generation.
+@end table
+
+Functions from different modes can be inlined in the caller's mode.
+
@end table
@node AVR Function Attributes
@@ -18436,8 +18457,9 @@
@xref{Function Attributes}, for more information about the
@code{target} attribute and the attribute syntax.
-The @code{#pragma GCC target} pragma is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{#pragma GCC target} pragma is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
@end table
@table @code
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/invoke.texi gnu_trunk.p4/gcc/gcc/doc/invoke.texi
--- gnu_trunk.p3/gcc/gcc/doc/invoke.texi 2015-05-06 09:00:31.232943164 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/invoke.texi 2015-05-07 09:10:04.612347618 +0200
@@ -13434,6 +13434,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{ARM Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* 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")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c
--- gnu_trunk.p3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 2015-05-06 14:36:32.335213601 +0200
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th)
2015-05-06 23:04 ` Sandra Loosemore
@ 2015-05-08 8:31 ` Ramana Radhakrishnan
2015-05-18 7:18 ` Christian Bruel
2015-05-18 8:16 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th) Christian Bruel
0 siblings, 2 replies; 15+ messages in thread
From: Ramana Radhakrishnan @ 2015-05-08 8:31 UTC (permalink / raw)
To: Sandra Loosemore, Christian Bruel; +Cc: gcc-patches, Richard Earnshaw, nickc
I'm still playing with the code, so this is a partial review.
We should prevent inlining of ARM state functions into functions we know
will be T16 if !TARGET_SOFT_FLOAT on the grounds that the architecture
doesn't have floating point instruction encodings in the T16 ISA
(Thumb1). We'll just cause internal compiler errors if we allow this.
On 07/05/15 00:03, Sandra Loosemore wrote:
> On 05/06/2015 08:24 AM, Christian Bruel wrote:
>> diff '--exclude=.svn' -ruN gnu_trunk.p3/gcc/gcc/doc/extend.texi gnu_trunk.p4/gcc/gcc/doc/extend.texi
>> --- gnu_trunk.p3/gcc/gcc/doc/extend.texi 2015-05-06 09:00:31.232943164 +0200
>> +++ gnu_trunk.p4/gcc/gcc/doc/extend.texi 2015-05-06 14:50:05.632612233 +0200
>> @@ -3419,6 +3419,25 @@
>> the compiler rejects attempts to specify an alternative.
>> @end table
>>
>> +@item target (@var{options})
>> +@cindex @code{target} function attribute
>> +As discussed in @ref{Common Function Attributes}, this attribute
>> +allows specification of target-specific compilation options.
>> +
>> +On ARM, the following options are allowed:
>> +
>> +@table @samp
>> +@item thumb
>> +@cindex @code{target("thumb")} function attribute, ARM
>> +Force Thumb1 Thumb2 code generation depending on the architecture.
>
> "Force Thumb or Thumb-2 code generation, depending on the architecture."
I'd rather it said something like
"Force code generation in the Thumb (T16/ T32) ISA. The exact
instructions chosen depends on the architecture levels chosen."
>> +
>> +@item arm
>> +@cindex @code{target("arm")} function attribute, ARM
>> +Force ARM code generation.
"Force code generation in the ARM (A32) ISA."
>> +@end table
>> +
>> +Functions from different modes can be inlined using the caller mode.
Rewrite this based on the review comment about inlining in the Thumb16
state from ARM state.
>
> "...the caller's mode."
>
>> +
>> @node AVR Function Attributes
>> @subsection AVR Function Attributes
>>
>> @@ -18436,8 +18455,9 @@
>> @xref{Function Attributes}, for more information about the
>> @code{target} attribute and the attribute syntax.
>>
>> -The @code{#pragma GCC target} pragma is presently implemented for
>> -x86, PowerPC, and Nios II targets only.
>> +The @code{#pragma GCC target} pragma is implemented for
>> +ARM, x86, PowerPC, and Nios II targets.
>> +
I'd rather say this once we have proper support with arch, cpu and fpu
options enabled. Until such a time I think this hunk is a bit premature.
Ramana
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th)
2015-05-08 8:31 ` Ramana Radhakrishnan
@ 2015-05-18 7:18 ` Christian Bruel
2015-05-18 8:16 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th) Christian Bruel
1 sibling, 0 replies; 15+ messages in thread
From: Christian Bruel @ 2015-05-18 7:18 UTC (permalink / raw)
To: Ramana Radhakrishnan; +Cc: gcc-patches, Richard Earnshaw, nickc
Hi Ramana,
On 05/08/2015 10:31 AM, Ramana Radhakrishnan wrote:
>
> I'm still playing with the code, so this is a partial review.
>
> We should prevent inlining of ARM state functions into functions we know
> will be T16 if !TARGET_SOFT_FLOAT on the grounds that the architecture
> doesn't have floating point instruction encodings in the T16 ISA
> (Thumb1). We'll just cause internal compiler errors if we allow this.
>
I tried to forge a bit with this situation, but I couldn't generate such
inconsistencies, as the situation is rejected with a :
"sorry, unimplemented: Thumb-1 hard-float VFP ABI"
when using -march=armv6 -mthumb -mhard-float (would that match with T16
&& !TARGET_SOFT_FLOAT)
Do you have the example producing an ICE ? That would be interesting to
add it in the testsuite.
by the way, I think the error message should be changed from
"sorry, unimplemented: Thumb-1 hard-float VFP ABI"
to a user error:
"Can't use Thumb-1 hard-float VFP ABI"
Christian
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-05-08 8:31 ` Ramana Radhakrishnan
2015-05-18 7:18 ` Christian Bruel
@ 2015-05-18 8:16 ` Christian Bruel
2015-06-01 10:39 ` Kyrill Tkachov
1 sibling, 1 reply; 15+ messages in thread
From: Christian Bruel @ 2015-05-18 8:16 UTC (permalink / raw)
To: Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
[-- Attachment #1: Type: text/plain, Size: 497 bytes --]
Hi,
Here is again a new version for patch [4/6]: (Implements and document
the hooks to support target_attributes.)
- Rewrote for conflicts introduced by the new macros defined in
https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01198.html
- Take your comments and Sandra's for documentation
- I'd like to leave the inlining question apart with its own patch
until we settle it. Is it OK with you ?
https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01527.html
many thanks,
Christian
[-- Attachment #2: p4.patch --]
[-- Type: text/x-patch, Size: 21763 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
* config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
(arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
(SWITCHABLE_TARGET): Define.
* config/arm/arm.c (arm_reset_previous_fndecl): New functions.
(arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
(arm_valid_target_attribute_p): Likewise.
(arm_set_current_function, arm_can_inline_p): Likewise.
(arm_valid_target_attribute_rec): Likewise.
(arm_previous_fndecl): New variable.
(TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
(TARGET_CAN_INLINE_P): Define.
(arm_asm_trampoline_template): Emit mode.
(arm_file_start): Don't set unified syntax.
(arm_declare_function_name): Set unified syntax and mode.
(arm_option_override): Init target_option_default_node.
and target_option_current_node.
* config/arm/arm.md (*call_value_symbol): Set mode when possible.
(*call_symbol): Likewise.
* doc/extend.texi: Document ARM/Thumb target attribute.
* doc/invoke.texi: Likewise.
2014-09-23 Christian Bruel <christian.bruel@st.com>
* gcc.target/arm/attr_arm.c: New test
* gcc.target/arm/attr_arm-err.c: New test
* gcc.target/arm/attr_thumb.c: New test
* gcc.target/arm/attr_thumb-static.c: New test
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/config/arm/arm.c gnu_trunk.p4/gcc/gcc/config/arm/arm.c
--- gnu_trunk.p2/gcc/gcc/config/arm/arm.c 2015-05-18 09:59:22.711435629 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.c 2015-05-13 13:51:47.427088369 +0200
@@ -94,6 +94,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -265,6 +266,9 @@
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_set_current_function (tree);
+static bool arm_can_inline_p (tree, 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);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -413,6 +417,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -431,6 +438,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2777,6 +2790,9 @@
max_insns_skipped = current_tune->max_insns_skipped;
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2799,23 +2815,29 @@
if (TARGET_THUMB_P (opts->x_target_flags) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
if (!TARGET_THUMB2_P (opts->x_target_flags))
opts->x_arm_restrict_it = 0;
+ /* Don't warn since it's on by default in -O2. */
if (TARGET_THUMB1_P (opts->x_target_flags))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* Disable shrink-wrap when optimizing function for size, since it tends to
generate additional returns. */
if (optimize_function_for_size_p (cfun)
&& TARGET_THUMB2_P (opts->x_target_flags))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2827,6 +2849,8 @@
fipa-ra. */
if (TARGET_THUMB1_P (opts->x_target_flags))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3329,12 +3353,20 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3488,13 +3520,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -24190,6 +24229,24 @@
mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
}
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+ int flags = callee_opts ->x_target_flags;
+
+ return (TARGET_THUMB_P (flags) != TARGET_THUMB);
+}
/* Like arm_compute_initial_elimination offset. Simpler because there
isn't an ABI specified frame pointer for Thumb. Instead, we set it
@@ -25517,9 +25574,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29266,9 +29320,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* 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. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strcmp (argstr, "thumb"))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strcmp (argstr, "arm"))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* 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,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* 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 = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ 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,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29280,6 +29521,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/config/arm/arm.h gnu_trunk.p4/gcc/gcc/config/arm/arm.h
--- gnu_trunk.p2/gcc/gcc/config/arm/arm.h 2015-05-18 09:59:22.715435636 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.h 2015-05-18 09:10:32.898017110 +0200
@@ -2258,4 +2258,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/config/arm/arm.md gnu_trunk.p4/gcc/gcc/config/arm/arm.md
--- gnu_trunk.p2/gcc/gcc/config/arm/arm.md 2015-05-18 09:36:56.844875186 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.md 2015-05-18 09:10:32.898017110 +0200
@@ -7738,6 +7738,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7755,6 +7762,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/config/arm/arm.opt gnu_trunk.p4/gcc/gcc/config/arm/arm.opt
--- gnu_trunk.p2/gcc/gcc/config/arm/arm.opt 2015-03-30 10:44:52.901327167 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm.opt 2015-05-13 12:59:54.625164421 +0200
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -246,7 +246,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -275,5 +275,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=.svn' -ruN gnu_trunk.p2/gcc/gcc/config/arm/arm-protos.h gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h
--- gnu_trunk.p2/gcc/gcc/config/arm/arm-protos.h 2015-05-18 09:59:19.267429002 +0200
+++ gnu_trunk.p4/gcc/gcc/config/arm/arm-protos.h 2015-05-13 12:59:54.653164472 +0200
@@ -210,6 +210,9 @@
extern int arm_dllimport_p (tree);
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 *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -326,6 +329,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/doc/extend.texi gnu_trunk.p4/gcc/gcc/doc/extend.texi
--- gnu_trunk.p2/gcc/gcc/doc/extend.texi 2015-05-13 09:07:31.339106236 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/extend.texi 2015-05-18 09:08:54.221837117 +0200
@@ -3067,8 +3067,9 @@
or separate the options with a comma (@samp{,}) within a single string.
The options supported are specific to each target; refer to @ref{x86
-Function Attributes}, @ref{PowerPC Function Attributes}, and
-@ref{Nios II Function Attributes}, for details.
+Function Attributes}, @ref{PowerPC Function Attributes},
+@ref{ARM Function Attributes},and @ref{Nios II Function Attributes},
+for details.
@item unused
@cindex @code{unused} function attribute
@@ -3417,6 +3418,27 @@
Variadic functions always use the @code{"aapcs"} calling convention and
the compiler rejects attempts to specify an alternative.
+
+@item target (@var{options})
+@cindex @code{target} function attribute
+As discussed in @ref{Common Function Attributes}, this attribute
+allows specification of target-specific compilation options.
+
+On ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} function attribute, ARM
+Force code generation in the Thumb (T16/T32) ISA, depending on the
+architecture level.
+
+@item arm
+@cindex @code{target("arm")} function attribute, ARM
+Force code generation in the ARM (A32) ISA.
+@end table
+
+Functions from different modes can be inlined in the caller's mode.
+
@end table
@node AVR Function Attributes
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/doc/invoke.texi gnu_trunk.p4/gcc/gcc/doc/invoke.texi
--- gnu_trunk.p2/gcc/gcc/doc/invoke.texi 2015-05-18 09:36:52.304866524 +0200
+++ gnu_trunk.p4/gcc/gcc/doc/invoke.texi 2015-05-18 09:10:29.078010152 +0200
@@ -13508,6 +13508,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{ARM Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-05-07 18:15:34.177443930 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-05-07 18:15:34.177443930 +0200
@@ -0,0 +1,13 @@
+/* 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")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
--- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-05-07 18:15:34.177443930 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c
--- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 2015-05-07 18:15:34.177443930 +0200
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-05-18 8:16 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th) Christian Bruel
@ 2015-06-01 10:39 ` Kyrill Tkachov
2015-06-01 11:30 ` Christian Bruel
0 siblings, 1 reply; 15+ messages in thread
From: Kyrill Tkachov @ 2015-06-01 10:39 UTC (permalink / raw)
To: Christian Bruel, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
On 18/05/15 09:14, Christian Bruel wrote:
> Hi,
Hi Christian,
A couple comments inline.
Overall, the approach looks ok to me, though I think we'll have to
generalise arm_valid_target_attribute_rec in the future if we want
to allow other target attributes.
Thanks,
Kyrill
>
> Here is again a new version for patch [4/6]: (Implements and document
> the hooks to support target_attributes.)
>
> - Rewrote for conflicts introduced by the new macros defined in
> https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01198.html
>
> - Take your comments and Sandra's for documentation
>
> - I'd like to leave the inlining question apart with its own patch
> until we settle it. Is it OK with you ?
> https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01527.html
>
> many thanks,
>
> Christian
>
> p4.patch
>
>
> 2014-09-23 Christian Bruel<christian.bruel@st.com>
>
> * config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
> * config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
> (arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
> (SWITCHABLE_TARGET): Define.
> * config/arm/arm.c (arm_reset_previous_fndecl): New functions.
> (arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
> (arm_valid_target_attribute_p): Likewise.
> (arm_set_current_function, arm_can_inline_p): Likewise.
> (arm_valid_target_attribute_rec): Likewise.
> (arm_previous_fndecl): New variable.
> (TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
> (TARGET_CAN_INLINE_P): Define.
> (arm_asm_trampoline_template): Emit mode.
> (arm_file_start): Don't set unified syntax.
> (arm_declare_function_name): Set unified syntax and mode.
> (arm_option_override): Init target_option_default_node.
> and target_option_current_node.
> * config/arm/arm.md (*call_value_symbol): Set mode when possible.
> (*call_symbol): Likewise.
> * doc/extend.texi: Document ARM/Thumb target attribute.
> * doc/invoke.texi: Likewise.
>
> 2014-09-23 Christian Bruel<christian.bruel@st.com>
>
> * gcc.target/arm/attr_arm.c: New test
> * gcc.target/arm/attr_arm-err.c: New test
> * gcc.target/arm/attr_thumb.c: New test
> * gcc.target/arm/attr_thumb-static.c: New test
Full stops at end of "New test"
<snip>
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+ int flags = callee_opts ->x_target_flags;
No space after callee_opts.
<snip>
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
I thought the more common approach was to define TARGET_OPTION_RESTORE
that was supposed to restore the backend state, including calling arm_option_params_internal?
That way, cl_target_option_restore would do all that needs to be done to restore the backend.
<snip>
diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-05-07 18:15:34.177443930 +0200
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
s/recogniwed/recognized/
> +/* { dg-do compile } */
> +/* { dg-require-effective-target arm_arm_ok } */
> +/* { dg-options "-O2" } */
> +/* { dg-final { scan-assembler ".arm" } } */
> +/* { dg-final { scan-assembler-not "ite" } } */
> +
> +int __attribute__((target("arm")))
> +foo(int a)
> +{
> + return a ? 1 : 5;
> +}
> +
> diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
> --- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
> +++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-05-07 18:15:34.177443930 +0200
> @@ -0,0 +1,13 @@
> +/* 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")))
> +foo(int a)
> +{ /* { dg-error "does not support" } */
> + return a ? 1 : 5;
> +}
> +
> +
> diff '--exclude=.svn' -ruN gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
> --- gnu_trunk.p2/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
> +++ gnu_trunk.p4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-05-07 18:15:34.177443930 +0200
> @@ -0,0 +1,13 @@
> +/* Check that attribute target thumb is recogniwed. */
s/recogniwed/recognized/
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-06-01 10:39 ` Kyrill Tkachov
@ 2015-06-01 11:30 ` Christian Bruel
2015-06-01 12:41 ` Kyrill Tkachov
0 siblings, 1 reply; 15+ messages in thread
From: Christian Bruel @ 2015-06-01 11:30 UTC (permalink / raw)
To: Kyrill Tkachov, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
hi Kyrill
On 06/01/2015 12:39 PM, Kyrill Tkachov wrote:
>
> On 18/05/15 09:14, Christian Bruel wrote:
>> Hi,
>
> Hi Christian,
> A couple comments inline.
> Overall, the approach looks ok to me, though I think we'll have to
> generalise arm_valid_target_attribute_rec in the future if we want
> to allow other target attributes.
>
the other fpu target attributes will be part of another set of
developments, specific parsing strings will be added as they are
implemented.
> +
> +/* Establish appropriate back-end context for processing the function
> + FNDECL. The argument might be NULL to indicate processing at top
> + level, outside of any function scope. */
> +static void
> +arm_set_current_function (tree fndecl)
> +{
> + if (!fndecl || fndecl == arm_previous_fndecl)
> + return;
> +
> + tree old_tree = (arm_previous_fndecl
> + ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
> + : NULL_TREE);
> +
> + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
> +
> + arm_previous_fndecl = fndecl;
> + if (old_tree == new_tree)
> + ;
> +
> + else if (new_tree)
> + {
> + cl_target_option_restore (&global_options,
> + TREE_TARGET_OPTION (new_tree));
> +
> + if (TREE_TARGET_GLOBALS (new_tree))
> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
> + else
> + TREE_TARGET_GLOBALS (new_tree)
> + = save_target_globals_default_opts ();
> + }
> +
> + else if (old_tree)
> + {
> + new_tree = target_option_current_node;
> +
> + cl_target_option_restore (&global_options,
> + TREE_TARGET_OPTION (new_tree));
> + if (TREE_TARGET_GLOBALS (new_tree))
> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
> + else if (new_tree == target_option_default_node)
> + restore_target_globals (&default_target_globals);
> + else
> + TREE_TARGET_GLOBALS (new_tree)
> + = save_target_globals_default_opts ();
> + }
> +
> + arm_option_params_internal (&global_options);
>
>
> I thought the more common approach was to define TARGET_OPTION_RESTORE
> that was supposed to restore the backend state, including calling arm_option_params_internal?
> That way, cl_target_option_restore would do all that needs to be done to restore the backend.
>
TARGET_OPTION_RESTORE is fine to restore target-specific
information from struct cl_target_option. Other global states might as
well be expressed within set_current_function (e.g indeed I might use
TARGET_OPTION_RESTORE to switch arm_fpu_attr in the fpu neon attribute).
But IMHO arm_option_params_internal are fine to be called there since
the 2 params only depend from x_target_flags without the need of a new
macro.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-06-01 11:30 ` Christian Bruel
@ 2015-06-01 12:41 ` Kyrill Tkachov
2015-06-01 12:55 ` Christian Bruel
2015-06-08 9:26 ` Christian Bruel
0 siblings, 2 replies; 15+ messages in thread
From: Kyrill Tkachov @ 2015-06-01 12:41 UTC (permalink / raw)
To: Christian Bruel, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
On 01/06/15 12:29, Christian Bruel wrote:
> hi Kyrill
>
>
> On 06/01/2015 12:39 PM, Kyrill Tkachov wrote:
>> On 18/05/15 09:14, Christian Bruel wrote:
>>> Hi,
>> Hi Christian,
>> A couple comments inline.
>> Overall, the approach looks ok to me, though I think we'll have to
>> generalise arm_valid_target_attribute_rec in the future if we want
>> to allow other target attributes.
>>
> the other fpu target attributes will be part of another set of
> developments, specific parsing strings will be added as they are
> implemented.
Ok, so you plan on working on fpu attributes as well?
>
>> +
>> +/* Establish appropriate back-end context for processing the function
>> + FNDECL. The argument might be NULL to indicate processing at top
>> + level, outside of any function scope. */
>> +static void
>> +arm_set_current_function (tree fndecl)
>> +{
>> + if (!fndecl || fndecl == arm_previous_fndecl)
>> + return;
>> +
>> + tree old_tree = (arm_previous_fndecl
>> + ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
>> + : NULL_TREE);
>> +
>> + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
>> +
>> + arm_previous_fndecl = fndecl;
>> + if (old_tree == new_tree)
>> + ;
>> +
>> + else if (new_tree)
>> + {
>> + cl_target_option_restore (&global_options,
>> + TREE_TARGET_OPTION (new_tree));
>> +
>> + if (TREE_TARGET_GLOBALS (new_tree))
>> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
>> + else
>> + TREE_TARGET_GLOBALS (new_tree)
>> + = save_target_globals_default_opts ();
>> + }
>> +
>> + else if (old_tree)
>> + {
>> + new_tree = target_option_current_node;
>> +
>> + cl_target_option_restore (&global_options,
>> + TREE_TARGET_OPTION (new_tree));
>> + if (TREE_TARGET_GLOBALS (new_tree))
>> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
>> + else if (new_tree == target_option_default_node)
>> + restore_target_globals (&default_target_globals);
>> + else
>> + TREE_TARGET_GLOBALS (new_tree)
>> + = save_target_globals_default_opts ();
>> + }
>> +
>> + arm_option_params_internal (&global_options);
>>
>>
>> I thought the more common approach was to define TARGET_OPTION_RESTORE
>> that was supposed to restore the backend state, including calling arm_option_params_internal?
>> That way, cl_target_option_restore would do all that needs to be done to restore the backend.
>>
> TARGET_OPTION_RESTORE is fine to restore target-specific
> information from struct cl_target_option. Other global states might as
> well be expressed within set_current_function (e.g indeed I might use
> TARGET_OPTION_RESTORE to switch arm_fpu_attr in the fpu neon attribute).
> But IMHO arm_option_params_internal are fine to be called there since
> the 2 params only depend from x_target_flags without the need of a new
> macro.
Ok, I see.
The patch looks ok to me modulo the typo nits I pointed out, but I think Ramana
should have the final say here as he's already started reviewing it and it adds quite
a lot of functionality.
Thanks,
Kyrill
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-06-01 12:41 ` Kyrill Tkachov
@ 2015-06-01 12:55 ` Christian Bruel
2015-06-08 9:26 ` Christian Bruel
1 sibling, 0 replies; 15+ messages in thread
From: Christian Bruel @ 2015-06-01 12:55 UTC (permalink / raw)
To: Kyrill Tkachov, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
On 06/01/2015 02:41 PM, Kyrill Tkachov wrote:
>
> On 01/06/15 12:29, Christian Bruel wrote:
>> hi Kyrill
>>
>>
>> On 06/01/2015 12:39 PM, Kyrill Tkachov wrote:
>>> On 18/05/15 09:14, Christian Bruel wrote:
>>>> Hi,
>>> Hi Christian,
>>> A couple comments inline.
>>> Overall, the approach looks ok to me, though I think we'll have to
>>> generalise arm_valid_target_attribute_rec in the future if we want
>>> to allow other target attributes.
>>>
>> the other fpu target attributes will be part of another set of
>> developments, specific parsing strings will be added as they are
>> implemented.
>
> Ok, so you plan on working on fpu attributes as well?
I have a prototype for fpu=neon, it works locally but there are still a
few corner cases and testing to sort out before sending a draft.
There are so many architectural variants to check that I might ask for
help once it is a little bit more robust, and some might be similar with
aarch64's simd.
>
>>
>>> +
>>> +/* Establish appropriate back-end context for processing the function
>>> + FNDECL. The argument might be NULL to indicate processing at top
>>> + level, outside of any function scope. */
>>> +static void
>>> +arm_set_current_function (tree fndecl)
>>> +{
>>> + if (!fndecl || fndecl == arm_previous_fndecl)
>>> + return;
>>> +
>>> + tree old_tree = (arm_previous_fndecl
>>> + ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
>>> + : NULL_TREE);
>>> +
>>> + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
>>> +
>>> + arm_previous_fndecl = fndecl;
>>> + if (old_tree == new_tree)
>>> + ;
>>> +
>>> + else if (new_tree)
>>> + {
>>> + cl_target_option_restore (&global_options,
>>> + TREE_TARGET_OPTION (new_tree));
>>> +
>>> + if (TREE_TARGET_GLOBALS (new_tree))
>>> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
>>> + else
>>> + TREE_TARGET_GLOBALS (new_tree)
>>> + = save_target_globals_default_opts ();
>>> + }
>>> +
>>> + else if (old_tree)
>>> + {
>>> + new_tree = target_option_current_node;
>>> +
>>> + cl_target_option_restore (&global_options,
>>> + TREE_TARGET_OPTION (new_tree));
>>> + if (TREE_TARGET_GLOBALS (new_tree))
>>> + restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
>>> + else if (new_tree == target_option_default_node)
>>> + restore_target_globals (&default_target_globals);
>>> + else
>>> + TREE_TARGET_GLOBALS (new_tree)
>>> + = save_target_globals_default_opts ();
>>> + }
>>> +
>>> + arm_option_params_internal (&global_options);
>>>
>>>
>>> I thought the more common approach was to define TARGET_OPTION_RESTORE
>>> that was supposed to restore the backend state, including calling arm_option_params_internal?
>>> That way, cl_target_option_restore would do all that needs to be done to restore the backend.
>>>
>> TARGET_OPTION_RESTORE is fine to restore target-specific
>> information from struct cl_target_option. Other global states might as
>> well be expressed within set_current_function (e.g indeed I might use
>> TARGET_OPTION_RESTORE to switch arm_fpu_attr in the fpu neon attribute).
>> But IMHO arm_option_params_internal are fine to be called there since
>> the 2 params only depend from x_target_flags without the need of a new
>> macro.
>
> Ok, I see.
> The patch looks ok to me modulo the typo nits I pointed out, but I think Ramana
> should have the final say here as he's already started reviewing it and it adds quite
> a lot of functionality.
OK thanks, I'll wait for Ramana's final words.
Cheers
Christian
>
> Thanks,
> Kyrill
>
>>
>>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-06-01 12:41 ` Kyrill Tkachov
2015-06-01 12:55 ` Christian Bruel
@ 2015-06-08 9:26 ` Christian Bruel
2015-06-08 9:33 ` Ramana Radhakrishnan
1 sibling, 1 reply; 15+ messages in thread
From: Christian Bruel @ 2015-06-08 9:26 UTC (permalink / raw)
To: Kyrill Tkachov, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
Hi Ramana,
>
> Ok, I see.
> The patch looks ok to me modulo the typo nits I pointed out, but I think Ramana
> should have the final say here as he's already started reviewing it and it adds quite
> a lot of functionality.
>
> Thanks,
> Kyrill
>
do you have other feedbacks for the remaining parts ?
many thanks
Christian
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th)
2015-06-08 9:26 ` Christian Bruel
@ 2015-06-08 9:33 ` Ramana Radhakrishnan
2015-06-10 8:26 ` [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6] Christian Bruel
0 siblings, 1 reply; 15+ messages in thread
From: Ramana Radhakrishnan @ 2015-06-08 9:33 UTC (permalink / raw)
To: Christian Bruel, Kyrill Tkachov, Ramana Radhakrishnan, Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
On 08/06/15 09:45, Christian Bruel wrote:
> Hi Ramana,
>
>>
>> Ok, I see.
>> The patch looks ok to me modulo the typo nits I pointed out, but I
>> think Ramana
>> should have the final say here as he's already started reviewing it
>> and it adds quite
>> a lot of functionality.
>>
>> Thanks,
>> Kyrill
>>
>
> do you have other feedbacks for the remaining parts ?
>
> many thanks
>
> Christian
This is OK, thanks.
Ramana
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6]
2015-06-08 9:33 ` Ramana Radhakrishnan
@ 2015-06-10 8:26 ` Christian Bruel
2015-06-15 10:15 ` James Greenhalgh
0 siblings, 1 reply; 15+ messages in thread
From: Christian Bruel @ 2015-06-10 8:26 UTC (permalink / raw)
To: Ramana Radhakrishnan, Kyrill Tkachov, Ramana Radhakrishnan,
Sandra Loosemore
Cc: gcc-patches, Richard Earnshaw, nickc
[-- Attachment #1: Type: text/plain, Size: 572 bytes --]
Hi,
Commited [4/6] as attached (r224314)
thanks
Christian
On 06/08/2015 11:26 AM, Ramana Radhakrishnan wrote:
>
>
> On 08/06/15 09:45, Christian Bruel wrote:
>> Hi Ramana,
>>
>>>
>>> Ok, I see.
>>> The patch looks ok to me modulo the typo nits I pointed out, but I
>>> think Ramana
>>> should have the final say here as he's already started reviewing it
>>> and it adds quite
>>> a lot of functionality.
>>>
>>> Thanks,
>>> Kyrill
>>>
>>
>> do you have other feedbacks for the remaining parts ?
>>
>> many thanks
>>
>> Christian
>
>
> This is OK, thanks.
>
> Ramana
>
[-- Attachment #2: commited.txt --]
[-- Type: text/plain, Size: 21594 bytes --]
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 224313)
+++ gcc/doc/extend.texi (revision 224314)
@@ -3098,8 +3098,9 @@
or separate the options with a comma (@samp{,}) within a single string.
The options supported are specific to each target; refer to @ref{x86
-Function Attributes}, @ref{PowerPC Function Attributes}, and
-@ref{Nios II Function Attributes}, for details.
+Function Attributes}, @ref{PowerPC Function Attributes},
+@ref{ARM Function Attributes},and @ref{Nios II Function Attributes},
+for details.
@item unused
@cindex @code{unused} function attribute
@@ -3448,8 +3449,29 @@
Variadic functions always use the @code{"aapcs"} calling convention and
the compiler rejects attempts to specify an alternative.
+
+@item target (@var{options})
+@cindex @code{target} function attribute
+As discussed in @ref{Common Function Attributes}, this attribute
+allows specification of target-specific compilation options.
+
+On ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} function attribute, ARM
+Force code generation in the Thumb (T16/T32) ISA, depending on the
+architecture level.
+
+@item arm
+@cindex @code{target("arm")} function attribute, ARM
+Force code generation in the ARM (A32) ISA.
@end table
+Functions from different modes can be inlined in the caller's mode.
+
+@end table
+
@node AVR Function Attributes
@subsection AVR Function Attributes
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi (revision 224313)
+++ gcc/doc/invoke.texi (revision 224314)
@@ -13512,6 +13512,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{ARM Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog (revision 224313)
+++ gcc/ChangeLog (revision 224314)
@@ -1,3 +1,28 @@
+2015-06-09 Christian Bruel <christian.bruel@st.com>
+
+ PR target/52144
+ * config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
+ * config/arm/arm-protos.h (arm_valid_target_attribute_tree): Declare.
+ (arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
+ * config/arm/arm.h (SWITCHABLE_TARGET): Define.
+ * config/arm/arm.c (arm_reset_previous_fndecl): New functions.
+ (arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
+ (arm_valid_target_attribute_p): Likewise.
+ (arm_set_current_function, arm_can_inline_p): Likewise.
+ (arm_valid_target_attribute_rec): Likewise.
+ (arm_previous_fndecl): New variable.
+ (TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
+ (TARGET_CAN_INLINE_P): Define.
+ (arm_asm_trampoline_template): Emit mode.
+ (arm_file_start): Don't set unified syntax.
+ (arm_declare_function_name): Set unified syntax and mode.
+ (arm_option_override): Init target_option_default_node.
+ and target_option_current_node.
+ * config/arm/arm.md (*call_value_symbol): Set mode when possible.
+ (*call_symbol): Likewise.
+ * doc/extend.texi: Document ARM/Thumb target attribute.
+ * doc/invoke.texi: Likewise.
+
2015-06-09 Alexandre Oliva <aoliva@redhat.com>
Revert:
Index: gcc/testsuite/gcc.target/arm/attr_arm-err.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr_arm-err.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/attr_arm-err.c (revision 224314)
@@ -0,0 +1,13 @@
+/* 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")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
Index: gcc/testsuite/gcc.target/arm/attr_thumb.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr_thumb.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/attr_thumb.c (revision 224314)
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
Index: gcc/testsuite/gcc.target/arm/attr_thumb-static.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr_thumb-static.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/attr_thumb-static.c (revision 224314)
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
Index: gcc/testsuite/gcc.target/arm/attr_arm.c
===================================================================
--- gcc/testsuite/gcc.target/arm/attr_arm.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/attr_arm.c (revision 224314)
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog (revision 224313)
+++ gcc/testsuite/ChangeLog (revision 224314)
@@ -1,3 +1,11 @@
+2015-06-09 Christian Bruel <christian.bruel@st.com>
+
+ PR target/52144
+ * gcc.target/arm/attr_arm.c: New test
+ * gcc.target/arm/attr_arm-err.c: New test
+ * gcc.target/arm/attr_thumb.c: New test
+ * gcc.target/arm/attr_thumb-static.c: New test
+
2015-06-10 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
PR target/66200
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c (revision 224313)
+++ gcc/config/arm/arm.c (revision 224314)
@@ -81,6 +81,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -252,6 +253,9 @@
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_set_current_function (tree);
+static bool arm_can_inline_p (tree, 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);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -400,6 +404,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -418,6 +425,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2778,6 +2791,9 @@
max_insns_skipped = current_tune->max_insns_skipped;
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2800,6 +2816,10 @@
if (TARGET_THUMB_P (opts->x_target_flags) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
@@ -2806,11 +2826,11 @@
if (!TARGET_THUMB2_P (opts->x_target_flags))
opts->x_arm_restrict_it = 0;
+ /* Don't warn since it's on by default in -O2. */
if (TARGET_THUMB1_P (opts->x_target_flags))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* Disable shrink-wrap when optimizing function for size, since it tends to
generate additional returns. */
@@ -2817,6 +2837,8 @@
if (optimize_function_for_size_p (cfun)
&& TARGET_THUMB2_P (opts->x_target_flags))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2828,6 +2850,8 @@
fipa-ra. */
if (TARGET_THUMB1_P (opts->x_target_flags))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3330,6 +3354,9 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
@@ -3336,6 +3363,11 @@
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3489,13 +3521,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -24193,7 +24232,25 @@
mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
}
+/* Check that FUNC is called with a different mode. */
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+ int flags = callee_opts->x_target_flags;
+
+ return (TARGET_THUMB_P (flags) != TARGET_THUMB);
+}
+
/* Like arm_compute_initial_elimination offset. Simpler because there
isn't an ABI specified frame pointer for Thumb. Instead, we set it
to point at the base of the local variables after static stack
@@ -25520,9 +25577,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29269,9 +29323,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* 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. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strcmp (argstr, "thumb"))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strcmp (argstr, "arm"))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* 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,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* 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 = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ 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,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
+void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29283,6 +29524,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h (revision 224313)
+++ gcc/config/arm/arm.h (revision 224314)
@@ -2258,4 +2258,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
Index: gcc/config/arm/arm-protos.h
===================================================================
--- gcc/config/arm/arm-protos.h (revision 224313)
+++ gcc/config/arm/arm-protos.h (revision 224314)
@@ -210,6 +210,9 @@
extern int arm_dllimport_p (tree);
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 *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -326,6 +329,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
Index: gcc/config/arm/arm.opt
===================================================================
--- gcc/config/arm/arm.opt (revision 224313)
+++ gcc/config/arm/arm.opt (revision 224314)
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -246,7 +246,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -275,5 +275,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.
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md (revision 224313)
+++ gcc/config/arm/arm.md (revision 224314)
@@ -7787,6 +7787,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7804,6 +7811,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6]
2015-06-10 8:26 ` [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6] Christian Bruel
@ 2015-06-15 10:15 ` James Greenhalgh
2015-06-15 12:05 ` Christian Bruel
0 siblings, 1 reply; 15+ messages in thread
From: James Greenhalgh @ 2015-06-15 10:15 UTC (permalink / raw)
To: Christian Bruel
Cc: Ramana Radhakrishnan, Kyrylo Tkachov, Ramana Radhakrishnan,
Sandra Loosemore, gcc-patches, Richard Earnshaw, nickc
On Wed, Jun 10, 2015 at 08:57:37AM +0100, Christian Bruel wrote:
> Hi,
>
> Commited [4/6] as attached (r224314)
>
> thanks
>
> Christian
>
> On 06/08/2015 11:26 AM, Ramana Radhakrishnan wrote:
> > On 08/06/15 09:45, Christian Bruel wrote:
> >>
> >> do you have other feedbacks for the remaining parts ?
> >>
> >> many thanks
> >>
> >
> > This is OK, thanks.
> >
> > Ramana
Hi Christian,
This patch is causing an ICE for me in my arm-none-linux-gnueabihf testing.
It looks like something isn't saving/restoring/initialising data
structures needed for IRA.
I've raised https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66541 , the bug
looks very similar to pr64047
( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64047 ).
Thanks,
James
---
.../gcc/cc1 bug.c -O2 -ftree-parallelize-loops=4 -O2 -flto -fno-use-linker-plugin -ftree-parallelize-loops=4 -o pr52429.s
foo
Analyzing compilation unit
Performing interprocedural optimizations
<*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <free-inline-summary> <whole-program> <profile_estimate> <icf> <devirt> <cp> <inline> <pure-const> <static-var> <single-use> <comdats>Assembling functions:
foo
.../gcc/testsuite/gcc.dg/torture/pr52429.c: In function âfooâ:
.../gcc/testsuite/gcc.dg/torture/pr52429.c:11:1: internal compiler error: Segmentation fault
int i;
^
0xafa15f crash_signal
.../gcc/toplev.c:369
0x97c2b4 record_operand_costs
.../gcc/ira-costs.c:1305
0x97c7a4 scan_one_insn
.../gcc/ira-costs.c:1483
0x97c7a4 process_bb_for_costs
.../gcc/ira-costs.c:1604
0x97d715 find_costs_and_classes
.../gcc/ira-costs.c:1711
0x97ec3a ira_set_pseudo_classes(bool, _IO_FILE*)
.../gcc/ira-costs.c:2245
0xffd743 alloc_global_sched_pressure_data
.../gcc/haifa-sched.c:7119
0xffd743 sched_init()
.../gcc/haifa-sched.c:7269
0xffebcf haifa_sched_init()
.../gcc/haifa-sched.c:7281
0xaab8dc schedule_insns
.../gcc/sched-rgn.c:3411
0xaac0b3 schedule_insns
.../gcc/sched-rgn.c:3405
0xaac0b3 rest_of_handle_sched
.../gcc/sched-rgn.c:3624
0xaac0b3 execute
.../gcc/sched-rgn.c:3732
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6]
2015-06-15 10:15 ` James Greenhalgh
@ 2015-06-15 12:05 ` Christian Bruel
0 siblings, 0 replies; 15+ messages in thread
From: Christian Bruel @ 2015-06-15 12:05 UTC (permalink / raw)
To: James Greenhalgh
Cc: Ramana Radhakrishnan, Kyrylo Tkachov, Ramana Radhakrishnan,
Sandra Loosemore, gcc-patches, Richard Earnshaw, nickc
On 06/15/2015 12:00 PM, James Greenhalgh wrote:
> On Wed, Jun 10, 2015 at 08:57:37AM +0100, Christian Bruel wrote:
>> Hi,
>>
>> Commited [4/6] as attached (r224314)
>>
>> thanks
>>
>> Christian
>>
>> On 06/08/2015 11:26 AM, Ramana Radhakrishnan wrote:
>>> On 08/06/15 09:45, Christian Bruel wrote:
>>>>
>>>> do you have other feedbacks for the remaining parts ?
>>>>
>>>> many thanks
>>>>
>>>
>>> This is OK, thanks.
>>>
>>> Ramana
>
> Hi Christian,
>
> This patch is causing an ICE for me in my arm-none-linux-gnueabihf testing.
> It looks like something isn't saving/restoring/initialising data
> structures needed for IRA.
>
> I've raised https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66541 , the bug
> looks very similar to pr64047
> ( https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64047 ).
>
> Thanks,
> James
>
Hi James,
OK, I'll have a look. pr52429.c is reported as UNSUPPORTED with my runs
of arm-none-eabi (no threads), but I can reproduce with a manual run.
Cheers
Christian
> ---
> .../gcc/cc1 bug.c -O2 -ftree-parallelize-loops=4 -O2 -flto -fno-use-linker-plugin -ftree-parallelize-loops=4 -o pr52429.s
>
> foo
> Analyzing compilation unit
> Performing interprocedural optimizations
> <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <free-inline-summary> <whole-program> <profile_estimate> <icf> <devirt> <cp> <inline> <pure-const> <static-var> <single-use> <comdats>Assembling functions:
> foo
> .../gcc/testsuite/gcc.dg/torture/pr52429.c: In function âfooâ:
> .../gcc/testsuite/gcc.dg/torture/pr52429.c:11:1: internal compiler error: Segmentation fault
> int i;
> ^
> 0xafa15f crash_signal
> .../gcc/toplev.c:369
> 0x97c2b4 record_operand_costs
> .../gcc/ira-costs.c:1305
> 0x97c7a4 scan_one_insn
> .../gcc/ira-costs.c:1483
> 0x97c7a4 process_bb_for_costs
> .../gcc/ira-costs.c:1604
> 0x97d715 find_costs_and_classes
> .../gcc/ira-costs.c:1711
> 0x97ec3a ira_set_pseudo_classes(bool, _IO_FILE*)
> .../gcc/ira-costs.c:2245
> 0xffd743 alloc_global_sched_pressure_data
> .../gcc/haifa-sched.c:7119
> 0xffd743 sched_init()
> .../gcc/haifa-sched.c:7269
> 0xffebcf haifa_sched_init()
> .../gcc/haifa-sched.c:7281
> 0xaab8dc schedule_insns
> .../gcc/sched-rgn.c:3411
> 0xaac0b3 schedule_insns
> .../gcc/sched-rgn.c:3405
> 0xaac0b3 rest_of_handle_sched
> .../gcc/sched-rgn.c:3624
> 0xaac0b3 execute
> .../gcc/sched-rgn.c:3732
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <http://gcc.gnu.org/bugs.html> for instructions.
>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-06-15 10:43 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 14:25 [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
2015-05-06 23:04 ` Sandra Loosemore
2015-05-08 8:31 ` Ramana Radhakrishnan
2015-05-18 7:18 ` Christian Bruel
2015-05-18 8:16 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (5th) Christian Bruel
2015-06-01 10:39 ` Kyrill Tkachov
2015-06-01 11:30 ` Christian Bruel
2015-06-01 12:41 ` Kyrill Tkachov
2015-06-01 12:55 ` Christian Bruel
2015-06-08 9:26 ` Christian Bruel
2015-06-08 9:33 ` Ramana Radhakrishnan
2015-06-10 8:26 ` [PATCH, ARM] (commited) attribute target (thumb,arm) [4/6] Christian Bruel
2015-06-15 10:15 ` James Greenhalgh
2015-06-15 12:05 ` Christian Bruel
2015-05-07 8:13 ` [PATCH, ARM] attribute target (thumb,arm) [4/6] respin (4th) Christian Bruel
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).