On 08.01.2018 18:39, Denis Chertykov wrote:
2018-01-08 20:19 GMT+04:00 Georg-Johann Lay <a...@gjlay.de>:
This PR skips saving of any registers in main.
Attribute OS_main can do this as well, however we can just drop
any saves / restores in all optimized compilation -- not even
the test suite needs these saves.
The feature can still be switched off by new -mno-OS_main
Ok for trunk?
I like it.
Please commit.
Committed a different approach:
1) The effect is the same as OS_task, hence named the
option -mmain-is-OS_task. OS_main is too strict
because that'd assume that IRQs are off when main is
entered, hence due to that rare case (and when main
needs a frame) OS_task is the right feature.
2) Instead of fiddling with prologue / epilogue directly,
now just add OS_task to main.
3) Some restrictions have been removed re. diagnostics
when naked, OS_task, OS_main are specified at the
same time. Instead, the logic follows now just
what the attributes are requesting (e.g. OS_main
supersedes OS_task and naked supersedes OS_main).
The original subject has a typo: The PR is PR83738.
PR target/83738
* doc/invoke.texi (AVR Options) [-mmain-is-OS_task]: Document it.
* config/avr/avr.opt (-mmain-is-OS_task): New target option.
* config/avr/avr.c (avr_set_current_function): Don't error if
naked, OS_task or OS_main are specified at the same time.
(avr_function_ok_for_sibcall): Don't disable sibcalls for OS_task,
OS_main.
(avr_insert_attributes) [-mmain-is-OS_task] <main>: Add OS_task
attribute.
* common/config/avr/avr-common.c (avr_option_optimization_table):
Switch on -mmain-is-OS_task for optimizing compilations.
Index: common/config/avr/avr-common.c
===================================================================
--- common/config/avr/avr-common.c (revision 256338)
+++ common/config/avr/avr-common.c (working copy)
@@ -31,6 +31,7 @@ static const struct default_options avr_
// a frame without need when it tries to be smart around calls.
{ OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_mgas_isr_prologues, NULL, 1 },
+ { OPT_LEVELS_1_PLUS, OPT_mmain_is_OS_task, NULL, 1 },
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c (revision 256338)
+++ config/avr/avr.c (working copy)
@@ -1030,9 +1030,6 @@ avr_no_gccisr_function_p (tree func)
static void
avr_set_current_function (tree decl)
{
- location_t loc;
- const char *isr;
-
if (decl == NULL_TREE
|| current_function_decl == NULL_TREE
|| current_function_decl == error_mark_node
@@ -1040,7 +1037,7 @@ avr_set_current_function (tree decl)
|| cfun->machine->attributes_checked_p)
return;
- loc = DECL_SOURCE_LOCATION (decl);
+ location_t loc = DECL_SOURCE_LOCATION (decl);
cfun->machine->is_naked = avr_naked_function_p (decl);
cfun->machine->is_signal = avr_signal_function_p (decl);
@@ -1049,21 +1046,19 @@ avr_set_current_function (tree decl)
cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl);
- isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
+ const char *isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
/* Too much attributes make no sense as they request conflicting features. */
- if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
- + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
- error_at (loc, "function attributes %qs, %qs and %qs are mutually"
- " exclusive", "OS_task", "OS_main", isr);
-
- /* 'naked' will hide effects of 'OS_task' and 'OS_main'. */
-
- if (cfun->machine->is_naked
- && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
- warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
- " no effect on %qs function", "OS_task", "OS_main", "naked");
+ if (cfun->machine->is_OS_task
+ && (cfun->machine->is_signal || cfun->machine->is_interrupt))
+ error_at (loc, "function attributes %qs and %qs are mutually exclusive",
+ "OS_task", isr);
+
+ if (cfun->machine->is_OS_main
+ && (cfun->machine->is_signal || cfun->machine->is_interrupt))
+ error_at (loc, "function attributes %qs and %qs are mutually exclusive",
+ "OS_main", isr);
if (cfun->machine->is_interrupt || cfun->machine->is_signal)
{
@@ -3526,12 +3521,7 @@ avr_function_ok_for_sibcall (tree decl_c
if (cfun->machine->is_interrupt
|| cfun->machine->is_signal
|| cfun->machine->is_naked
- || avr_naked_function_p (decl_callee)
- /* FIXME: For OS_task and OS_main, this might be over-conservative. */
- || (avr_OS_task_function_p (decl_callee)
- != cfun->machine->is_OS_task)
- || (avr_OS_main_function_p (decl_callee)
- != cfun->machine->is_OS_main))
+ || avr_naked_function_p (decl_callee))
{
return false;
}
@@ -10101,13 +10091,29 @@ avr_pgm_check_var_decl (tree node)
}
-/* Add the section attribute if the variable is in progmem. */
+/* Implement `TARGET_INSERT_ATTRIBUTES'. */
static void
avr_insert_attributes (tree node, tree *attributes)
{
avr_pgm_check_var_decl (node);
+ if (TARGET_MAIN_IS_OS_TASK
+ && TREE_CODE (node) == FUNCTION_DECL
+ && MAIN_NAME_P (DECL_NAME (node))
+ // FIXME: We'd like to also test `flag_hosted' which is only
+ // available in the C-ish fronts, hence no such test for now.
+ // Instead, we test the return type of "main" which is not exactly
+ // the same but good enough.
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (node)))
+ && NULL == lookup_attribute ("OS_task", *attributes))
+ {
+ *attributes = tree_cons (get_identifier ("OS_task"),
+ NULL, *attributes);
+ }
+
+ /* Add the section attribute if the variable is in progmem. */
+
if (TREE_CODE (node) == VAR_DECL
&& (TREE_STATIC (node) || DECL_EXTERNAL (node))
&& avr_progmem_p (node, *attributes))
Index: config/avr/avr.opt
===================================================================
--- config/avr/avr.opt (revision 256338)
+++ config/avr/avr.opt (working copy)
@@ -64,6 +64,10 @@ mbranch-cost=
Target Report Joined RejectNegative UInteger Var(avr_branch_cost) Init(0)
Set the branch costs for conditional branch instructions. Reasonable values are small, non-negative integers. The default branch cost is 0.
+mmain-is-OS_task
+Target Report Mask(MAIN_IS_OS_TASK)
+Treat main as if it had attribute OS_task.
+
morder1
Target Report Undocumented Mask(ORDER_1)
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi (revision 256338)
+++ doc/invoke.texi (working copy)
@@ -669,7 +669,8 @@ -imacros @var{file} -imultilib @var{dir
-mbranch-cost=@var{cost} @gol
-mcall-prologues -mgas-isr-prologues -mint8 @gol
-mn_flash=@var{size} -mno-interrupts @gol
--mrelax -mrmw -mstrict-X -mtiny-stack -mfract-convert-truncate @gol
+-mmain-is-OS_task -mrelax -mrmw -mstrict-X -mtiny-stack @gol
+-mfract-convert-truncate @gol
-mshort-calls -nodevicelib @gol
-Waddr-space-convert -Wmisspelled-isr}
@@ -16462,6 +16463,12 @@ and @code{long long} is 4 bytes. Please
conform to the C standards, but it results in smaller code
size.
+@item -mmain-is-OS_task
+@opindex mmain-is-OS_task
+Do not save registers in @code{main}. The effect is similar to
+attaching attribute @ref{AVR Function Attributes,,@code{OS_task}}
+to @code{main}. It is activated per default if optimization is on.
+
@item -mn-flash=@var{num}
@opindex mn-flash
Assume that the flash memory has a size of