aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Preud'homme <thopre01@gcc.gnu.org>2018-12-19 17:34:18 +0000
committerThomas Preud'homme <thopre01@gcc.gnu.org>2018-12-19 17:34:18 +0000
commit72e3a529238a86235f74f563d13f27b26b2b816b (patch)
tree2470dfe1119acfbbf4d3ce2d93a9fded5cb0f681 /gcc
parentc4686fa91e3f4852f0182df220ced85b6ff0e13c (diff)
downloadgcc-72e3a529238a86235f74f563d13f27b26b2b816b.zip
gcc-72e3a529238a86235f74f563d13f27b26b2b816b.tar.gz
gcc-72e3a529238a86235f74f563d13f27b26b2b816b.tar.bz2
[ARM] Optimize executable size when using softfloat fmul/dmul
Softfloat single precision and double precision floating-point multiplication routines in libgcc share some code with the floating-point division of their corresponding precision. As the code is structured now, this leads to *all* division code being pulled in an executable in softfloat mode even if only multiplication is performed. This patch create some new LIB1ASMFUNCS macros to also build files with just the multiplication and shared code as weak symbols. By putting these earlier in the static library, they can then be picked up when only multiplication is used and they are overriden by the global definition in the existing file containing both multiplication and division code when division is needed. The patch also removes changes made to the FUNC_START and ARM_FUNC_START macros in r218124 since the intent was to put multiplication and division code into their own section in a later patch to achieve the same size optimization. That approach relied on specific section layout to ensure multiplication and division were not too far from the shared bit of code in order to the branches to be within range. Due to lack of guarantee regarding section layout, in particular with all the possibility of linker scripts, this approach was chosen instead. This patch keeps the two testcases that were posted by Tony Wang on the mailing list to implement this approach and adds a new one. 2018-12-19 Thomas Preud'homme <thomas.preudhomme@linaro.org> libgcc/ * /config/arm/lib1funcs.S (FUNC_START): Remove unused sp_section parameter and corresponding code. (ARM_FUNC_START): Likewise in both definitions. Also update footer comment about condition that need to match with gcc/config/arm/elf.h to also include libgcc/config/arm/t-arm. * config/arm/ieee754-df.S (muldf3): Also build it if L_arm_muldf3 is defined. Weakly define it in this case. * config/arm/ieee754-sf.S (mulsf3): Likewise with L_arm_mulsf3. * config/arm/t-elf (LIB1ASMFUNCS): Build _arm_muldf3.o and _arm_mulsf3.o before muldiv versions if targeting Thumb-1 only. Add comment to keep condition in sync with the one in libgcc/config/arm/lib1funcs.S and gcc/config/arm/elf.h. gcc/ * config/arm/elf.h: Update comment about condition that need to match with libgcc/config/arm/lib1funcs.S to also include libgcc/config/arm/t-arm. * doc/sourcebuild.texi (output-exists, output-exists-not): Rename subsubsection these directives are in to "Check for output files". Move scan-symbol to that section and add to it new scan-symbol-not directive. 2018-12-19 Tony Wang <tony.wang@arm.com> Thomas Preud'homme <thomas.preudhomme@linaro.org> gcc/testsuite/ * lib/lto.exp (lto-execute): Define output_file and testname_with_flags to same value as execname. (scan-symbol): Move and rename to ... * lib/gcc-dg.exp (scan-symbol-common): This. Adapt into a helper function returning true or false if a symbol is present. (scan-symbol): New procedure. (scan-symbol-not): Likewise. * gcc.target/arm/size-optimization-ieee-1.c: New testcase. * gcc.target/arm/size-optimization-ieee-2.c: Likewise. * gcc.target/arm/size-optimization-ieee-3.c: Likewise. From-SVN: r267282
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/arm/elf.h2
-rw-r--r--gcc/doc/sourcebuild.texi9
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c33
-rw-r--r--gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c33
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp76
-rw-r--r--gcc/testsuite/lib/lto.exp63
9 files changed, 214 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 365d593..53cdc83 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2018-12-19 Thomas Preud'homme <thomas.preudhomme@linaro.org>
+
+ * config/arm/elf.h: Update comment about condition that need to
+ match with libgcc/config/arm/lib1funcs.S to also include
+ libgcc/config/arm/t-arm.
+ * doc/sourcebuild.texi (output-exists, output-exists-not): Rename
+ subsubsection these directives are in to "Check for output files".
+ Move scan-symbol to that section and add to it new scan-symbol-not
+ directive.
+
2018-12-19 Tom de Vries <tdevries@suse.de>
* config/nvptx/nvptx.c (PTX_CTA_SIZE): Define.
diff --git a/gcc/config/arm/elf.h b/gcc/config/arm/elf.h
index ad3651b..1e00e99 100644
--- a/gcc/config/arm/elf.h
+++ b/gcc/config/arm/elf.h
@@ -137,7 +137,7 @@
/* Horrible hack: We want to prevent some libgcc routines being included
for some multilibs. The condition should match the one in
- libgcc/config/arm/lib1funcs.S. */
+ libgcc/config/arm/lib1funcs.S and libgcc/config/arm/t-elf. */
#if __ARM_ARCH_ISA_ARM || __ARM_ARCH_ISA_THUMB != 1
#undef L_fixdfsi
#undef L_fixunsdfsi
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 46ef388..29c693b 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2668,7 +2668,7 @@ Passes if @var{regex} does not match demangled text in the dump file with
suffix @var{suffix}.
@end table
-@subsubsection Verify that an output files exists or not
+@subsubsection Check for output files
@table @code
@item output-exists [@{ target/xfail @var{selector} @}]
@@ -2676,13 +2676,12 @@ Passes if compiler output file exists.
@item output-exists-not [@{ target/xfail @var{selector} @}]
Passes if compiler output file does not exist.
-@end table
-
-@subsubsection Check for LTO tests
-@table @code
@item scan-symbol @var{regexp} [@{ target/xfail @var{selector} @}]
Passes if the pattern is present in the final executable.
+
+@item scan-symbol-not @var{regexp} [@{ target/xfail @var{selector} @}]
+Passes if the pattern is absent from the final executable.
@end table
@subsubsection Checks for @command{gcov} tests
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d1ebfc7..e199cd0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,17 @@
+2018-12-19 Tony Wang <tony.wang@arm.com>
+ Thomas Preud'homme <thomas.preudhomme@linaro.org>
+
+ * lib/lto.exp (lto-execute): Define output_file and testname_with_flags
+ to same value as execname.
+ (scan-symbol): Move and rename to ...
+ * lib/gcc-dg.exp (scan-symbol-common): This. Adapt into a
+ helper function returning true or false if a symbol is present.
+ (scan-symbol): New procedure.
+ (scan-symbol-not): Likewise.
+ * gcc.target/arm/size-optimization-ieee-1.c: New testcase.
+ * gcc.target/arm/size-optimization-ieee-2.c: Likewise.
+ * gcc.target/arm/size-optimization-ieee-3.c: Likewise.
+
2018-12-19 Segher Boessenkool <segher@kernel.crashing.org>
* g++.dg/asm-qual-3.C: New testcase.
diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c
new file mode 100644
index 0000000..34090f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-1.c
@@ -0,0 +1,33 @@
+/* { dg-do link { target arm_soft_ok } } */
+/* { dg-options "-mfloat-abi=soft" } */
+
+int
+foo (void)
+{
+ volatile float a;
+ volatile float b;
+ volatile float c = a * b;
+ return 0;
+}
+
+int
+bar (void)
+{
+ volatile double a;
+ volatile double b;
+ volatile double c = a * b;
+ return 0;
+}
+
+int
+main (void)
+{
+ foo ();
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-symbol "__aeabi_fmul" } } */
+/* { dg-final { scan-symbol "__aeabi_dmul" } } */
+/* { dg-final { scan-symbol-not "__aeabi_fdiv" } } */
+/* { dg-final { scan-symbol-not "__aeabi_ddiv" } } */
diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c
new file mode 100644
index 0000000..7533789
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-2.c
@@ -0,0 +1,31 @@
+/* { dg-do link { target arm_soft_ok } } */
+/* { dg-options "-mfloat-abi=soft" } */
+
+int
+foo (void)
+{
+ volatile float a;
+ volatile float b;
+ volatile float c = a / b;
+ return 0;
+}
+
+int
+bar (void)
+{
+ volatile double a;
+ volatile double b;
+ volatile double c = a / b;
+ return 0;
+}
+
+int
+main (void)
+{
+ foo ();
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-symbol "__aeabi_fdiv" } } */
+/* { dg-final { scan-symbol "__aeabi_ddiv" } } */
diff --git a/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c
new file mode 100644
index 0000000..63c92b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/size-optimization-ieee-3.c
@@ -0,0 +1,33 @@
+/* { dg-do link { target arm_soft_ok } } */
+/* { dg-options "-mfloat-abi=soft" } */
+
+int
+foo (void)
+{
+ volatile float a;
+ volatile float b;
+ volatile float c = a * b + a / b;
+ return 0;
+}
+
+int
+bar (void)
+{
+ volatile double a;
+ volatile double b;
+ volatile double c = a * b + a / b;
+ return 0;
+}
+
+int
+main (void)
+{
+ foo ();
+ bar ();
+ return 0;
+}
+
+/* { dg-final { scan-symbol "__aeabi_fmul" } } */
+/* { dg-final { scan-symbol "__aeabi_dmul" } } */
+/* { dg-final { scan-symbol "__aeabi_fdiv" } } */
+/* { dg-final { scan-symbol "__aeabi_ddiv" } } */
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 054d884..e47f80d 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -1244,5 +1244,81 @@ proc gdb-exists { args } {
return 0;
}
+# Helper function for scan-symbol and scan-symbol-not. It scans a symbol in
+# the final executable and return 1 if present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 handles expected failures and the like
+proc scan-symbol-common { scan_directive args } {
+ global nm
+ global base_dir
+
+ # Access variable from gcc-dg-test-1 or lto-execute.
+ upvar 3 output_file output_file
+
+ if { [llength $args] >= 2 } {
+ switch [dg-process-target [lindex $args 1]] {
+ "S" { }
+ "N" { return }
+ "F" { setup_xfail "*-*-*" }
+ "P" { }
+ }
+ }
+
+ # Find nm like we find g++ in g++.exp.
+ if ![info exists nm] {
+ set nm [findfile $base_dir/../../../binutils/nm \
+ $base_dir/../../../binutils/nm \
+ [findfile $base_dir/../../nm $base_dir/../../nm \
+ [findfile $base_dir/nm $base_dir/nm \
+ [transform nm]]]]
+ verbose -log "nm is $nm"
+ }
+
+ set output_file "[glob -nocomplain $output_file]"
+ if { $output_file == "" } {
+ fail "$scan_directive $args: output file does not exist"
+ return
+ }
+
+ set fd [open "| $nm $output_file" r]
+ set text [read $fd]
+ close $fd
+
+ if [regexp -- [lindex $args 0] $text] {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+# Utility for scanning a symbol in the final executable, invoked via dg-final.
+# Call pass if pattern is present, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 handles expected failures and the like
+proc scan-symbol { args } {
+ set testcase [testname-for-summary]
+ if { [scan-symbol-common "scan-symbol" $args]} {
+ pass "$testcase scan-symbol $args"
+ } else {
+ fail "$testcase scan-symbol $args"
+ }
+}
+
+# Utility for scanning a symbol in the final executable, invoked via dg-final.
+# Call pass if pattern is absent, otherwise fail.
+#
+# Argument 0 is the regexp to match.
+# Argument 1 handles expected failures and the like
+proc scan-symbol-not { args } {
+ set testcase [testname-for-summary]
+ if { [scan-symbol-common "scan-symbol-not" $args]} {
+ fail "$testcase scan-symbol-not $args"
+ } else {
+ pass "$testcase scan-symbol-not $args"
+ }
+}
+
set additional_prunes ""
set dg_runtest_extra_prunes ""
diff --git a/gcc/testsuite/lib/lto.exp b/gcc/testsuite/lib/lto.exp
index 58a84aa..c2c3569 100644
--- a/gcc/testsuite/lib/lto.exp
+++ b/gcc/testsuite/lib/lto.exp
@@ -712,6 +712,17 @@ proc lto-execute { src1 sid } {
# There's a unique name for each executable we generate.
set execname "${execbase}-${count}1.exe"
+
+ # The LTO tests don't use dg-test, so testname_with_flags and
+ # output_file need to be defined explicitly for each file. scan-symbol
+ # directives rely on both of these to be defined to find the symbol to
+ # scan and for the text to print in the PASS/FAIL since they can also
+ # be called from dg-test. testname_with_flags is also used via
+ # testname-for-summary when calling into generic function below to
+ # clean temporary files.
+ set output_file $execname
+ set testname_with_flags $execname
+
incr count
file_on_host delete $execname
@@ -774,11 +785,7 @@ proc lto-execute { src1 sid } {
}
}
- # Clean up after -save-temps. The LTO tests don't use dg-test, so
- # testname-for-summary needs to be defined explicitly for each
- # file that needs to be removed.
- set testname_with_flags $execname
-
+ # Clean up after -save-temps.
eval "cleanup-saved-temps"
for {set i 0} {$i < $num_srcs} {incr i} {
@@ -801,52 +808,6 @@ proc lto-execute { src1 sid } {
}
}
-# Utility for scanning a symbol in the final executable, invoked via dg-final.
-# Call pass if pattern is present, otherwise fail.
-#
-# Argument 0 is the regexp to match.
-# Argument 1 handles expected failures and the like
-proc scan-symbol { args } {
- global nm
- global base_dir
- upvar 2 execname execname
-
- if { [llength $args] >= 2 } {
- switch [dg-process-target [lindex $args 1]] {
- "S" { }
- "N" { return }
- "F" { setup_xfail "*-*-*" }
- "P" { }
- }
- }
-
- # Find nm like we find g++ in g++.exp.
- if ![info exists nm] {
- set nm [findfile $base_dir/../../../binutils/nm \
- $base_dir/../../../binutils/nm \
- [findfile $base_dir/../../nm $base_dir/../../nm \
- [findfile $base_dir/nm $base_dir/nm \
- [transform nm]]]]
- verbose -log "nm is $nm"
- }
-
- set output_file "[glob -nocomplain $execname]"
- if { $output_file == "" } {
- fail "scan-symbol $args: dump file does not exist"
- return
- }
-
- set fd [open "| $nm $output_file" r]
- set text [read $fd]
- close $fd
-
- if [regexp -- [lindex $args 0] $text] {
- pass "scan-symbol $args"
- } else {
- fail "scan-symbol $args"
- }
-}
-
# Call pass if object readelf is ok, otherwise fail.
# example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */
proc object-readelf { args } {