This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

unit at time and local function II


Hi,
this version bootstraps with all frontends now.
Note that I was not able to use TREE_ADDRESSABLE as you suggested
because multiple versions of the same DECL_NODE exists and additionally
it does not seem to be set for function declarations refered from local
initializers.

OK for mainline?
/* { 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 at suse dot cz>
	* cgraph.h  (cgraph_node):  Add field "local".
	(cgraph_local_function_p): Declare.
	* cgraph.c (cgraph_local_function_p): New global function.
	* cgraphunit.c (cgraph_mark_local_functions): New local 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.4
diff -c -3 -p -r1.4 cgraph.c
*** cgraph.c	22 Feb 2003 10:02:29 -0000	1.4
--- cgraph.c	22 Feb 2003 12:40:59 -0000
*************** dump_cgraph (f)
*** 210,212 ****
--- 210,229 ----
        fprintf (f, "\n");
      }
  }
+ 
+ /* 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;
+     }
+ }
+ 
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 cgraph.h
*** cgraph.h	22 Feb 2003 10:02:29 -0000	1.1
--- cgraph.h	22 Feb 2003 12:40:59 -0000
*************** struct cgraph_node
*** 51,56 ****
--- 51,57 ----
    bool lowered;
    /* Set when function is scheduled to be assembled.  */
    bool output;
+   bool local;
  };
  
  struct cgraph_edge
*************** void cgraph_remove_call			PARAMS ((tree,
*** 69,74 ****
--- 70,76 ----
  struct cgraph_edge *cgraph_record_call	PARAMS ((tree, tree));
  struct cgraph_node *cgraph_node		PARAMS ((tree decl));
  bool cgraph_calls_p			PARAMS ((tree, tree));
+ bool cgraph_local_function_p		PARAMS ((tree));
  
  /* In cgraphunit.c  */
  void cgraph_finalize_function		PARAMS ((tree, tree));
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 cgraphunit.c
*** cgraphunit.c	22 Feb 2003 10:02:29 -0000	1.1
--- cgraphunit.c	22 Feb 2003 12:40:59 -0000
*************** static void cgraph_expand_functions PARA
*** 38,43 ****
--- 38,44 ----
  static void cgraph_mark_functions_to_output PARAMS ((void));
  static void cgraph_expand_function PARAMS ((struct cgraph_node *));
  static tree record_call_1 PARAMS ((tree *, int *, void *));
+ static void cgraph_mark_local_functions PARAMS ((void));
  
  /* Analyze function once it is parsed.  Set up the local information
     available - create cgraph edges for function calles via BODY.  */
*************** cgraph_expand_functions ()
*** 325,330 ****
--- 326,355 ----
    free (order);
  }
  
+ /* 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 ()
*** 334,339 ****
--- 359,366 ----
    bool changed = true;
    struct cgraph_edge *edge;
  
+   cgraph_mark_local_functions ();
+ 
    if (!quiet_flag)
      fprintf (stderr, "\n\nAssembling functions:");
  
*************** cgraph_optimize ()
*** 343,348 ****
--- 370,377 ----
       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: 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	22 Feb 2003 12:41:00 -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.539
diff -c -3 -p -r1.539 i386.c
*** config/i386/i386.c	22 Feb 2003 02:09:05 -0000	1.539
--- config/i386/i386.c	22 Feb 2003 12:41:01 -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)
      {
--- 1759,1773 ----
     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;
  
--- 1793,1802 ----
        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 ****
--- 1807,1826 ----
  	{
  	  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.324
diff -c -3 -p -r1.324 i386.h
*** config/i386/i386.h	22 Feb 2003 02:09:05 -0000	1.324
--- config/i386/i386.h	22 Feb 2003 12:41:02 -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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]