This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
i386 PIC improvement for static functions.
- To: egcs-patches at cygnus dot com
- Subject: i386 PIC improvement for static functions.
- From: john at feith dot com (John Wehle)
- Date: Sat, 20 Jun 1998 18:56:04 -0400
This patch allows the compiler to detect situations which don't require
the pic register to be loaded for static functions. It works by having
expand_expr mark functions whose address has been used. Static functions
which have not been marked by expand_expr don't need to load the pic
register since they are only called by other functions which are in the
same file (and hence share the same global table pointer).
ChangeLog:
Sat Jun 20 16:18:00 EDT 1998 John Wehle (john@feith.com)
* toplev.c (rest_of_compilation): Defer static functions
when optimizing for PIC.
* tree.h (struct tree_common): Add address_load_flag.
(TREE_ADDRESS_LOAD): New macro.
* print-tree.c (print_node): Handle TREE_ADDRESS_LOAD.
* expr.c (expand_expr): Set TREE_ADDRESS_LOAD if it's a function.
* i386.c (need_to_load_pic_register): New function.
(asm_output_function_prefix, ix86_prologue,
ix86_can_use_return_insn_p, ix86_epilogue): Use it.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/toplev.c.ORIGINAL Mon Jun 8 08:43:20 1998
--- gcc/toplev.c Sun Jun 14 20:20:47 1998
***************
*** 3028,3034 ****
compile it by itself, defer decision till end of compilation.
finish_compilation will call rest_of_compilation again
for those functions that need to be output. Also defer those
! functions that we are supposed to defer. We cannot defer
functions containing nested functions since the nested function
data is in our non-saved obstack. We cannot defer nested
functions for the same reason. */
--- 3028,3036 ----
compile it by itself, defer decision till end of compilation.
finish_compilation will call rest_of_compilation again
for those functions that need to be output. Also defer those
! functions that we are supposed to defer. We defer static
! functions when optimizing for PIC so that the function
! prolog can optimize loading the PIC register. We cannot defer
functions containing nested functions since the nested function
data is in our non-saved obstack. We cannot defer nested
functions for the same reason. */
***************
*** 3048,3053 ****
--- 3050,3056 ----
if (! current_function_contains_functions
&& ! decl_function_context (decl)
&& (DECL_DEFER_OUTPUT (decl)
+ || (! TREE_PUBLIC (decl) && optimize && flag_pic)
|| (DECL_INLINE (decl)
&& ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
&& ! flag_keep_inline_functions)
*** gcc/tree.h.ORIGINAL Mon Jun 8 08:43:21 1998
--- gcc/tree.h Thu Jun 18 00:06:26 1998
***************
*** 169,174 ****
--- 169,175 ----
unsigned constant_flag : 1;
unsigned permanent_flag : 1;
unsigned addressable_flag : 1;
+ unsigned address_load_flag : 1;
unsigned volatile_flag : 1;
unsigned readonly_flag : 1;
unsigned unsigned_flag : 1;
***************
*** 188,194 ****
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
! /* There is room for three more flags. */
};
/* The following table lists the uses of each of the above flags and
--- 189,195 ----
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
! /* There is room for two more flags. */
};
/* The following table lists the uses of each of the above flags and
***************
*** 201,206 ****
--- 202,212 ----
VAR_DECL, FUNCTION_DECL, CONSTRUCTOR, LABEL_DECL, ..._TYPE
IDENTIFIER_NODE
+ address_load_flag:
+
+ TREE_ADDRESS_LOAD in
+ FUNCTION_DECL
+
static_flag:
TREE_STATIC in
***************
*** 415,420 ****
--- 421,430 ----
In IDENTIFIER_NODEs, this means that some extern decl for this name
had its address taken. That matters for inline functions. */
#define TREE_ADDRESSABLE(NODE) ((NODE)->common.addressable_flag)
+
+ /* In a FUNCTION_DECL, nonzero means its address has been loaded so
+ assume that it can be called from other modules even if !TREE_PUBLIC. */
+ #define TREE_ADDRESS_LOAD(NODE) ((NODE)->common.address_load_flag)
/* In a VAR_DECL, nonzero means allocate static storage.
In a FUNCTION_DECL, nonzero if function has been defined.
*** gcc/print-tree.c.ORIGINAL Wed Apr 8 10:03:45 1998
--- gcc/print-tree.c Thu Jun 18 01:01:57 1998
***************
*** 293,298 ****
--- 293,300 ----
fputs (" constant", file);
if (TREE_ADDRESSABLE (node))
fputs (" addressable", file);
+ if (TREE_ADDRESS_LOAD (node))
+ fputs (" address_load", file);
if (TREE_THIS_VOLATILE (node))
fputs (" volatile", file);
if (TREE_UNSIGNED (node))
*** gcc/expr.c.ORIGINAL Mon Jun 8 08:43:15 1998
--- gcc/expr.c Thu Jun 18 23:45:45 1998
***************
*** 5140,5145 ****
--- 5140,5151 ----
TREE_USED (exp) = 1;
}
+ /* Mark function address as being loaded. */
+ if (code == FUNCTION_DECL)
+ {
+ TREE_ADDRESS_LOAD (exp) = 1;
+ }
+
/* Show we haven't gotten RTL for this yet. */
temp = 0;
*** gcc/config/i386/i386.c.ORIGINAL Fri Jun 12 22:52:54 1998
--- gcc/config/i386/i386.c Sat Jun 20 01:19:52 1998
***************
*** 1899,1904 ****
--- 1899,1922 ----
static char pic_label_name [256];
static int pic_label_no = 0;
+ /* Indicate if the pic register needs to be loaded. A static function
+ whose address has never been assigned to a variable does not need to
+ load the pic register since it will already have the correct value.
+ Detecting this situation requires that processing the static function
+ be deferred until the end which is only done when optimizing. Assume
+ the worst case when not optimizing. */
+
+ static int
+ need_to_load_pic_register()
+ {
+
+ return flag_pic && (current_function_uses_pic_offset_table
+ || current_function_uses_const_pool)
+ && (TREE_PUBLIC (current_function_decl)
+ || TREE_ADDRESS_LOAD(current_function_decl)
+ || !optimize);
+ }
+
/* This function generates code for -fpic that loads %ebx with
the return address of the caller and then returns. */
***************
*** 1908,1915 ****
char *name;
{
rtx xops[2];
! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
xops[0] = pic_offset_table_rtx;
xops[1] = stack_pointer_rtx;
--- 1926,1932 ----
char *name;
{
rtx xops[2];
! int pic_reg_used = need_to_load_pic_register();
xops[0] = pic_offset_table_rtx;
xops[1] = stack_pointer_rtx;
***************
*** 2037,2044 ****
register int regno;
int limit;
rtx xops[4];
! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
long tsize = get_frame_size ();
rtx insn;
int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
--- 2054,2060 ----
register int regno;
int limit;
rtx xops[4];
! int pic_reg_used = need_to_load_pic_register();
long tsize = get_frame_size ();
rtx insn;
int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
***************
*** 2204,2211 ****
int nregs = 0;
int reglimit = (frame_pointer_needed
? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
#ifdef NON_SAVING_SETJMP
if (NON_SAVING_SETJMP && current_function_calls_setjmp)
--- 2220,2226 ----
int nregs = 0;
int reglimit = (frame_pointer_needed
? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
! int pic_reg_used = need_to_load_pic_register();
#ifdef NON_SAVING_SETJMP
if (NON_SAVING_SETJMP && current_function_calls_setjmp)
***************
*** 2251,2258 ****
register int nregs, limit;
int offset;
rtx xops[3];
! int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
! || current_function_uses_const_pool);
long tsize = get_frame_size ();
/* Compute the number of registers to pop */
--- 2266,2272 ----
register int nregs, limit;
int offset;
rtx xops[3];
! int pic_reg_used = need_to_load_pic_register();
long tsize = get_frame_size ();
/* Compute the number of registers to pop */
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------