From mboxrd@z Thu Jan 1 00:00:00 1970 From: John Carr To: egcs@cygnus.com Subject: egcs compile time optimization Date: Thu, 04 Dec 1997 17:29:00 -0000 Message-id: <199712050128.UAA01626@jfc.> X-SW-Source: 1997-12/msg00281.html This patch improves compilation speed by removing a level of indirection from common rtl references and merging the common rtl into one data structure. Sat Sep 20 17:14:23 1997 John F. Carr * rtl.h (global_rtl): New variable, replacing separate variables for commonly used rtl. (const_int_rtx): Now array of rtx_def, not rtx. * emit-rtl.c: Update for new rtl data structures. * genattrtab.c: Define global_rtl. *** rtl.h.orig Thu Aug 28 09:08:51 1997 --- rtl.h Sat Sep 20 17:12:33 1997 *************** *** 830,841 **** extern rtx replace_regs PROTO((rtx, rtx *, int, int)); /* Standard pieces of rtx, to be substituted directly into things. */ ! extern rtx pc_rtx; ! extern rtx cc0_rtx; ! extern rtx const0_rtx; ! extern rtx const1_rtx; ! extern rtx const2_rtx; ! extern rtx constm1_rtx; extern rtx const_true_rtx; extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; --- 830,845 ---- extern rtx replace_regs PROTO((rtx, rtx *, int, int)); /* Standard pieces of rtx, to be substituted directly into things. */ ! #define pc_rtx (&global_rtl.pc_val) ! #define cc0_rtx (&global_rtl.cc0_val) ! ! #define MAX_SAVED_CONST_INT 64 ! extern struct rtx_def const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; ! ! #define const0_rtx (&const_int_rtx[MAX_SAVED_CONST_INT]) ! #define const1_rtx (&const_int_rtx[MAX_SAVED_CONST_INT+1]) ! #define const2_rtx (&const_int_rtx[MAX_SAVED_CONST_INT+2]) ! #define constm1_rtx (&const_int_rtx[MAX_SAVED_CONST_INT-1]) extern rtx const_true_rtx; extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; *************** *** 850,862 **** #define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)]) #define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)]) /* All references to certain hard regs, except those created by allocating pseudo regs into them (when that's possible), go through these unique rtx objects. */ ! extern rtx stack_pointer_rtx; ! extern rtx frame_pointer_rtx; ! extern rtx hard_frame_pointer_rtx; ! extern rtx arg_pointer_rtx; extern rtx pic_offset_table_rtx; extern rtx struct_value_rtx; extern rtx struct_value_incoming_rtx; --- 854,877 ---- #define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)]) #define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)]) + extern struct _global_rtl + { + struct rtx_def pc_val, cc0_val; + struct rtx_def stack_pointer_val, frame_pointer_val; + struct rtx_def hard_frame_pointer_val; + struct rtx_def arg_pointer_val; + struct rtx_def virtual_incoming_args_val; + struct rtx_def virtual_stack_vars_val; + struct rtx_def virtual_stack_dynamic_val; + struct rtx_def virtual_outgoing_args_val; + } global_rtl; + /* All references to certain hard regs, except those created by allocating pseudo regs into them (when that's possible), go through these unique rtx objects. */ ! #define stack_pointer_rtx (&global_rtl.stack_pointer_val) ! #define frame_pointer_rtx (&global_rtl.frame_pointer_val) ! extern rtx pic_offset_table_rtx; extern rtx struct_value_rtx; extern rtx struct_value_incoming_rtx; *************** *** 873,878 **** --- 888,912 ---- #define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM #endif + /* For register elimination to work properly these hard_frame_pointer_rtx, + frame_pointer_rtx, and arg_pointer_rtx must be the same if they refer to + the same register. */ + #if HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM + #define hard_frame_pointer_rtx (&global_rtl.frame_pointer_val) + #else + #define hard_frame_pointer_rtx (&global_rtl.hard_frame_pointer_val) + #endif + + #if FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM + #define arg_pointer_rtx (&global_rtl.frame_pointer_val) + #else + #if HARD_POINTER_REGNUM == ARG_POINTER_REGNUM + #define arg_pointer_rtx (&global_rtl.hard_frame_pointer_val) + #else + #define arg_pointer_rtx (&global_rtl.arg_pointer_val) + #endif + #endif + /* Virtual registers are used during RTL generation to refer to locations into the stack frame when the actual location isn't known until RTL generation is complete. The routine instantiate_virtual_regs replaces these with *************** *** 885,891 **** either by the caller or by the callee when pretending it was passed by the caller. */ ! extern rtx virtual_incoming_args_rtx; #define VIRTUAL_INCOMING_ARGS_REGNUM (FIRST_VIRTUAL_REGISTER) --- 919,925 ---- either by the caller or by the callee when pretending it was passed by the caller. */ ! #define virtual_incoming_args_rtx (&global_rtl.virtual_incoming_args_val) #define VIRTUAL_INCOMING_ARGS_REGNUM (FIRST_VIRTUAL_REGISTER) *************** *** 893,899 **** variable on the stack. Otherwise, it points to the first variable on the stack. */ ! extern rtx virtual_stack_vars_rtx; #define VIRTUAL_STACK_VARS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 1) --- 927,933 ---- variable on the stack. Otherwise, it points to the first variable on the stack. */ ! #define virtual_stack_vars_rtx (&global_rtl.virtual_stack_vars_val) #define VIRTUAL_STACK_VARS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 1) *************** *** 901,907 **** immediately after the stack pointer has been adjusted by the amount desired. */ ! extern rtx virtual_stack_dynamic_rtx; #define VIRTUAL_STACK_DYNAMIC_REGNUM ((FIRST_VIRTUAL_REGISTER) + 2) --- 935,941 ---- immediately after the stack pointer has been adjusted by the amount desired. */ ! #define virtual_stack_dynamic_rtx (&global_rtl.virtual_stack_dynamic_val) #define VIRTUAL_STACK_DYNAMIC_REGNUM ((FIRST_VIRTUAL_REGISTER) + 2) *************** *** 909,915 **** be written when the stack is pre-pushed (arguments pushed using push insns always use sp). */ ! extern rtx virtual_outgoing_args_rtx; #define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3) --- 943,949 ---- be written when the stack is pre-pushed (arguments pushed using push insns always use sp). */ ! #define virtual_outgoing_args_rtx (&global_rtl.virtual_outgoing_args_val) #define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3) *************** *** 959,966 **** Allocated in parallel with regno_pointer_flag. */ extern rtx *regno_reg_rtx; ! /* Vector indexed by regno; contains the alignment in bytes for a ! register that contains a pointer, if known. */ extern char *regno_pointer_align; #define REGNO_POINTER_ALIGN(REGNO) regno_pointer_align[REGNO] --- 993,1000 ---- Allocated in parallel with regno_pointer_flag. */ extern rtx *regno_reg_rtx; ! /* Vector indexed by regno; contain the alignment in bytes and type ! pointed to for a register that contains a pointer, if known. */ extern char *regno_pointer_align; #define REGNO_POINTER_ALIGN(REGNO) regno_pointer_align[REGNO] *** emit-rtl.c.orig Mon Sep 15 22:07:17 1997 --- emit-rtl.c Sat Sep 20 17:13:04 1997 *************** *** 111,124 **** All of these except perhaps the floating-point CONST_DOUBLEs are unique; no other rtx-object will be equal to any of these. */ ! rtx pc_rtx; /* (PC) */ ! rtx cc0_rtx; /* (CC0) */ ! rtx cc1_rtx; /* (CC1) (not actually used nowadays) */ ! rtx const0_rtx; /* (CONST_INT 0) */ ! rtx const1_rtx; /* (CONST_INT 1) */ ! rtx const2_rtx; /* (CONST_INT 2) */ ! rtx constm1_rtx; /* (CONST_INT -1) */ ! rtx const_true_rtx; /* (CONST_INT STORE_FLAG_VALUE) */ /* We record floating-point CONST_DOUBLEs in each floating-point mode for the values of 0, 1, and 2. For the integer entries and VOIDmode, we --- 111,129 ---- All of these except perhaps the floating-point CONST_DOUBLEs are unique; no other rtx-object will be equal to any of these. */ ! struct _global_rtl global_rtl = ! { ! {PC, VOIDmode}, /* pc_rtx */ ! {CC0, VOIDmode}, /* cc0_rtx */ ! {REG}, /* stack_pointer_rtx */ ! {REG}, /* frame_pointer_rtx */ ! {REG}, /* hard_frame_pointer_rtx */ ! {REG}, /* arg_pointer_rtx */ ! {REG}, /* virtual_incoming_args_rtx */ ! {REG}, /* virtual_stack_vars_rtx */ ! {REG}, /* virtual_stack_dynamic_rtx */ ! {REG}, /* virtual_outgoing_args_rtx */ ! }; /* We record floating-point CONST_DOUBLEs in each floating-point mode for the values of 0, 1, and 2. For the integer entries and VOIDmode, we *************** *** 126,131 **** --- 131,138 ---- rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; + rtx const_true_rtx; + REAL_VALUE_TYPE dconst0; REAL_VALUE_TYPE dconst1; REAL_VALUE_TYPE dconst2; *************** *** 149,158 **** In an inline procedure, the stack and frame pointer rtxs may not be used for anything else. */ - rtx stack_pointer_rtx; /* (REG:Pmode STACK_POINTER_REGNUM) */ - rtx frame_pointer_rtx; /* (REG:Pmode FRAME_POINTER_REGNUM) */ - rtx hard_frame_pointer_rtx; /* (REG:Pmode HARD_FRAME_POINTER_REGNUM) */ - rtx arg_pointer_rtx; /* (REG:Pmode ARG_POINTER_REGNUM) */ rtx struct_value_rtx; /* (REG:Pmode STRUCT_VALUE_REGNUM) */ rtx struct_value_incoming_rtx; /* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */ rtx static_chain_rtx; /* (REG:Pmode STATIC_CHAIN_REGNUM) */ --- 156,161 ---- *************** *** 163,182 **** See for instance the MIPS port. */ rtx return_address_pointer_rtx; /* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */ - rtx virtual_incoming_args_rtx; /* (REG:Pmode VIRTUAL_INCOMING_ARGS_REGNUM) */ - rtx virtual_stack_vars_rtx; /* (REG:Pmode VIRTUAL_STACK_VARS_REGNUM) */ - rtx virtual_stack_dynamic_rtx; /* (REG:Pmode VIRTUAL_STACK_DYNAMIC_REGNUM) */ - rtx virtual_outgoing_args_rtx; /* (REG:Pmode VIRTUAL_OUTGOING_ARGS_REGNUM) */ - /* We make one copy of (const_int C) where C is in [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT] to save space during the compilation and simplify comparisons of integers. */ ! #define MAX_SAVED_CONST_INT 64 - static rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; - /* The ends of the doubly-linked chain of rtl for the current function. Both are reset to null at the start of rtl generation for the function. --- 166,178 ---- See for instance the MIPS port. */ rtx return_address_pointer_rtx; /* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */ /* We make one copy of (const_int C) where C is in [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT] to save space during the compilation and simplify comparisons of integers. */ ! struct rtx_def const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; /* The ends of the doubly-linked chain of rtl for the current function. Both are reset to null at the start of rtl generation for the function. *************** *** 310,319 **** HOST_WIDE_INT arg = va_arg (p, HOST_WIDE_INT); if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT) ! return const_int_rtx[arg + MAX_SAVED_CONST_INT]; if (const_true_rtx && arg == STORE_FLAG_VALUE) return const_true_rtx; rt_val = rtx_alloc (code); INTVAL (rt_val) = arg; --- 306,317 ---- HOST_WIDE_INT arg = va_arg (p, HOST_WIDE_INT); if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT) ! return &const_int_rtx[arg + MAX_SAVED_CONST_INT]; + #if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1 if (const_true_rtx && arg == STORE_FLAG_VALUE) return const_true_rtx; + #endif rt_val = rtx_alloc (code); INTVAL (rt_val) = arg; *************** *** 336,351 **** Also don't do this when we are making new REGs in reload, since we don't want to get confused with the real pointers. */ ! if (frame_pointer_rtx && regno == FRAME_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return frame_pointer_rtx; #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM ! if (hard_frame_pointer_rtx && regno == HARD_FRAME_POINTER_REGNUM ! && mode == Pmode && ! reload_in_progress) return hard_frame_pointer_rtx; #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! if (arg_pointer_rtx && regno == ARG_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return arg_pointer_rtx; #endif --- 334,349 ---- Also don't do this when we are making new REGs in reload, since we don't want to get confused with the real pointers. */ ! if (regno == FRAME_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return frame_pointer_rtx; #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM ! if (regno == HARD_FRAME_POINTER_REGNUM && mode == Pmode ! && ! reload_in_progress) return hard_frame_pointer_rtx; #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM ! if (regno == ARG_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return arg_pointer_rtx; #endif *************** *** 354,360 **** && mode == Pmode && ! reload_in_progress) return return_address_pointer_rtx; #endif ! if (stack_pointer_rtx && regno == STACK_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return stack_pointer_rtx; else --- 352,358 ---- && mode == Pmode && ! reload_in_progress) return return_address_pointer_rtx; #endif ! if (regno == STACK_POINTER_REGNUM && mode == Pmode && ! reload_in_progress) return stack_pointer_rtx; else *************** *** 3344,3370 **** /* Create the unique rtx's for certain rtx codes and operand values. */ - pc_rtx = gen_rtx (PC, VOIDmode); - cc0_rtx = gen_rtx (CC0, VOIDmode); - - /* Don't use gen_rtx here since gen_rtx in this case - tries to use these variables. */ for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++) { ! const_int_rtx[i + MAX_SAVED_CONST_INT] = rtx_alloc (CONST_INT); ! PUT_MODE (const_int_rtx[i + MAX_SAVED_CONST_INT], VOIDmode); ! INTVAL (const_int_rtx[i + MAX_SAVED_CONST_INT]) = i; } ! /* These four calls obtain some of the rtx expressions made above. */ ! const0_rtx = GEN_INT (0); ! const1_rtx = GEN_INT (1); ! const2_rtx = GEN_INT (2); ! constm1_rtx = GEN_INT (-1); - /* This will usually be one of the above constants, but may be a new rtx. */ - const_true_rtx = GEN_INT (STORE_FLAG_VALUE); - dconst0 = REAL_VALUE_ATOF ("0", DFmode); dconst1 = REAL_VALUE_ATOF ("1", DFmode); dconst2 = REAL_VALUE_ATOF ("2", DFmode); --- 3342,3360 ---- /* Create the unique rtx's for certain rtx codes and operand values. */ for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++) { ! PUT_CODE (&const_int_rtx[i + MAX_SAVED_CONST_INT], CONST_INT); ! PUT_MODE (&const_int_rtx[i + MAX_SAVED_CONST_INT], VOIDmode); ! INTVAL (&const_int_rtx[i + MAX_SAVED_CONST_INT]) = i; } ! if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT ! && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT) ! const_true_rtx = &const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT]; ! else ! const_true_rtx = gen_rtx (CONST_INT, VOIDmode, STORE_FLAG_VALUE); dconst0 = REAL_VALUE_ATOF ("0", DFmode); dconst1 = REAL_VALUE_ATOF ("1", DFmode); dconst2 = REAL_VALUE_ATOF ("2", DFmode); *************** *** 3404,3443 **** mode = GET_MODE_WIDER_MODE (mode)) const_tiny_rtx[0][(int) mode] = const0_rtx; - stack_pointer_rtx = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM); - frame_pointer_rtx = gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM); ! if (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM) ! hard_frame_pointer_rtx = frame_pointer_rtx; ! else ! hard_frame_pointer_rtx = gen_rtx (REG, Pmode, HARD_FRAME_POINTER_REGNUM); ! ! if (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) ! arg_pointer_rtx = frame_pointer_rtx; ! else if (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM) ! arg_pointer_rtx = hard_frame_pointer_rtx; ! else if (STACK_POINTER_REGNUM == ARG_POINTER_REGNUM) ! arg_pointer_rtx = stack_pointer_rtx; ! else ! arg_pointer_rtx = gen_rtx (REG, Pmode, ARG_POINTER_REGNUM); #ifdef RETURN_ADDRESS_POINTER_REGNUM return_address_pointer_rtx = gen_rtx (REG, Pmode, RETURN_ADDRESS_POINTER_REGNUM); #endif - /* Create the virtual registers. Do so here since the following objects - might reference them. */ - - virtual_incoming_args_rtx = gen_rtx (REG, Pmode, - VIRTUAL_INCOMING_ARGS_REGNUM); - virtual_stack_vars_rtx = gen_rtx (REG, Pmode, - VIRTUAL_STACK_VARS_REGNUM); - virtual_stack_dynamic_rtx = gen_rtx (REG, Pmode, - VIRTUAL_STACK_DYNAMIC_REGNUM); - virtual_outgoing_args_rtx = gen_rtx (REG, Pmode, - VIRTUAL_OUTGOING_ARGS_REGNUM); - #ifdef STRUCT_VALUE struct_value_rtx = STRUCT_VALUE; #else --- 3394,3427 ---- mode = GET_MODE_WIDER_MODE (mode)) const_tiny_rtx[0][(int) mode] = const0_rtx; ! /* Assign register numbers to the globally defined register rtx. ! This must be done at runtime because the register number field ! is in a union and some compilers can't initialize unions. */ + REGNO (stack_pointer_rtx) = STACK_POINTER_REGNUM; + PUT_MODE (stack_pointer_rtx, Pmode); + REGNO (frame_pointer_rtx) = FRAME_POINTER_REGNUM; + PUT_MODE (frame_pointer_rtx, Pmode); + REGNO (hard_frame_pointer_rtx) = HARD_FRAME_POINTER_REGNUM; + PUT_MODE (hard_frame_pointer_rtx, Pmode); + REGNO (arg_pointer_rtx) = ARG_POINTER_REGNUM; + PUT_MODE (arg_pointer_rtx, Pmode); + + REGNO (virtual_incoming_args_rtx) = VIRTUAL_INCOMING_ARGS_REGNUM; + PUT_MODE (virtual_incoming_args_rtx, Pmode); + REGNO (virtual_stack_vars_rtx) = VIRTUAL_STACK_VARS_REGNUM; + PUT_MODE (virtual_stack_vars_rtx, Pmode); + REGNO (virtual_stack_dynamic_rtx) = VIRTUAL_STACK_DYNAMIC_REGNUM; + PUT_MODE (virtual_stack_dynamic_rtx, Pmode); + REGNO (virtual_outgoing_args_rtx) = VIRTUAL_OUTGOING_ARGS_REGNUM; + PUT_MODE (virtual_outgoing_args_rtx, Pmode); + #ifdef RETURN_ADDRESS_POINTER_REGNUM return_address_pointer_rtx = gen_rtx (REG, Pmode, RETURN_ADDRESS_POINTER_REGNUM); #endif #ifdef STRUCT_VALUE struct_value_rtx = STRUCT_VALUE; #else *** genattrtab.c.egcs Sun Sep 21 20:49:30 1997 --- genattrtab.c Sat Nov 8 17:56:29 1997 *************** *** 358,365 **** /* These are referenced by rtlanal.c and hence need to be defined somewhere. They won't actually be used. */ ! rtx frame_pointer_rtx, hard_frame_pointer_rtx, stack_pointer_rtx; ! rtx arg_pointer_rtx; static rtx attr_rtx PVPROTO((enum rtx_code, ...)); #ifdef HAVE_VPRINTF --- 358,364 ---- /* These are referenced by rtlanal.c and hence need to be defined somewhere. They won't actually be used. */ ! struct _global_rtl global_rtl; static rtx attr_rtx PVPROTO((enum rtx_code, ...)); #ifdef HAVE_VPRINTF *************** *** 483,490 **** codes are made. */ #define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777) - rtx pc_rtx; - /* Add an entry to the hash table for RTL with hash code HASHCODE. */ static void --- 482,487 ---- *************** *** 5575,5585 **** init_rtl (); - /* We don't use this, but it is referenced in rtlanal.c. - Set it up correctly just in case someone tries to use it someday. */ - pc_rtx = rtx_alloc (PC); - PUT_MODE (pc_rtx, VOIDmode); - /* Set up true and false rtx's */ true_rtx = rtx_alloc (CONST_INT); XWINT (true_rtx, 0) = 1; --- 5572,5577 ----