aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlex Coplan <alex.coplan@arm.com>2024-08-03 17:02:36 +0000
committerAlex Coplan <alex.coplan@arm.com>2024-09-11 11:50:48 +0100
commit9759f6299d9633cabac540e5c893341c708093ac (patch)
tree801554cd6a88774873385b3d3e865e3eac8e49b3 /gcc
parent31ff173c70847bba94613eac5b1ef2c0bec842e6 (diff)
downloadgcc-9759f6299d9633cabac540e5c893341c708093ac.zip
gcc-9759f6299d9633cabac540e5c893341c708093ac.tar.gz
gcc-9759f6299d9633cabac540e5c893341c708093ac.tar.bz2
lto: Stream has_unroll flag during LTO [PR116140]
When #pragma GCC unroll is processed in tree-cfg.cc:replace_loop_annotate_in_block, we set both the loop->unroll field (which is currently streamed out and back in during LTO) but also the cfun->has_unroll flag. cfun->has_unroll, however, is not currently streamed during LTO. This patch fixes that. Prior to this patch, loops marked with #pragma GCC unroll that would be unrolled by RTL loop2_unroll in a non-LTO compilation didn't get unrolled under LTO. gcc/ChangeLog: PR libstdc++/116140 * lto-streamer-in.cc (input_struct_function_base): Stream in fn->has_unroll. * lto-streamer-out.cc (output_struct_function_base): Stream out fn->has_unroll. gcc/testsuite/ChangeLog: PR libstdc++/116140 * g++.dg/ext/pragma-unroll-lambda-lto.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/lto-streamer-in.cc1
-rw-r--r--gcc/lto-streamer-out.cc1
-rw-r--r--gcc/testsuite/g++.dg/ext/pragma-unroll-lambda-lto.C32
3 files changed, 34 insertions, 0 deletions
diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index 64f7580..9d0ec5d 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -1326,6 +1326,7 @@ input_struct_function_base (struct function *fn, class data_in *data_in,
fn->has_force_vectorize_loops = bp_unpack_value (&bp, 1);
fn->has_simduid_loops = bp_unpack_value (&bp, 1);
fn->has_musttail = bp_unpack_value (&bp, 1);
+ fn->has_unroll = bp_unpack_value (&bp, 1);
fn->assume_function = bp_unpack_value (&bp, 1);
fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index a4b1713..807b935 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -2283,6 +2283,7 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
bp_pack_value (&bp, fn->has_force_vectorize_loops, 1);
bp_pack_value (&bp, fn->has_simduid_loops, 1);
bp_pack_value (&bp, fn->has_musttail, 1);
+ bp_pack_value (&bp, fn->has_unroll, 1);
bp_pack_value (&bp, fn->assume_function, 1);
bp_pack_value (&bp, fn->va_list_fpr_size, 8);
bp_pack_value (&bp, fn->va_list_gpr_size, 8);
diff --git a/gcc/testsuite/g++.dg/ext/pragma-unroll-lambda-lto.C b/gcc/testsuite/g++.dg/ext/pragma-unroll-lambda-lto.C
new file mode 100644
index 0000000..144c4c3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/pragma-unroll-lambda-lto.C
@@ -0,0 +1,32 @@
+// { dg-do link { target c++11 } }
+// { dg-options "-O2 -flto -fdump-rtl-loop2_unroll" }
+
+#include <cstdlib>
+
+template<typename Iter, typename Pred>
+inline Iter
+my_find(Iter first, Iter last, Pred pred)
+{
+#pragma GCC unroll 4
+ while (first != last && !pred(*first))
+ ++first;
+ return first;
+}
+
+__attribute__((noipa))
+short *use_find(short *p)
+{
+ auto pred = [](short x) { return x == 42; };
+ return my_find(p, p + 1024, pred);
+}
+
+int main(void)
+{
+ short a[1024];
+ for (int i = 0; i < 1024; i++)
+ a[i] = rand ();
+
+ return use_find (a) - a;
+}
+
+// { dg-final { scan-ltrans-rtl-dump-times "Unrolled loop 3 times" 1 "loop2_unroll" } }