diff mbox

[PTX] var emission

Message ID 5661DEF1.2000708@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Dec. 4, 2015, 6:44 p.m. UTC
I've committed this patch to unify the variable emission machinery.  All four 
hooks were doing small variations of a common theme.  This introduces 
nvptx_assemble_decl_begin to do the common work.  While there, I expanded the 
init initialization code to work with multi-dimensional arrays.

nathan

Comments

Nathan Sidwell Dec. 4, 2015, 6:50 p.m. UTC | #1
On 12/04/15 13:44, Nathan Sidwell wrote:
> I've committed this patch to unify the variable emission machinery.  All four
> hooks were doing small variations of a common theme.  This introduces
> nvptx_assemble_decl_begin to do the common work.  While there, I expanded the
> init initialization code to work with multi-dimensional arrays.

I forgot to mention that undefined decls are now emitted with the expected size, 
rather than a plain '.b8'.  This fixed one of the struct compatibility tests, 
and I suspect a bunch of other inter-linking  cases.


nathan
diff mbox

Patch

2015-12-04  Nathan Sidwell  <nathan@acm.org>

	gcc/
	* config/nvptx/nvptx.c (nvptx_assemble_decl_begin): New,
	replacing ...
	(init_output_initializer): ... this.
	(nvptx_output_aligned_decl, nvptx_asm_declare_constant_name,
	nvptx_declare_object_name, nvptx_assemble_undefined_decl): Use
	nvptx_assemble_decl_begin.

	gcc/testsuite/
	* gcc.target/nvptx/ary-init.c: New.

Index: config/nvptx/nvptx.c
===================================================================
--- config/nvptx/nvptx.c	(revision 231267)
+++ config/nvptx/nvptx.c	(working copy)
@@ -1628,6 +1628,50 @@  nvptx_output_ascii (FILE *, const char *
     nvptx_assemble_value (str[i], 1);
 }
 
+/* Emit a PTX variable decl and prepare for emission of its
+   initializer.  NAME is the symbol name and SETION the PTX data
+   area. The type is TYPE, object size SIZE and alignment is ALIGN.
+   The caller has already emitted any indentation and linkage
+   specifier.  It is responsible for any initializer, terminating ;
+   and newline.  SIZE is in bytes, ALIGN is in bits -- confusingly
+   this is the opposite way round that PTX wants them!  */
+
+static void
+nvptx_assemble_decl_begin (FILE *file, const char *name, const char *section,
+			   const_tree type, HOST_WIDE_INT size, unsigned align)
+{
+  while (TREE_CODE (type) == ARRAY_TYPE)
+    type = TREE_TYPE (type);
+
+  if (!INTEGRAL_TYPE_P (type) && !SCALAR_FLOAT_TYPE_P (type))
+    type = ptr_type_node;
+  unsigned elt_size = int_size_in_bytes (type);
+  if (elt_size > UNITS_PER_WORD)
+    {
+      type = ptr_type_node;
+      elt_size = int_size_in_bytes (type);
+    }
+
+  decl_chunk_size = elt_size;
+  decl_chunk_mode = int_mode_for_mode (TYPE_MODE (type));
+  decl_offset = 0;
+  init_part = 0;
+
+  object_size = size;
+  object_finished = !size;
+
+  fprintf (file, "%s .align %d .u%d ",
+	   section, align / BITS_PER_UNIT,
+	   elt_size * BITS_PER_UNIT);
+  assemble_name (file, name);
+
+  if (size)
+    /* We make everything an array, to simplify any initialization
+       emission.  */
+    fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
+	     (size + elt_size - 1) / elt_size);
+}
+
 /* Called when the initializer for a decl has been completely output through
    combinations of the three functions above.  */
 
@@ -1644,33 +1688,6 @@  nvptx_assemble_decl_end (void)
   fprintf (asm_out_file, ";\n");
 }
 
-/* Start a declaration of a variable of TYPE with NAME to
-   FILE.  IS_PUBLIC says whether this will be externally visible.
-   Here we just write the linker hint and decide on the chunk size
-   to use.  */
-
-static void
-init_output_initializer (FILE *file, const char *name, const_tree type,
-			 bool is_public)
-{
-  write_var_marker (file, true, is_public, name);
-
-  if (TREE_CODE (type) == ARRAY_TYPE)
-    type = TREE_TYPE (type);
-  int sz = int_size_in_bytes (type);
-  if ((TREE_CODE (type) != INTEGER_TYPE
-       && TREE_CODE (type) != ENUMERAL_TYPE
-       && TREE_CODE (type) != REAL_TYPE)
-      || sz < 0
-      || sz > HOST_BITS_PER_WIDE_INT)
-    type = ptr_type_node;
-  decl_chunk_size = int_size_in_bytes (type);
-  decl_chunk_mode = int_mode_for_mode (TYPE_MODE (type));
-  decl_offset = 0;
-  init_part = 0;
-  object_finished = false;
-}
-
 /* Output an uninitialized common or file-scope variable.  */
 
 void
@@ -1681,13 +1698,10 @@  nvptx_output_aligned_decl (FILE *file, c
 
   /* If this is public, it is common.  The nearest thing we have to
      common is weak.  */
-  fprintf (file, "\t%s%s .align %d .b8 ",
-	   TREE_PUBLIC (decl) ? ".weak " : "",
-	   section_for_decl (decl),
-	   align / BITS_PER_UNIT);
-  assemble_name (file, name);
-  if (size > 0)
-    fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC"]", size);
+  fprintf (file, "\t%s", TREE_PUBLIC (decl) ? ".weak " : "");
+
+  nvptx_assemble_decl_begin (file, name, section_for_decl (decl),
+			     TREE_TYPE (decl), size, align);
   fprintf (file, ";\n");
 }
 
@@ -1697,17 +1711,15 @@  nvptx_output_aligned_decl (FILE *file, c
 
 static void
 nvptx_asm_declare_constant_name (FILE *file, const char *name,
-				 const_tree exp, HOST_WIDE_INT size)
+				 const_tree exp, HOST_WIDE_INT obj_size)
 {
+  write_var_marker (file, true, false, name);
+
+  fprintf (file, "\t");
+
   tree type = TREE_TYPE (exp);
-  init_output_initializer (file, name, type, false);
-  fprintf (file, "\t.const .align %d .u%d ",
-	   TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT,
-	   decl_chunk_size * BITS_PER_UNIT);
-  assemble_name (file, name);
-  fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
-	   (size + decl_chunk_size - 1) / decl_chunk_size);
-  object_size = size;
+  nvptx_assemble_decl_begin (file, name, ".const", type, obj_size,
+			     TYPE_ALIGN (type));
 }
 
 /* Implement the ASM_DECLARE_OBJECT_NAME macro.  Used to start writing
@@ -1716,24 +1728,15 @@  nvptx_asm_declare_constant_name (FILE *f
 void
 nvptx_declare_object_name (FILE *file, const char *name, const_tree decl)
 {
-  tree type = TREE_TYPE (decl);
+  write_var_marker (file, true, TREE_PUBLIC (decl), name);
 
-  init_output_initializer (file, name, type, TREE_PUBLIC (decl));
-  fprintf (file, "\t%s%s .align %d .u%d ",
-	   !TREE_PUBLIC (decl) ? ""
-	   : DECL_WEAK (decl) ? ".weak " : ".visible ",
-	   section_for_decl (decl),
-	   DECL_ALIGN (decl) / BITS_PER_UNIT,
-	   decl_chunk_size * BITS_PER_UNIT);
-  assemble_name (file, name);
+  fprintf (file, "\t%s", (!TREE_PUBLIC (decl) ? ""
+			  : DECL_WEAK (decl) ? ".weak " : ".visible "));
 
-  unsigned HOST_WIDE_INT size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
-  if (size > 0)
-    fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC "]",
-	     (size + decl_chunk_size - 1) / decl_chunk_size);
-  else
-    object_finished = true;
-  object_size = size;
+  tree type = TREE_TYPE (decl);
+  HOST_WIDE_INT obj_size = tree_to_shwi (DECL_SIZE_UNIT (decl));
+  nvptx_assemble_decl_begin (file, name, section_for_decl (decl),
+			     type, obj_size, DECL_ALIGN (decl));
 }
 
 /* Implement TARGET_ASM_GLOBALIZE_LABEL by doing nothing.  */
@@ -1751,12 +1754,11 @@  nvptx_assemble_undefined_decl (FILE *fil
 {
   write_var_marker (file, false, TREE_PUBLIC (decl), name);
 
-  fprintf (file, "\t.extern %s .b8 ", section_for_decl (decl));
-  assemble_name_raw (file, name);
-
-  HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
-  if (size > 0)
-    fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC"]", size);
+  fprintf (file, "\t.extern ");
+  tree size = DECL_SIZE_UNIT (decl);
+  nvptx_assemble_decl_begin (file, name, section_for_decl (decl),
+			     TREE_TYPE (decl), size ? tree_to_shwi (size) : 0,
+			     DECL_ALIGN (decl));
   fprintf (file, ";\n");
 }
 
Index: testsuite/gcc.target/nvptx/ary-init.c
===================================================================
--- testsuite/gcc.target/nvptx/ary-init.c	(revision 0)
+++ testsuite/gcc.target/nvptx/ary-init.c	(working copy)
@@ -0,0 +1,21 @@ 
+/* { dg-additional-options "-Wno-long-long" } */
+
+char ca1[2] = {'a', 'b'};
+short sa1[2] = { 1, 2 };
+int ia1[2] = { 3, 4 };
+long long la1[2] = { 5, 6 };
+
+char ca2[2][2] = {'A', 'B', 'C', 'D'};
+short sa2[2][2] = { 7, 8, 9, 10 };
+int ia2[2][2] = { 11, 12, 13, 14 };
+long long la2[2][2] = { 15, 16, 17, 18 };
+
+/* dg-final { scan-assembler " .align 8 .u64 la1\\\[2\\\] = { 5, 6 };" } } */
+/* dg-final { scan-assembler " .align 4 .u32 ia1\\\[2\\\] = { 3, 4 };" } } */
+/* dg-final { scan-assembler " .align 2 .u16 sa1\\\[2\\\] = { 1, 2 };" } } */
+/* dg-final { scan-assembler " .align 1 .u8 ca1\\\[2\\\] = { 97, 98 };" } } */
+
+/* dg-final { scan-assembler " .align 8 .u64 la2\\\[4\\\] = { 15, 16, 17, 18 };" } } */
+/* dg-final { scan-assembler " .align 4 .u32 ia2\\\[4\\\] = { 11, 12, 13, 14 };" } } */
+/* dg-final { scan-assembler " .align 2 .u16 sa2\\\[4\\\] = { 7, 8, 9, 10 };" } } */
+/* dg-final { scan-assembler " .align 1 .u8 ca2\\\[4\\\] = { 65, 66, 67, 68 };" } } */