From: Alan Modra Date: Thu, 9 Sep 2010 02:30:54 +0000 (+0930) Subject: invoke.text: Reinstate mcmodel=medium. X-Git-Tag: releases/gcc-4.6.0~4527 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5a79bcc454b5792db3471c4deba84630b2c26dd7;p=thirdparty%2Fgcc.git invoke.text: Reinstate mcmodel=medium. * 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. From-SVN: r164045 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05be760ea2dd..b42132227af8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2010-09-09 Alan Modra + + * 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 PR target/45250 diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h index 0e165ea7199a..faf9e2f2a777 100644 --- a/gcc/config/rs6000/linux64.h +++ b/gcc/config/rs6000/linux64.h @@ -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; \ diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 67fa9bab17e7..c6c3dbf7fabe 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 3ce011f2376d..63f1bba738da 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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 }; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 7e15e3fd4b40..b24688b2f0da 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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