From: "wangjue.wangjue" <[email protected]>
RISC-V enables -funroll-loops at -O2 for small-loop unrolling. Keep
size-growing complete unrolling disabled unless unrolling is explicitly
requested.
gcc/ChangeLog:
* config/riscv/riscv.cc (riscv_override_options_after_change): New
function.
(riscv_option_override): Call it.
(TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/unroll-explicit-attr-cunroll.c: New test.
* gcc.target/riscv/unroll-small-loop-cunroll.c: New test.
---
gcc/config/riscv/riscv.cc | 31 +++++++++++++------
.../riscv/unroll-explicit-attr-cunroll.c | 22 +++++++++++++
.../riscv/unroll-small-loop-cunroll.c | 22 +++++++++++++
3 files changed, 66 insertions(+), 9 deletions(-)
create mode 100644
gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c
create mode 100644 gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 57e798556d0..a401c0c7c93 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -12142,6 +12142,24 @@ riscv_override_options_internal (struct gcc_options
*opts)
}
}
+/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */
+
+static void
+riscv_override_options_after_change (void)
+{
+ /* Explicit unrolling is not restricted to small loops. */
+ if ((OPTION_SET_P (flag_unroll_loops) && flag_unroll_loops)
+ || (OPTION_SET_P (flag_unroll_all_loops) && flag_unroll_all_loops))
+ {
+ if (!OPTION_SET_P (riscv_unroll_only_small_loops))
+ riscv_unroll_only_small_loops = 0;
+ if (!OPTION_SET_P (flag_cunroll_grow_size))
+ flag_cunroll_grow_size = 1;
+ }
+ else if (!OPTION_SET_P (flag_cunroll_grow_size))
+ flag_cunroll_grow_size = flag_peel_loops || optimize >= 3;
+}
+
/* Implement TARGET_OPTION_OVERRIDE. */
void
@@ -12153,15 +12171,7 @@ riscv_option_override (void)
flag_pcc_struct_return = 0;
- /* Explicit -funroll-loops or -funroll-all-loops turns
- -munroll-only-small-loops off, allowing the unroller to handle
- all loops without the conservative small-loop restriction. */
- if ((OPTION_SET_P (flag_unroll_loops) && flag_unroll_loops)
- || (OPTION_SET_P (flag_unroll_all_loops) && flag_unroll_all_loops))
- {
- if (!OPTION_SET_P (riscv_unroll_only_small_loops))
- riscv_unroll_only_small_loops = 0;
- }
+ riscv_override_options_after_change ();
if (flag_pic)
g_switch_value = 0;
@@ -16523,6 +16533,9 @@ riscv_memtag_tag_bitsize ()
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE riscv_option_override
+#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
riscv_override_options_after_change
+
#undef TARGET_OPTION_SAVE
#define TARGET_OPTION_SAVE riscv_option_save
diff --git a/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c
b/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c
new file mode 100644
index 00000000000..e9628cf8ffb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/unroll-explicit-attr-cunroll.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cunroll-details" } */
+
+unsigned short data;
+
+__attribute__ ((optimize ("unroll-loops")))
+void
+explicit_attr_cunroll (void)
+{
+ unsigned char x;
+
+ for (unsigned int i = 0; i < 8; ++i)
+ {
+ x = data & 1;
+ data >>= 1;
+ if (x == 1)
+ data ^= 0x4;
+ data >>= 1;
+ }
+}
+
+/* { dg-final { scan-tree-dump "loop with 7 iterations completely unrolled"
"cunroll" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c
b/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c
new file mode 100644
index 00000000000..87aec5988fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/unroll-small-loop-cunroll.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cunroll-details" } */
+
+unsigned short data;
+
+void
+small_loop_cunroll (void)
+{
+ unsigned char x;
+
+ for (unsigned int i = 0; i < 8; ++i)
+ {
+ x = data & 1;
+ data >>= 1;
+ if (x == 1)
+ data ^= 0x4;
+ data >>= 1;
+ }
+}
+
+/* { dg-final { scan-tree-dump "Not unrolling loop \[0-9\]\+: size would grow"
"cunroll" } } */
+/* { dg-final { scan-tree-dump-not "completely unrolled" "cunroll" } } */
--
2.34.1