From 8cac4d85875ff23588908341fdd69fb4c39a7210 Mon Sep 17 00:00:00 2001 From: Bernd Schmidt Date: Thu, 24 Nov 2016 12:54:56 +0000 Subject: [PATCH] common.opt (flimit-function-alignment): New. gcc/ * common.opt (flimit-function-alignment): New. * doc/invoke.texi (-flimit-function-alignment): Document. * emit-rtl.h (struct rtl_data): Add max_insn_address field. * final.c (shorten_branches): Set it. * varasm.c (assemble_start_function): Limit alignment if requested. gcc/testsuite/ * gcc.target/i386/align-limit.c: New test. From-SVN: r242836 --- gcc/ChangeLog | 9 +++++++++ gcc/common.opt | 3 +++ gcc/doc/invoke.texi | 8 +++++++- gcc/emit-rtl.h | 3 +++ gcc/final.c | 2 +- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/i386/align-limit.c | 9 +++++++++ gcc/varasm.c | 9 +++++++-- 8 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/align-limit.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1676fe100d1..92c2c9e0015 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-11-24 Bernd Schmidt + + * common.opt (flimit-function-alignment): New. + * doc/invoke.texi (-flimit-function-alignment): Document. + * emit-rtl.h (struct rtl_data): Add max_insn_address field. + * final.c (shorten_branches): Set it. + * varasm.c (assemble_start_function): Limit alignment if + requested. + 2016-11-24 Richard Biener PR tree-optimization/71595 diff --git a/gcc/common.opt b/gcc/common.opt index d7ccf3b1a90..b350b07b9d8 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -924,6 +924,9 @@ Align the start of functions. falign-functions= Common RejectNegative Joined UInteger Var(align_functions) +flimit-function-alignment +Common Report Var(flag_limit_function_alignment) Optimization Init(0) + falign-jumps Common Report Var(align_jumps,0) Optimization UInteger Align labels which are only reached by jumping. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 22f539d4407..34c7187e46d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -373,7 +373,7 @@ Objective-C and Objective-C++ Dialects}. -fno-ira-share-spill-slots @gol -fisolate-erroneous-paths-dereference -fisolate-erroneous-paths-attribute @gol -fivopts -fkeep-inline-functions -fkeep-static-functions @gol --fkeep-static-consts -flive-range-shrinkage @gol +-fkeep-static-consts -flimit-function-alignment -flive-range-shrinkage @gol -floop-block -floop-interchange -floop-strip-mine @gol -floop-unroll-and-jam -floop-nest-optimize @gol -floop-parallelize-all -flra-remat -flto -flto-compression-level @gol @@ -8513,6 +8513,12 @@ If @var{n} is not specified or is zero, use a machine-dependent default. Enabled at levels @option{-O2}, @option{-O3}. +@item -flimit-function-alignment +If this option is enabled, the compiler tries to avoid unnecessarily +overaligning functions. It attempts to instruct the assembler to align +by the amount specified by @option{-falign-functions}, but not to +skip more bytes than the size of the function. + @item -falign-labels @itemx -falign-labels=@var{n} @opindex falign-labels diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index 0a242b1234d..a919bf072ab 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -288,6 +288,9 @@ struct GTY(()) rtl_data { to eliminable regs (like the frame pointer) are set if an asm sets them. */ HARD_REG_SET asm_clobbers; + + /* The highest address seen during shorten_branches. */ + int max_insn_address; }; #define return_label (crtl->x_return_label) diff --git a/gcc/final.c b/gcc/final.c index d3a53c3cbe6..91acb01d96b 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1463,7 +1463,7 @@ shorten_branches (rtx_insn *first) if (!increasing) break; } - + crtl->max_insn_address = insn_current_address; free (varying_length); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 300106c19ff..694e59dfd0f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-24 Bernd Schmidt + + * gcc.target/i386/align-limit.c: New test. + 2016-11-24 Richard Biener PR tree-optimization/71595 diff --git a/gcc/testsuite/gcc.target/i386/align-limit.c b/gcc/testsuite/gcc.target/i386/align-limit.c new file mode 100644 index 00000000000..e34baf01f29 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/align-limit.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment" } */ +/* { dg-final { scan-assembler ".p2align 6,,1" } } */ +/* { dg-final { scan-assembler-not ".p2align 6,,63" } } */ + +void +test_func (void) +{ +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 2a20f64d667..54e06acd542 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1791,9 +1791,14 @@ assemble_start_function (tree decl, const char *fnname) && align_functions_log > align && optimize_function_for_speed_p (cfun)) { + int align_log = align_functions_log; + int max_skip = align_functions - 1; + if (flag_limit_function_alignment && crtl->max_insn_address > 0 + && max_skip >= crtl->max_insn_address) + max_skip = crtl->max_insn_address - 1; + #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, - align_functions_log, align_functions - 1); + ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, align_log, max_skip); #else ASM_OUTPUT_ALIGN (asm_out_file, align_functions_log); #endif