OSDN Git Service

* doc/invoke.text: Reinstate mcmodel=medium.
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Sep 2010 02:30:54 +0000 (02:30 +0000)
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 9 Sep 2010 02:30:54 +0000 (02:30 +0000)
* config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Set
CMODEL_MEDIUM as default.
* config/rs6000/rs6000.h (enum rs6000_cmodel): Add CMODEL_MEDIUM.
* config/rs6000/rs6000.c (rs6000_handle_option): Add mcmodel=medium.
(toc_relative_ok, offsettable_ok_by_alignment): New functions.
(rs6000_emit_move): Reinstate mcmodel=medium optimization.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164045 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/linux64.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/doc/invoke.texi

index 05be760..b421322 100644 (file)
@@ -1,3 +1,13 @@
+2010-09-09  Alan Modra  <amodra@gmail.com>
+
+       * doc/invoke.text: Reinstate mcmodel=medium.
+       * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Set
+       CMODEL_MEDIUM as default.
+       * config/rs6000/rs6000.h (enum rs6000_cmodel): Add CMODEL_MEDIUM.
+       * config/rs6000/rs6000.c (rs6000_handle_option): Add mcmodel=medium.
+       (toc_relative_ok, offsettable_ok_by_alignment): New functions.
+       (rs6000_emit_move): Reinstate mcmodel=medium optimization.
+
 2010-09-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR target/45250
index 0e165ea..faf9e2f 100644 (file)
@@ -134,7 +134,7 @@ extern enum rs6000_cmodel cmodel;
          else                                                  \
            {                                                   \
              if (!rs6000_explicit_options.cmodel)              \
-               SET_CMODEL (CMODEL_LARGE);                      \
+               SET_CMODEL (CMODEL_MEDIUM);                     \
              if (cmodel != CMODEL_SMALL)                       \
                {                                               \
                  TARGET_NO_FP_IN_TOC = 0;                      \
index 67fa9ba..c6c3dbf 100644 (file)
@@ -6992,6 +6992,80 @@ rs6000_eliminate_indexed_memrefs (rtx operands[2])
                               copy_addr_to_reg (XEXP (operands[1], 0)));
 }
 
+/* Return true if OP, a SYMBOL_REF, should be considered local when
+   generating -mcmodel=medium code.  */
+
+static bool
+toc_relative_ok (rtx op)
+{
+  tree decl;
+
+  if (!SYMBOL_REF_LOCAL_P (op))
+    return false;
+
+  /* This is a bit hard to explain.  When building shared libraries,
+     you are supposed to pass -fpic or -fPIC to the compiler.
+     -fpic/-fPIC not only generate position independent code but also
+     generate code that supports ELF shared library global function
+     or variable overriding.  ppc64 is always PIC and at least some of
+     the ELF shared libaray semantics of global variables happen to be
+     supported without -fpic/-fPIC.  So people may not be careful
+     about using -fPIC for shared libs.
+     With -mcmodel=medium this situation changes.  A shared library
+     built without -fpic/-fPIC requires text relocs for global var
+     access (and would fail to load since glibc ld.so doesn't support
+     the required dynamic relocs).  So avoid this potential
+     problem by using -mcmodel=large access for global vars, unless
+     we know we are compiling for an executable.  */
+  if (flag_pie)
+    return true;
+
+  decl = SYMBOL_REF_DECL (op);
+  if (!decl || !DECL_P (decl))
+    return true;
+  if (!TREE_PUBLIC (decl))
+    return true;
+  if (DECL_VISIBILITY (decl) != VISIBILITY_DEFAULT)
+    return true;
+
+  /* If we get here we must have a global var.  See binds_local_p.  */
+  return flag_whole_program;
+}
+
+/* Return true if memory accesses to DECL are known to never straddle
+   a 32k boundary.  */
+
+static bool
+offsettable_ok_by_alignment (tree decl)
+{
+  unsigned HOST_WIDE_INT dsize, dalign;
+
+  /* Presume any compiler generated symbol_ref is suitably aligned.  */
+  if (!decl)
+    return true;
+
+  if (TREE_CODE (decl) != VAR_DECL
+      && TREE_CODE (decl) != PARM_DECL
+      && TREE_CODE (decl) != RESULT_DECL
+      && TREE_CODE (decl) != FIELD_DECL)
+    return true;
+
+  if (!DECL_SIZE_UNIT (decl))
+    return false;
+
+  if (!host_integerp (DECL_SIZE_UNIT (decl), 1))
+    return false;
+
+  dsize = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+  if (dsize <= 1)
+    return true;
+  if (dsize > 32768)
+    return false;
+
+  dalign = DECL_ALIGN_UNIT (decl);
+  return dalign >= dsize;
+}
+
 /* Emit a move from SOURCE to DEST in mode MODE.  */
 void
 rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
@@ -7305,11 +7379,16 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
       /* If this is a SYMBOL_REF that refers to a constant pool entry,
         and we have put it in the TOC, we just need to make a TOC-relative
         reference to it.  */
-      if (TARGET_TOC
-         && GET_CODE (operands[1]) == SYMBOL_REF
-         && constant_pool_expr_p (operands[1])
-         && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
-                                             get_pool_mode (operands[1])))
+      if ((TARGET_TOC
+          && GET_CODE (operands[1]) == SYMBOL_REF
+          && constant_pool_expr_p (operands[1])
+          && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
+                                              get_pool_mode (operands[1])))
+         || (TARGET_CMODEL == CMODEL_MEDIUM
+             && GET_CODE (operands[1]) == SYMBOL_REF
+             && !CONSTANT_POOL_ADDRESS_P (operands[1])
+             && toc_relative_ok (operands[1])
+             && offsettable_ok_by_alignment (SYMBOL_REF_DECL (operands[1]))))
        {
          rtx reg = NULL_RTX;
          if (TARGET_CMODEL != CMODEL_SMALL)
index 3ce011f..63f1bba 100644 (file)
@@ -297,9 +297,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 
 /* Code model for 64-bit linux.
    small: 16-bit toc offsets.
-   large: 32-bit toc offsets.  */
+   medium: 32-bit toc offsets, static data and code within 2G of TOC pointer.
+   large: 32-bit toc offsets, no limit on static data and code.  */
 enum rs6000_cmodel {
   CMODEL_SMALL,
+  CMODEL_MEDIUM,
   CMODEL_LARGE
 };
 
index 7e15e3f..b24688b 100644 (file)
@@ -15213,6 +15213,11 @@ scheduling parameters set by @option{-mtune}.
 Generate PowerPC64 code for the small model: The TOC is limited to
 64k.
 
+@item -mcmodel=medium
+@opindex mcmodel=medium
+Generate PowerPC64 code for the medium model: The TOC and other static
+data may be up to a total of 4G in size.
+
 @item -mcmodel=large
 @opindex mcmodel=large
 Generate PowerPC64 code for the large model: The TOC may be up to 4G