alpha.c (decl_has_samegp): New.
authorRichard Henderson <rth@redhat.com>
Fri, 20 Dec 2002 19:42:41 +0000 (11:42 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 20 Dec 2002 19:42:41 +0000 (11:42 -0800)
        * 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
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/doc/invoke.texi

index 03ec274..19fee58 100644 (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
index 71079ef..e19f7cb 100644 (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));
index eeab805..e28f319 100644 (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.
-
-     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)
index 026c62a..2873d15 100644 (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}},                     \
index 062e05e..523b1d2 100644 (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")])
index 7e54944..8b60235 100644 (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