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