Unit at a time 2/3 II - local functions

Jan Hubicka jh@suse.cz
Thu Feb 20 10:05:00 GMT 2003


Hi,
this is updated patch for local functions.  This patch does NOT bootstrap with fortran
frontend enabled.  This is because i386.o now force cgraph.o that force tree-inline.o
that requires build_stmt and so not provided by fortran frontend.

In the case my inlining patch will get accepted, it already contains
cgraph.h file so not everything have to come into cgraph.c. I would like
to simply break cgraph.c into cgraph.c containing generic cgraph
handling stuff and cgraphunit.c containing the code to deal with
unit-at-a-time compilation.  That way I will break the chain and
everything will work fine.

Honza

/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -funit-at-a-time" } */
/* { dg-final { scan-assembler "magic.*eax" } } */

/* Verify that local calling convention is used.  */
static t(int) __attribute__ ((noinline));
m()
{
	t(1);
}
static t(int a)
{
	asm("magic %1"::"g"(a));
}
Thu Feb 20 10:50:38 CET 2003  Jan Hubicka  <jh@suse.cz>
	* cgraph.c  (cgraph_node):  Add field "local".
	(cgraph_mark_local_functions): New local function.
	(cgraph_local_function_p): New global function.
	(cgraph_optimize): Mark local functions.
	* tree.h (cgraph_local_function_p): Declare.
	* i386-protos.h (init_cumulative_args): Update prototype.
	* i386.c (init_cumulative_args): Use register passing convention for
	local functions.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 cgraph.c
*** cgraph.c	19 Feb 2003 10:24:54 -0000	1.3
--- cgraph.c	20 Feb 2003 09:49:24 -0000
*************** struct cgraph_node
*** 62,67 ****
--- 62,68 ----
    bool lowered;
    /* Set when function is scheduled to be assembled.  */
    bool output;
+   bool local;
  };
  
  struct cgraph_edge
*************** static void cgraph_expand_functions PARA
*** 93,98 ****
--- 94,100 ----
  static void cgraph_mark_functions_to_output PARAMS ((void));
  static void cgraph_expand_function PARAMS ((struct cgraph_node *));
  static void cgraph_mark_needed_node PARAMS ((struct cgraph_node *, int));
+ static void cgraph_mark_local_functions PARAMS ((void));
  
  /* Returns a hash code for P.  */
  
*************** cgraph_expand_functions ()
*** 542,547 ****
--- 543,587 ----
    free (order);
  }
  
+ /* Return true when the function is local -- it's address is never taken
+    and is not visible outside current compilation unit so the calling
+    conventions can be modified.  */
+ bool
+ cgraph_local_function_p (decl)
+ 	tree decl;
+ {
+   if (!flag_unit_at_a_time)
+     return false;
+   else
+     {
+       struct cgraph_node *node = cgraph_node (decl);
+       return node->local;
+     }
+ }
+ 
+ /* Mark all local functions.
+    We can not use node->needed directly as it is modified during
+    execution of cgraph_optimize.  */
+ 
+ static void
+ cgraph_mark_local_functions ()
+ {
+   struct cgraph_node *node;
+ 
+   if (!quiet_flag)
+     fprintf (stderr, "\n\nMarking local functions:");
+ 
+   /* Figure out functions we want to assemble.  */
+   for (node = cgraph_nodes; node; node = node->next)
+     {
+       node->local = (!node->needed
+ 		     && DECL_SAVED_TREE (node->decl)
+ 		     && !TREE_PUBLIC (node->decl));
+       if (node->local)
+ 	announce_function (node->decl);
+     }
+ }
+ 
  /* Perform simple optimizations based on callgraph.  */
  
  void
*************** cgraph_optimize ()
*** 551,556 ****
--- 591,598 ----
    bool changed = true;
    struct cgraph_edge *edge;
  
+   cgraph_mark_local_functions ();
+ 
    if (!quiet_flag)
      fprintf (stderr, "\n\nAssembling functions:");
  
*************** cgraph_optimize ()
*** 560,565 ****
--- 602,609 ----
       Later we should move all inlining decisions to callgraph code to make
       this impossible.  */
    cgraph_expand_functions ();
+   if (!quiet_flag)
+     fprintf (stderr, "\n\nAssembling functions that failed to inline:");
    while (changed)
      {
        changed = false;
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.381
diff -c -3 -p -r1.381 tree.h
*** tree.h	12 Feb 2003 21:48:58 -0000	1.381
--- tree.h	20 Feb 2003 09:49:26 -0000
*************** void dump_cgraph			PARAMS ((FILE *));
*** 3172,3177 ****
--- 3172,3178 ----
  void cgraph_optimize			PARAMS ((void));
  void cgraph_remove_call			PARAMS ((tree, tree));
  bool cgraph_calls_p			PARAMS ((tree, tree));
+ bool cgraph_local_function_p		PARAMS ((tree));
  
  
  /* Redefine abort to report an internal error w/o coredump, and
Index: config/i386/i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.94
diff -c -3 -p -r1.94 i386-protos.h
*** config/i386/i386-protos.h	16 Feb 2003 01:35:35 -0000	1.94
--- config/i386/i386-protos.h	20 Feb 2003 09:49:27 -0000
*************** extern void x86_emit_floatuns PARAMS ((r
*** 194,200 ****
  
  
  #ifdef TREE_CODE
! extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
  extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
  extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
  						   enum machine_mode,
--- 194,200 ----
  
  
  #ifdef TREE_CODE
! extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, tree));
  extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
  extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
  						   enum machine_mode,
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.537
diff -c -3 -p -r1.537 i386.c
*** config/i386/i386.c	16 Feb 2003 01:35:32 -0000	1.537
--- config/i386/i386.c	20 Feb 2003 09:49:28 -0000
*************** ix86_function_arg_regno_p (regno)
*** 1771,1783 ****
     For a library call, FNTYPE is 0.  */
  
  void
! init_cumulative_args (cum, fntype, libname)
       CUMULATIVE_ARGS *cum;	/* Argument info to initialize */
       tree fntype;		/* tree ptr for function decl */
       rtx libname;		/* SYMBOL_REF of library name or 0 */
  {
    static CUMULATIVE_ARGS zero_cum;
    tree param, next_param;
  
    if (TARGET_DEBUG_ARG)
      {
--- 1771,1785 ----
     For a library call, FNTYPE is 0.  */
  
  void
! init_cumulative_args (cum, fntype, libname, fndecl)
       CUMULATIVE_ARGS *cum;	/* Argument info to initialize */
       tree fntype;		/* tree ptr for function decl */
       rtx libname;		/* SYMBOL_REF of library name or 0 */
+      tree fndecl;
  {
    static CUMULATIVE_ARGS zero_cum;
    tree param, next_param;
+   bool user_convention = false;
  
    if (TARGET_DEBUG_ARG)
      {
*************** init_cumulative_args (cum, fntype, libna
*** 1803,1809 ****
        tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
  
        if (attr)
! 	cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
      }
    cum->maybe_vaarg = false;
  
--- 1805,1814 ----
        tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
  
        if (attr)
! 	{
! 	  cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
! 	  user_convention = true;
! 	}
      }
    cum->maybe_vaarg = false;
  
*************** init_cumulative_args (cum, fntype, libna
*** 1814,1820 ****
--- 1819,1838 ----
  	{
  	  cum->nregs = 2;
  	  cum->fastcall = 1;
+ 	  user_convention = true;
  	}
+     }
+ 
+   /* Use register calling convention for local functions when possible.  */
+   if (!TARGET_64BIT && !user_convention && fndecl
+       && cgraph_local_function_p (fndecl))
+     {
+       /* We can't use regparm(3) for nested functions as these use
+          static chain pointer in third argument.  */
+       if (DECL_CONTEXT (fndecl) && !DECL_NO_STATIC_CHAIN (fndecl))
+ 	cum->nregs = 2;
+       else
+ 	cum->nregs = 3;
      }
  
  
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.322
diff -c -3 -p -r1.322 i386.h
*** config/i386/i386.h	9 Feb 2003 23:30:51 -0000	1.322
--- config/i386/i386.h	20 Feb 2003 09:49:28 -0000
*************** typedef struct ix86_args {
*** 1740,1747 ****
     for a call to a function whose data type is FNTYPE.
     For a library call, FNTYPE is 0.  */
  
! #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
!   init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME))
  
  /* Update the data in CUM to advance over an argument
     of mode MODE and data type TYPE.
--- 1740,1747 ----
     for a call to a function whose data type is FNTYPE.
     For a library call, FNTYPE is 0.  */
  
! #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL) \
!   init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
  
  /* Update the data in CUM to advance over an argument
     of mode MODE and data type TYPE.



More information about the Gcc-patches mailing list