From 3094247fd2404373d9bd706ede23ecef45d60b84 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 20 Dec 2002 11:42:41 -0800 Subject: [PATCH] alpha.c (decl_has_samegp): New. * config/alpha/alpha.c (decl_has_samegp): New. (samegp_function_operand): Use it. Rename from current_file_function_operand. (direct_call_operand): Handle -msmall-text via symbol->jump. (tls_symbolic_operand_1): Use T for tprel64, t for smaller tprel. (tls_symbolic_operand_type): Likewise. (alpha_encode_section_info): Likewise. Handle -msmall-text. (alpha_function_ok_for_sibcall): Use decl_has_samegp. (alpha_end_function): Set symbol->jump for functions defined in the text section. * config/alpha/alpha-protos.h: Update. * config/alpha/alpha.h (MASK_SMALL_TEXT, TARGET_SMALL_TEXT): New. (TARGET_SWITCHES): Add -msmall-text and -mlarge-text. (PREDICATE_CODES): Update. * config/alpha/alpha.md (call patterns): Update for samegp_function_operand rename; use !samegp reloc if TARGET_EXPLICIT_RELOCS. * doc/invoke.text: Document -msmall-text and -mlarge-text. From-SVN: r60373 --- gcc/ChangeLog | 21 ++++ gcc/config/alpha/alpha-protos.h | 2 +- gcc/config/alpha/alpha.c | 163 ++++++++++++++++++++++---------- gcc/config/alpha/alpha.h | 9 +- gcc/config/alpha/alpha.md | 16 ++-- gcc/doc/invoke.texi | 15 ++- 6 files changed, 163 insertions(+), 63 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 03ec274bb7e..19fee5850f1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2002-12-20 Richard Henderson + + * config/alpha/alpha.c (decl_has_samegp): New. + (samegp_function_operand): Use it. Rename from + current_file_function_operand. + (direct_call_operand): Handle -msmall-text via symbol->jump. + (tls_symbolic_operand_1): Use T for tprel64, t for smaller tprel. + (tls_symbolic_operand_type): Likewise. + (alpha_encode_section_info): Likewise. Handle -msmall-text. + (alpha_function_ok_for_sibcall): Use decl_has_samegp. + (alpha_end_function): Set symbol->jump for functions defined in + the text section. + * config/alpha/alpha-protos.h: Update. + * config/alpha/alpha.h (MASK_SMALL_TEXT, TARGET_SMALL_TEXT): New. + (TARGET_SWITCHES): Add -msmall-text and -mlarge-text. + (PREDICATE_CODES): Update. + * config/alpha/alpha.md (call patterns): Update for + samegp_function_operand rename; use !samegp reloc if + TARGET_EXPLICIT_RELOCS. + * doc/invoke.text: Document -msmall-text and -mlarge-text. + 2002-12-20 Ian Dall * config/ns32k/ns32k.md (movdi): Use "l" instead of "f" to match diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 71079eff7e8..e19f7cb10ee 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -54,7 +54,7 @@ extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode)); extern int some_operand PARAMS ((rtx, enum machine_mode)); extern int some_ni_operand PARAMS ((rtx, enum machine_mode)); extern int input_operand PARAMS ((rtx, enum machine_mode)); -extern int current_file_function_operand PARAMS ((rtx, enum machine_mode)); +extern int samegp_function_operand PARAMS ((rtx, enum machine_mode)); extern int direct_call_operand PARAMS ((rtx, enum machine_mode)); extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode)); extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode)); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index eeab8057204..e28f3195b3d 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -128,6 +128,8 @@ static enum tls_model tls_symbolic_operand_type PARAMS ((rtx)); static bool decl_in_text_section PARAMS ((tree)); +static bool decl_has_samegp + PARAMS ((tree)); static bool alpha_in_small_data_p PARAMS ((tree)); static void alpha_encode_section_info @@ -971,7 +973,7 @@ input_operand (op, mode) file, and in the same section as the current function. */ int -current_file_function_operand (op, mode) +samegp_function_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; { @@ -982,14 +984,9 @@ current_file_function_operand (op, mode) if (op == XEXP (DECL_RTL (current_function_decl), 0)) return 1; - /* Otherwise, we need the DECL for the SYMBOL_REF, which we can't get. - So SYMBOL_REF_FLAG has been declared to imply that the function is - in the default text section. So we must also check that the current - function is also in the text section. */ - if (SYMBOL_REF_FLAG (op) && decl_in_text_section (current_function_decl)) - return 1; - - return 0; + /* Otherwise, encode_section_info recorded whether we are to treat + this symbol as having the same GP. */ + return SYMBOL_REF_FLAG (op); } /* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */ @@ -999,20 +996,28 @@ direct_call_operand (op, mode) rtx op; enum machine_mode mode; { - /* Must be defined in this file. */ - if (! current_file_function_operand (op, mode)) + /* Must share the same GP. */ + if (!samegp_function_operand (op, mode)) return 0; /* If profiling is implemented via linker tricks, we can't jump - to the nogp alternate entry point. */ + to the nogp alternate entry point. Note that current_function_profile + would not be correct, since that doesn't indicate if the target + function uses profiling. */ /* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test, but is approximately correct for the OSF ABIs. Don't know what to do for VMS, NT, or UMK. */ - if (! TARGET_PROFILING_NEEDS_GP - && ! current_function_profile) + if (!TARGET_PROFILING_NEEDS_GP && profile_flag) return 0; - return 1; + /* Must be "near" so that the branch is assumed to reach. With + -msmall-text, this is true of all local symbols. */ + if (TARGET_SMALL_TEXT) + return op->jump; + + /* Otherwise, a decl is "near" if it is defined in the same section. + See alpha_encode_section_info for commentary. */ + return op->jump && decl_in_text_section (cfun->decl); } /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing @@ -1182,7 +1187,6 @@ tls_symbolic_operand_1 (op, mode, size, unspec) int size, unspec; { const char *str; - int letter; if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op)) return 0; @@ -1212,9 +1216,17 @@ tls_symbolic_operand_1 (op, mode, size, unspec) else return 0; - letter = (unspec == UNSPEC_DTPREL ? 'D' : 'T'); - - return str[1] == letter; + switch (str[1]) + { + case 'D': + return unspec == UNSPEC_DTPREL; + case 'T': + return unspec == UNSPEC_TPREL && size == 64; + case 't': + return unspec == UNSPEC_TPREL && size < 64; + default: + abort (); + } } /* Return true if OP is valid for 16-bit DTP relative relocations. */ @@ -1784,14 +1796,9 @@ tls_symbolic_operand_type (symbol) return TLS_MODEL_GLOBAL_DYNAMIC; } if (str[1] == 'T') - { - /* 64-bit local exec is the same as initial exec except without - the dynamic relocation. In either case we use a got entry. */ - if (alpha_tls_size == 64) - return TLS_MODEL_INITIAL_EXEC; - else - return TLS_MODEL_LOCAL_EXEC; - } + return TLS_MODEL_INITIAL_EXEC; + if (str[1] == 't') + return TLS_MODEL_LOCAL_EXEC; } return 0; @@ -1814,6 +1821,29 @@ decl_in_text_section (decl) && DECL_ONE_ONLY (decl)))); } +/* Return true if the function DECL will share the same GP as any + function in the current unit of translation. */ + +static bool +decl_has_samegp (decl) + tree decl; +{ + /* Functions that are not local can be overridden, and thus may + not share the same gp. */ + if (!(*targetm.binds_local_p) (decl)) + return false; + + /* If -msmall-data is in effect, assume that there is only one GP + for the module, and so any local symbol has this property. We + need explicit relocations to be able to enforce this for symbols + not defined in this unit of translation, however. */ + if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA) + return true; + + /* Functions that are not external are defined in this UoT. */ + return !DECL_EXTERNAL (decl); +} + /* Return true if EXP should be placed in the small data section. */ static bool @@ -1870,20 +1900,38 @@ alpha_encode_section_info (decl, first) symbol = XEXP (rtl, 0); if (GET_CODE (symbol) != SYMBOL_REF) return; + + /* A variable is considered "local" if it is defined in this module. */ + is_local = (*targetm.binds_local_p) (decl); if (TREE_CODE (decl) == FUNCTION_DECL) { - /* We mark public functions once they are emitted; otherwise we - don't know that they exist in this unit of translation. */ - if (TREE_PUBLIC (decl)) - return; + /* Mark whether the decl is "near" in distance. If -msmall-text is + in effect, this is trivially true of all local symbols. */ + if (TARGET_SMALL_TEXT) + { + if (is_local) + symbol->jump = 1; + } + else + { + /* Otherwise, a decl is "near" if it is defined in this same + section. What we really need is to be able to access the + target decl of a call from the call_insn pattern, so that + we can determine if the call is from the same section. We + can't do that at present, so handle the common case and + match up .text with .text. - /* Do not mark functions that are not in .text; otherwise we - don't know that they are near enough for a direct branch. */ - if (! decl_in_text_section (decl)) - return; + Delay marking public functions until they are emitted; otherwise + we don't know that they exist in this unit of translation. */ + if (!TREE_PUBLIC (decl) && decl_in_text_section (decl)) + symbol->jump = 1; + } - SYMBOL_REF_FLAG (symbol) = 1; + /* Indicate whether the target function shares the same GP as any + function emitted in this unit of translation. */ + if (decl_has_samegp (decl)) + SYMBOL_REF_FLAG (symbol) = 1; return; } @@ -1893,9 +1941,6 @@ alpha_encode_section_info (decl, first) symbol_str = XSTR (symbol, 0); - /* A variable is considered "local" if it is defined in this module. */ - is_local = (*targetm.binds_local_p) (decl); - /* Care for TLS variables. */ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl)) { @@ -1908,9 +1953,11 @@ alpha_encode_section_info (decl, first) encoding = 'D'; break; case TLS_MODEL_INITIAL_EXEC: - case TLS_MODEL_LOCAL_EXEC: encoding = 'T'; break; + case TLS_MODEL_LOCAL_EXEC: + encoding = (alpha_tls_size == 64 ? 'T' : 't'); + break; } } else if (is_local) @@ -2282,16 +2329,22 @@ alpha_legitimize_address (x, scratch, mode) } /* We do not allow indirect calls to be optimized into sibling calls, nor - can we allow a call to a function in a different compilation unit to - be optimized into a sibcall. */ + can we allow a call to a function with a different GP to be optimized + into a sibcall. */ + static bool alpha_function_ok_for_sibcall (decl, exp) tree decl; tree exp ATTRIBUTE_UNUSED; { - return (decl - && (! TREE_PUBLIC (decl) - || (TREE_ASM_WRITTEN (decl) && (*targetm.binds_local_p) (decl)))); + /* Can't do indirect tail calls, since we don't know if the target + uses the same GP. */ + if (!decl) + return false; + + /* Otherwise, we can make a tail call if the target function shares + the same GP. */ + return decl_has_samegp (decl); } /* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a @@ -7853,15 +7906,21 @@ alpha_end_function (file, fnname, decl) #endif /* Show that we know this function if it is called again. + This is only meaningful for symbols that bind locally. */ + if ((*targetm.binds_local_p) (decl)) + { + rtx symbol = XEXP (DECL_RTL (decl), 0); - Do this only for functions whose symbols bind locally. + /* Mark whether the decl is "near". See the commentary in + alpha_encode_section_info wrt the .text section. */ + if (decl_in_text_section (decl)) + symbol->jump = 1; - Don't do this for functions not defined in the .text section, as - otherwise it's not unlikely that the destination is out of range - for a direct branch. */ - - if ((*targetm.binds_local_p) (decl) && decl_in_text_section (decl)) - SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1; + /* Mark whether the decl shares a GP with other functions + in this unit of translation. This is trivially true of + local symbols. */ + SYMBOL_REF_FLAG (symbol) = 1; + } /* Output jump tables and the static subroutine information block. */ if (TARGET_ABI_UNICOSMK) diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index 026c62a0bed..2873d157eff 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -222,6 +222,10 @@ extern int alpha_tls_size; #define MASK_TLS_KERNEL (1 << 14) #define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL) +/* This means use direct branches to local functions. */ +#define MASK_SMALL_TEXT (1 << 15) +#define TARGET_SMALL_TEXT (target_flags & MASK_SMALL_TEXT) + /* This means that the processor is an EV5, EV56, or PCA56. Unlike alpha_cpu this is not affected by -mtune= setting. */ #define MASK_CPU_EV5 (1 << 28) @@ -310,6 +314,9 @@ extern int alpha_tls_size; N_("Emit 16-bit relocations to the small data areas")}, \ {"large-data", -MASK_SMALL_DATA, \ N_("Emit 32-bit relocations to the small data areas")}, \ + {"small-text", MASK_SMALL_TEXT, \ + N_("Emit direct branches to local functions")}, \ + {"large-text", -MASK_SMALL_TEXT, ""}, \ {"tls-kernel", MASK_TLS_KERNEL, \ N_("Emit rdval instead of rduniq for thread pointer")}, \ {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \ @@ -1914,7 +1921,7 @@ do { \ {"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \ {"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \ {"const0_operand", {CONST_INT, CONST_DOUBLE, CONST_VECTOR}}, \ - {"current_file_function_operand", {SYMBOL_REF}}, \ + {"samegp_function_operand", {SYMBOL_REF}}, \ {"direct_call_operand", {SYMBOL_REF}}, \ {"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ {"small_symbolic_operand", {SYMBOL_REF, CONST}}, \ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 062e05e5c42..523b1d2b3eb 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -4567,7 +4567,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* - bsr $26,$%0..ng + bsr $26,%0\t\t!samegp ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) @@ -4580,7 +4580,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[0], Pmode) + && ! samegp_function_operand (operands[0], Pmode) && peep2_regno_dead_p (1, 29)" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) @@ -4610,7 +4610,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[0], Pmode) + && ! samegp_function_operand (operands[0], Pmode) && ! peep2_regno_dead_p (1, 29)" [(parallel [(call (mem:DI (match_dup 2)) (match_dup 1)) @@ -4688,7 +4688,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ - br $31,$%0..ng + br $31,%0\t\t!samegp ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#" [(set_attr "type" "jsr") (set_attr "length" "*,8")]) @@ -7779,7 +7779,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%* - bsr $26,$%1..ng + bsr $26,%1\t\t!samegp ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*" [(set_attr "type" "jsr") (set_attr "length" "12,*,16")]) @@ -7793,7 +7793,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[1], Pmode) + && ! samegp_function_operand (operands[1], Pmode) && peep2_regno_dead_p (1, 29)" [(parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) @@ -7825,7 +7825,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (use (reg:DI 29)) (clobber (reg:DI 26))])] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed - && ! current_file_function_operand (operands[1], Pmode) + && ! samegp_function_operand (operands[1], Pmode) && ! peep2_regno_dead_p (1, 29)" [(parallel [(set (match_dup 0) (call (mem:DI (match_dup 3)) @@ -7970,7 +7970,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none" (unspec [(reg:DI 29)] UNSPEC_SIBCALL)] "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF" "@ - br $31,$%1..ng + br $31,%1\t\t!samegp ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#" [(set_attr "type" "jsr") (set_attr "length" "*,8")]) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7e5494451ce..8b602358b18 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -559,7 +559,7 @@ in the following sections. -mcpu=@var{cpu-type} -mtune=@var{cpu-type} @gol -mbwx -mmax -mfix -mcix @gol -mfloat-vax -mfloat-ieee @gol --mexplicit-relocs -msmall-data -mlarge-data @gol +-mexplicit-relocs -msmall-data -mlarge-data -msmall-text -mlarge-text @gol -mmemory-latency=@var{time}} @emph{DEC Alpha/VMS Options} @@ -8749,6 +8749,19 @@ heap instead of in the program's data segment. When generating code for shared libraries, @option{-fpic} implies @option{-msmall-data} and @option{-fPIC} implies @option{-mlarge-data}. +@item -msmall-text +@itemx -mlarge-text +@opindex msmall-text +@opindex mlarge-text +When @option{-msmall-text} is used, the compiler assumes that the +code of the entire program (or shared library) fits in 4MB, and is +thus reachable with a branch instruction. When @option{-msmall-data} +is used, the compiler can assume that all local symbols share the +same @code{$gp} value, and thus reduce the number of instructions +required for a function call from 4 to 1. + +The default is @option{-mlarge-text}. + @item -mcpu=@var{cpu_type} @opindex mcpu Set the instruction set and instruction scheduling parameters for