The "io", "io_low", and "address" attributes require to asm output
the definition of respective symbols in a manner that was not supported
until the introduction of the new target hook TARGET_ASM_VARIABLE.

The previous implementation of these attributes abused tls_common_section
which is a noswitch section.  Notice that the middle-end doesn't allow to
introduce own, custom noswitch sections.
   The tls_comm_section->noswitch.callback allowed for a custom asm output
regardless of -f[no-]data-sections and -f[no-]common.  However, it would
not work with checking enabled due to varasm.cc::assemble_variable()'s

  /* Emulated TLS had better not get this far.  */
  gcc_checking_assert (targetm.have_tls || !DECL_THREAD_LOCAL_P (decl));

This patch avoids that hack and uses the new TARGET_ASM_VARIABLE target
hook to output variables with the mentioned attributes.

Ok for trunk?

Johann

--

AVR: target/112952 - Use new TARGET_ASM_VARIABLE for io, io_low, address.

The "io", "io_low", and "address" attributes require to asm output
the definition of respective symbols in a manner that was not supported
until the introduction of the new target hook TARGET_ASM_VARIABLE.

The previous implementation of these attributes abused tls_common_section
which is a noswitch section.  Notice that the middle-end doesn't allow to
introduce own, custom noswitch sections.
   The tls_comm_section->noswitch.callback allowed for a custom asm output
regardless of -f[no-]data-sections and -f[no-]common.  However, it would
not work with checking enabled due to varasm.cc::assemble_variable()'s

  /* Emulated TLS had better not get this far.  */
  gcc_checking_assert (targetm.have_tls || !DECL_THREAD_LOCAL_P (decl));

This patch avoids that hack and uses the new TARGET_ASM_VARIABLE target
hook to output variables with the mentioned attributes.

        PR target/112952
gcc/
        * config/avr/avr.cc (avr_output_addr_attrib): Rename and
        rewrite to avr_asm_variable.
        (avr_asm_init_sections): Leave tls_comm_section alone.
        (avr_encode_section_info) [io, io_low, address]: Don't
        abuse tls_comm_section.
        (TARGET_ASM_VARIABLE): New define to avr_asm_variable.
diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 05a6905b5d6..a326d029412 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -11689,24 +11689,25 @@ avr_output_progmem_section_asm_op (const char *data)
 }
 
 
-/* A noswitch section callback to output symbol definitions for
-   attributes "io", "io_low" and "address".  */
+/* Implement `TARGET_ASM_VARIABLE'.  */
+/* Output symbol definitions for attributes "io", "io_low" and "address".
+   This hook is the only way to output the definitions in the required way
+   since the middle-end makes assumptions on the asm representation that
+   don't hold for these attributes.  */
 
 static bool
-avr_output_addr_attrib (tree decl, const char *name,
-			unsigned HOST_WIDE_INT /* size */,
-			unsigned HOST_WIDE_INT /* align */)
+avr_asm_variable (FILE *stream, tree decl, const char *name)
 {
-  gcc_assert (DECL_RTL_SET_P (decl));
+  rtx mem, symbol;
 
-  FILE *stream = asm_out_file;
-  bool local_p = ! DECL_WEAK (decl) && ! TREE_PUBLIC (decl);
-  rtx symbol, mem = DECL_RTL (decl);
-
-  if (mem != NULL_RTX && MEM_P (mem)
-      && SYMBOL_REF_P ((symbol = XEXP (mem, 0)))
+  if (VAR_P (decl)
+      && DECL_RTL_SET_P (decl)
+      && MEM_P (mem = DECL_RTL (decl))
+      && SYMBOL_REF_P (symbol = XEXP (mem, 0))
       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
     {
+      bool local_p = ! DECL_WEAK (decl) && ! TREE_PUBLIC (decl);
+
       if (! local_p)
 	{
 	  fprintf (stream, "\t%s\t", DECL_WEAK (decl) ? ".weak" : ".globl");
@@ -11735,8 +11736,6 @@ avr_output_addr_attrib (tree decl, const char *name,
       return true;
     }
 
-  gcc_unreachable ();
-
   return false;
 }
 
@@ -11754,7 +11753,6 @@ avr_asm_init_sections (void)
     readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
   data_section->unnamed.callback = avr_output_data_section_asm_op;
   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
-  tls_comm_section->noswitch.callback = avr_output_addr_attrib;
 }
 
 
@@ -11974,18 +11972,11 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
 	    }
 	  else
 	    {
-	      /* PR112952: The only way to output a variable declaration in a
-		 custom manner is by means of a noswitch section callback.
-		 There are only three noswitch sections: comm_section,
-		 lcomm_section and tls_comm_section.  And there is no way to
-		 wire a custom noswitch section to a decl.  As lcomm_section
-		 is bypassed with -fdata-sections -fno-common, there is no
-		 other way than making use of tls_comm_section.  As we are
-		 using that section anyway, also use it in the public case.  */
-
-	      DECL_COMMON (decl) = 1;
+	      /* PR112952: Thanks to TARGET_ASM_VARIABLE, we can output
+		 a variable / symbol definition in a custom way entirely.
+		 There's no more need to abuse tls_comm_section.  */
+
 	      set_decl_section_name (decl, (const char *) nullptr);
-	      set_decl_tls_model (decl, (tls_model) 2);
 	    }
 	}
     }
@@ -16076,6 +16067,9 @@ avr_use_lra_p ()
 #undef  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
 
+#undef  TARGET_ASM_VARIABLE
+#define TARGET_ASM_VARIABLE avr_asm_variable
+
 #undef  TARGET_FUNCTION_VALUE
 #define TARGET_FUNCTION_VALUE avr_function_value
 #undef  TARGET_LIBCALL_VALUE

Reply via email to