From: Georg-Johann Lay Date: Tue, 9 Jan 2018 10:38:45 +0000 (+0000) Subject: Don't save registers in main(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dcbe9170136139ea9cc3a85699efebb2b7be0fa2;p=gcc.git Don't save registers in main(). gcc/ Don't save registers in main(). PR target/83737 * 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]
: Add OS_task attribute. * common/config/avr/avr-common.c (avr_option_optimization_table): Switch on -mmain-is-OS_task for optimizing compilations. From-SVN: r256373 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 813dca6472d..bdda6c8de13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2018-01-09 Georg-Johann Lay + + Don't save registers in main(). + + PR target/83737 + * 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]
: Add OS_task + attribute. + * common/config/avr/avr-common.c (avr_option_optimization_table): + Switch on -mmain-is-OS_task for optimizing compilations. + 2018-01-09 Richard Biener PR tree-optimization/83572 diff --git a/gcc/common/config/avr/avr-common.c b/gcc/common/config/avr/avr-common.c index e69be8239bd..078584d53c3 100644 --- a/gcc/common/config/avr/avr-common.c +++ b/gcc/common/config/avr/avr-common.c @@ -31,6 +31,7 @@ static const struct default_options avr_option_optimization_table[] = // 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 } }; diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 12645f9f5e7..ad155125741 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -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_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_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_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_callee, tree exp_callee) 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)) diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index da2a219078a..40177c28f7d 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -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) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c6025382dbb..928561d0e8f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -669,7 +669,8 @@ Objective-C and Objective-C++ Dialects}. -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 note that this option does not 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 the same like +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