Don't save registers in main().
authorGeorg-Johann Lay <avr@gjlay.de>
Tue, 9 Jan 2018 10:38:45 +0000 (10:38 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Tue, 9 Jan 2018 10:38:45 +0000 (10:38 +0000)
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] <main>: 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

gcc/ChangeLog
gcc/common/config/avr/avr-common.c
gcc/config/avr/avr.c
gcc/config/avr/avr.opt
gcc/doc/invoke.texi

index 813dca6472dbfad5836f1898496a6a90fc49f0dd..bdda6c8de13659f5477b7284b0de1c6acee83d40 100644 (file)
@@ -1,3 +1,19 @@
+2018-01-09  Georg-Johann Lay  <avr@gjlay.de>
+
+       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] <main>: 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  <rguenther@suse.de>
 
        PR tree-optimization/83572
index e69be8239bde9917e7b48bacc670f0f7d959f462..078584d53c3bd2edfdc3043c298cf118177a2fbb 100644 (file)
@@ -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 }
   };
 
index 12645f9f5e71803750b5ea162908f1b43827b55c..ad15512574118632aa20365e1e6293dd6036d1a6 100644 (file)
@@ -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))
index da2a219078a9777eef7bb30980da2500eba20ce2..40177c28f7d6766f35d391dd1d772c5afafce991 100644 (file)
@@ -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 c6025382dbb8349ed5cec63c559276a4776254f1..928561d0e8f4f1baaad54f6df4d3ea030f56366f 100644 (file)
@@ -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