From: ramana Date: Fri, 9 Oct 2015 10:58:06 +0000 (+0000) Subject: [AArch64] Handle literal pools for functions > 1 MiB in size. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6b7a6f44f5064190fe3f02d4cd0a45c97a159dcc;p=thirdparty%2Fgcc.git [AArch64] Handle literal pools for functions > 1 MiB in size. This patch fixes the issue in PR63304 where we have functions that are > 1MiB. The idea is to use adrp / ldr or adrp / add instructions to address the literal pools under the use of a command line option. I would like to turn this on by default on trunk but keep this disabled by default for the release branches in order to get some serious testing for this feature while it bakes on trunk. As a follow-up I would like to try and see if estimate_num_insns or something else can give us a heuristic to turn this on for "large" functions. After all the number of incidences of this are quite low in real life, so may be we should look to restrict this use as much as possible on the grounds that this code generation implies an extra integer register for addressing for every floating point and vector constant and I don't think that's great in code that already may have high register pressure. Tested on aarch64-none-elf with no regressions. A previous version was bootstrapped and regression tested. Applied to trunk. regards Ramana 2015-09-14 Ramana Radhakrishnan PR target/63304 * config/aarch64/aarch64.c (aarch64_expand_mov_immediate): Handle nopcrelative_literal_loads. (aarch64_classify_address): Likewise. (aarch64_constant_pool_reload_icode): Define. (aarch64_secondary_reload): Handle secondary reloads for literal pools. (aarch64_override_options): Handle nopcrelative_literal_loads. (aarch64_classify_symbol): Handle nopcrelative_literal_loads. * config/aarch64/aarch64.md (aarch64_reload_movcp): Define. (aarch64_reload_movcp): Likewise. * config/aarch64/aarch64.opt (mpc-relative-literal-loads): New option. * config/aarch64/predicates.md (aarch64_constant_pool_symref): New predicate. * doc/invoke.texi (mpc-relative-literal-loads): Document. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@228644 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f096c7b4b0a..514bb313b4d8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-10-09 Richard Biener + + PR target/67366 + * gimple-fold.c (optabs-query.h): Include + (gimple_fold_builtin_memory_op): Allow unaligned stores + when movmisalign_optabs are available. + 2015-10-09 Ramana Radhakrishnan PR target/67366 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index ee2a320c1fcb..17a23d65f392 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -63,6 +63,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-eh.h" #include "gimple-match.h" #include "gomp-constants.h" +#include "optabs-query.h" + /* Return true when DECL can be referenced from current unit. FROM_DECL (if non-null) specify constructor of variable DECL was taken from. @@ -709,7 +711,9 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, /* If the destination pointer is not aligned we must be able to emit an unaligned store. */ && (dest_align >= GET_MODE_ALIGNMENT (TYPE_MODE (type)) - || !SLOW_UNALIGNED_ACCESS (TYPE_MODE (type), dest_align))) + || !SLOW_UNALIGNED_ACCESS (TYPE_MODE (type), dest_align) + || (optab_handler (movmisalign_optab, TYPE_MODE (type)) + != CODE_FOR_nothing))) { tree srctype = type; tree desttype = type; @@ -721,7 +725,10 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, srcmem = tem; else if (src_align < GET_MODE_ALIGNMENT (TYPE_MODE (type)) && SLOW_UNALIGNED_ACCESS (TYPE_MODE (type), - src_align)) + src_align) + && (optab_handler (movmisalign_optab, + TYPE_MODE (type)) + == CODE_FOR_nothing)) srcmem = NULL_TREE; if (srcmem) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ce8fab13935..d7eba156ccb5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-10-09 Ramana Radhakrishnan + + PR target/67366 + * lib/target-supports.exp (check_effective_target_non_strict_align): + Adjust for arm*-*-*. + * gcc.target/arm/pr67366.c: New test. + 2015-10-09 Richard Biener PR tree-optimization/67891 diff --git a/gcc/testsuite/gcc.target/arm/pr67366.c b/gcc/testsuite/gcc.target/arm/pr67366.c new file mode 100644 index 000000000000..1e8b6727003c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr67366.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target arm_unaligned } */ +/* { dg-options "-O2" } */ + +typedef unsigned int u32; +u32 +read32 (const void* ptr) +{ + u32 v; + __builtin_memcpy (&v, ptr, sizeof(v)); + return v; +} + +/* { dg-final { scan-assembler "@ unaligned" } } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 9057a27c6b43..4d5b0a3df61e 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -6262,6 +6262,15 @@ proc check_vect_support_and_set_flags { } { # Return 1 if the target does *not* require strict alignment. proc check_effective_target_non_strict_align {} { + + # On ARM, the default is to use STRICT_ALIGNMENT, but there + # are interfaces defined for misaligned access and thus + # depending on the architecture levels unaligned access is + # available. + if [istarget "arm*-*-*"] { + return [check_effective_target_arm_unaligned] + } + return [check_no_compiler_messages non_strict_align assembly { char *y; typedef char __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))) c;