* 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
+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
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));
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
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;
{
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. */
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
int size, unspec;
{
const char *str;
- int letter;
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
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. */
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;
&& 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
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;
}
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))
{
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)
}
/* 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
#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.
-
- 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. */
+ /* 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;
- 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)
#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)
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 \
{"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}}, \
"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")])
(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))
(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))
(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")])
"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")])
(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))
(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))
(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")])
-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}
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