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
This commit is contained in:
Richard Henderson 2002-12-20 11:42:41 -08:00 committed by Richard Henderson
parent 913746e328
commit 3094247fd2
6 changed files with 163 additions and 63 deletions

View File

@ -1,3 +1,24 @@
2002-12-20 Richard Henderson <rth@redhat.com>
* 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 <ian@sibyl.beware.dropbear.id.au>
* config/ns32k/ns32k.md (movdi): Use "l" instead of "f" to match

View File

@ -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));

View File

@ -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)

View File

@ -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}}, \

View File

@ -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")])

View File

@ -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