diff mbox

The nvptx port [8/11+] Write undefined decls.

Message ID 54451C9F.2080503@codesourcery.com
State New
Headers show

Commit Message

Bernd Schmidt Oct. 20, 2014, 2:30 p.m. UTC
ptx assembly requires that declarations are written for undefined 
variables. This adds that functionality.


Bernd

Comments

Jeff Law Oct. 21, 2014, 10:05 p.m. UTC | #1
On 10/20/14 14:30, Bernd Schmidt wrote:
> ptx assembly requires that declarations are written for undefined
> variables. This adds that functionality.
>
>
> Bernd
>
>
> 008-undefdecl.diff
>
>
> 	gcc/
> 	* target.def (assemble_undefined_decl): New hooks.
> 	* hooks.c (hook_void_FILEptr_constcharptr_const_tree): New function.
> 	* hooks.h (hook_void_FILEptr_constcharptr_const_tree): Declare.
> 	* doc/tm.texi.in (TARGET_ASM_ASSEMBLE_UNDEFINED_DECL): Add.
> 	* doc/tm.texi: Regenerate.
> 	* output.h (assemble_undefined_decl): Declare.
> 	(get_fnname_from_decl): Declare.
> 	* varasm.c (assemble_undefined_decl): New function.
> 	(get_fnname_from_decl): New function.
> 	* final.c (rest_of_handle_final): Use it.
> 	* varpool.c (varpool_output_variables): Call assemble_undefined_decl
> 	for nodes without a definition.
Does this need to happen at the use site, or can it be deferred?

THe PA had to do something similar.  We built up a vector of every 
external object in ASM_OUTPUT_EXTERNAL, but did not emit anything.

Then in ASM_FILE_END, we walked that vector and anything that was 
actually referenced (as opposed to just just declared) we would emit the 
magic .IMPORT lines.

Jeff
Bernd Schmidt Oct. 21, 2014, 10:15 p.m. UTC | #2
On 10/22/2014 12:05 AM, Jeff Law wrote:
> On 10/20/14 14:30, Bernd Schmidt wrote:
>> ptx assembly requires that declarations are written for undefined
>> variables. This adds that functionality.
> Does this need to happen at the use site, or can it be deferred?

This is independent of use sites. The patch just adds another walk over 
the varpool to emit not just the defined vars.

Ideally we'd maintain an order that declares or defines every variable 
before it is referenced by an initializer, but the attempt to do that in 
the compiler totally failed due to references between constant pools and 
regular variables. The nvptx-as tool we have fixes up the order of 
declarations after the first compilation stage.

> THe PA had to do something similar.  We built up a vector of every
> external object in ASM_OUTPUT_EXTERNAL, but did not emit anything.
>
> Then in ASM_FILE_END, we walked that vector and anything that was
> actually referenced (as opposed to just just declared) we would emit the
> magic .IMPORT lines.

Sounds like the PA could use this hook to simplify its code quite a bit.

Looking at the patch again I noticed there's still some unrelated code 
in here - the patch used to be quite a lot larger and got shrunk due to 
the failure mentioned above. get_fnname_for_decl is just a new function 
broken out of rest_of_handle_final, it is used by the nvptx.c code.


Bernd
Jeff Law Oct. 22, 2014, 6:11 p.m. UTC | #3
On 10/21/14 16:15, Bernd Schmidt wrote:
> On 10/22/2014 12:05 AM, Jeff Law wrote:
>> On 10/20/14 14:30, Bernd Schmidt wrote:
>>> ptx assembly requires that declarations are written for undefined
>>> variables. This adds that functionality.
>> Does this need to happen at the use site, or can it be deferred?
>
> This is independent of use sites. The patch just adds another walk over
> the varpool to emit not just the defined vars.
>
> Ideally we'd maintain an order that declares or defines every variable
> before it is referenced by an initializer, but the attempt to do that in
> the compiler totally failed due to references between constant pools and
> regular variables. The nvptx-as tool we have fixes up the order of
> declarations after the first compilation stage.
>
>> THe PA had to do something similar.  We built up a vector of every
>> external object in ASM_OUTPUT_EXTERNAL, but did not emit anything.
>>
>> Then in ASM_FILE_END, we walked that vector and anything that was
>> actually referenced (as opposed to just just declared) we would emit the
>> magic .IMPORT lines.
>
> Sounds like the PA could use this hook to simplify its code quite a bit.
The PA stuff is a trivial amount of code :-)  But it is a bit awkward in 
that we're using a per-variable hook to stash, then the end-file hook to 
walk the stashed stuff.

IIRC, the problem is tentative definitions.  Otherwise we'd just emit 
the .import statements as we saw the declarations.  I believe that was 
to properly interface with the HP assembler/linker.

We also have to defer emitting plabels, but I can't recall the 
braindamage behind that.


I'm not going to insist you do this in the same way as the PA.  That was 
a different era -- we had significant motivation to make things work in 
such a way that everything could be buried in the pa specific files. 
That sometimes led to less than optimal approaches to fix certain problems.


Jeff
Bernd Schmidt Nov. 5, 2014, 12:01 p.m. UTC | #4
On 10/22/2014 08:11 PM, Jeff Law wrote:
> I'm not going to insist you do this in the same way as the PA.  That was
> a different era -- we had significant motivation to make things work in
> such a way that everything could be buried in the pa specific files.
> That sometimes led to less than optimal approaches to fix certain problems.

So... is this patch approved?


Bernd
Jeff Law Nov. 5, 2014, 8:05 p.m. UTC | #5
On 11/05/14 05:01, Bernd Schmidt wrote:
> On 10/22/2014 08:11 PM, Jeff Law wrote:
>> I'm not going to insist you do this in the same way as the PA.  That was
>> a different era -- we had significant motivation to make things work in
>> such a way that everything could be buried in the pa specific files.
>> That sometimes led to less than optimal approaches to fix certain
>> problems.
>
> So... is this patch approved?
Yes, sorry for not being explicit.

Jeff
diff mbox

Patch

	gcc/
	* target.def (assemble_undefined_decl): New hooks.
	* hooks.c (hook_void_FILEptr_constcharptr_const_tree): New function.
	* hooks.h (hook_void_FILEptr_constcharptr_const_tree): Declare.
	* doc/tm.texi.in (TARGET_ASM_ASSEMBLE_UNDEFINED_DECL): Add.
	* doc/tm.texi: Regenerate.
	* output.h (assemble_undefined_decl): Declare.
	(get_fnname_from_decl): Declare.
	* varasm.c (assemble_undefined_decl): New function.
	(get_fnname_from_decl): New function.
	* final.c (rest_of_handle_final): Use it.
	* varpool.c (varpool_output_variables): Call assemble_undefined_decl
	for nodes without a definition.

------------------------------------------------------------------------
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi.orig
+++ gcc/doc/tm.texi
@@ -7899,6 +7902,13 @@  global; that is, available for reference
 The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_ASM_ASSEMBLE_UNDEFINED_DECL (FILE *@var{stream}, const char *@var{name}, const_tree @var{decl})
+This target hook is a function to output to the stdio stream
+@var{stream} some commands that will declare the name associated with
+@var{decl} which is not defined in the current translation unit.  Most
+assemblers do not require anything to be output in this case.
+@end deftypefn
+
 @defmac ASM_WEAKEN_LABEL (@var{stream}, @var{name})
 A C statement (sans semicolon) to output to the stdio stream
 @var{stream} some commands that will make the label @var{name} weak;
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in.orig
+++ gcc/doc/tm.texi.in
@@ -5693,6 +5693,8 @@  You may wish to use @code{ASM_OUTPUT_SIZ
 
 @hook TARGET_ASM_GLOBALIZE_DECL_NAME
 
+@hook TARGET_ASM_ASSEMBLE_UNDEFINED_DECL
+
 @defmac ASM_WEAKEN_LABEL (@var{stream}, @var{name})
 A C statement (sans semicolon) to output to the stdio stream
 @var{stream} some commands that will make the label @var{name} weak;
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c.orig
+++ gcc/hooks.c
@@ -139,6 +139,13 @@  hook_void_FILEptr_constcharptr (FILE *a
 {
 }
 
+/* Generic hook that takes (FILE *, const char *, constr_tree *) and does
+   nothing.  */
+void
+hook_void_FILEptr_constcharptr_const_tree (FILE *, const char *, const_tree)
+{
+}
+
 /* Generic hook that takes (FILE *, rtx) and returns false.  */
 bool
 hook_bool_FILEptr_rtx_false (FILE *a ATTRIBUTE_UNUSED,
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h.orig
+++ gcc/hooks.h
@@ -69,6 +69,8 @@  extern void hook_void_void (void);
 extern void hook_void_constcharptr (const char *);
 extern void hook_void_rtx_int (rtx, int);
 extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
+extern void hook_void_FILEptr_constcharptr_const_tree (FILE *, const char *,
+						       const_tree);
 extern bool hook_bool_FILEptr_rtx_false (FILE *, rtx);
 extern void hook_void_rtx (rtx);
 extern void hook_void_tree (tree);
Index: gcc/target.def
===================================================================
--- gcc/target.def.orig
+++ gcc/target.def
@@ -158,6 +158,16 @@  global; that is, available for reference
 The default implementation uses the TARGET_ASM_GLOBALIZE_LABEL target hook.",
  void, (FILE *stream, tree decl), default_globalize_decl_name)
 
+/* Output code that will declare an external variable.  */
+DEFHOOK
+(assemble_undefined_decl,
+ "This target hook is a function to output to the stdio stream\n\
+@var{stream} some commands that will declare the name associated with\n\
+@var{decl} which is not defined in the current translation unit.  Most\n\
+assemblers do not require anything to be output in this case.",
+ void, (FILE *stream, const char *name, const_tree decl),
+ hook_void_FILEptr_constcharptr_const_tree)
+
 /* Output code that will emit a label for unwind info, if this
    target requires such labels.  Second argument is the decl the
    unwind info is associated with, third is a boolean: true if
Index: gcc/final.c
===================================================================
--- gcc/final.c.orig
+++ gcc/final.c
@@ -4434,17 +4434,7 @@  leaf_renumber_regs_insn (rtx in_rtx)
 static unsigned int
 rest_of_handle_final (void)
 {
-  rtx x;
-  const char *fnname;
-
-  /* Get the function's name, as described by its RTL.  This may be
-     different from the DECL_NAME name used in the source file.  */
-
-  x = DECL_RTL (current_function_decl);
-  gcc_assert (MEM_P (x));
-  x = XEXP (x, 0);
-  gcc_assert (GET_CODE (x) == SYMBOL_REF);
-  fnname = XSTR (x, 0);
+  const char *fnname = get_fnname_from_decl (current_function_decl);
 
   assemble_start_function (current_function_decl, fnname);
   final_start_function (get_insns (), asm_out_file, optimize);
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c.orig
+++ gcc/varasm.c
@@ -1611,6 +1611,18 @@  decide_function_section (tree decl)
   in_cold_section_p = first_function_block_is_cold;
 }
 
+/* Get the function's name, as described by its RTL.  This may be
+   different from the DECL_NAME name used in the source file.  */
+const char *
+get_fnname_from_decl (tree decl)
+{
+  rtx x = DECL_RTL (decl);
+  gcc_assert (MEM_P (x));
+  x = XEXP (x, 0);
+  gcc_assert (GET_CODE (x) == SYMBOL_REF);
+  return XSTR (x, 0);
+}
+
 /* Output assembler code for the constant pool of a function and associated
    with defining the name of the function.  DECL describes the function.
    NAME is the function's name.  For the constant pool, we use the current
@@ -1977,6 +1989,15 @@  assemble_variable_contents (tree decl, c
     }
 }
 
+/* Write out assembly for the variable DECL, which is not defined in
+   the current translation unit.  */
+void
+assemble_undefined_decl (tree decl)
+{
+  const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+  targetm.asm_out.assemble_undefined_decl (asm_out_file, name, decl);
+}
+
 /* Assemble everything that is needed for a variable or function declaration.
    Not used for automatic variables, and not used for function definitions.
    Should not be called for variables of incomplete structure type.
Index: gcc/output.h
===================================================================
--- gcc/output.h.orig
+++ gcc/output.h
@@ -176,6 +176,9 @@  extern void default_assemble_visibility
    for an `asm' keyword used between functions.  */
 extern void assemble_asm (tree);
 
+/* Get the function's name from a decl, as described by its RTL.  */
+extern const char *get_fnname_from_decl (tree);
+
 /* Output assembler code for the constant pool of a function and associated
    with defining the name of the function.  DECL describes the function.
    NAME is the function's name.  For the constant pool, we use the current
@@ -201,6 +204,10 @@  extern void assemble_variable (tree, int
    into the preinit array.  */
 extern void assemble_vtv_preinit_initializer (tree);
 
+/* Assemble everything that is needed for a variable declaration that has
+   no definition in the current translation unit.  */
+extern void assemble_undefined_decl (tree);
+
 /* Compute the alignment of variable specified by DECL.
    DONT_OUTPUT_DATA is from assemble_variable.  */
 extern void align_variable (tree decl, bool dont_output_data);
Index: gcc/varpool.c
===================================================================
--- gcc/varpool.c.orig
+++ gcc/varpool.c
@@ -610,6 +642,9 @@  varpool_output_variables (void)
   FOR_EACH_DEFINED_VARIABLE (node)
     varpool_finalize_named_section_flags (node);
 
+  FOR_EACH_VARIABLE (node)
+    if (!node->definition)
+      assemble_undefined_decl (node->decl);
   FOR_EACH_DEFINED_VARIABLE (node)
     if (varpool_assemble_decl (node))
       changed = true;