diff options
| -rw-r--r-- | gcc/bb-reorder.cc | 13 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr122675-1.c | 31 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/i386/pr122675-1.c | 33 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr122675-1.c | 42 |
4 files changed, 117 insertions, 2 deletions
diff --git a/gcc/bb-reorder.cc b/gcc/bb-reorder.cc index e4efdee..0bcd0e5 100644 --- a/gcc/bb-reorder.cc +++ b/gcc/bb-reorder.cc @@ -2377,7 +2377,11 @@ reorder_basic_blocks_software_trace_cache (void) FREE (bbd); } -/* Order edges by execution frequency, higher first. */ +/* Order edges by execution frequency, higher first. + Return: + 1 iff frequency (VE1) < frequency (VE2) + 0 iff frequency (VE1) == frequency (VE2) + -1 iff frequency (VE1) > frequency (VE2) */ static int edge_order (const void *ve1, const void *ve2) @@ -2392,7 +2396,12 @@ edge_order (const void *ve1, const void *ve2) gcov_type gc1 = c1.initialized_p () ? c1.to_gcov_type () : 0; gcov_type gc2 = c2.initialized_p () ? c2.to_gcov_type () : 0; gcov_type m = MAX (gc1, gc2); - return (m == gc1) - (m == gc2); + int low_to_high_cmp = (m == gc1) - (m == gc2); + /* gcc_stablesort sorts values in low-to-high order. But edges should + be sorted in the opposite order - with highest execution frequency first. + So return an inverted comparison to trick gcc_stablesort into + performing a reversed sorting order. */ + return -1 * low_to_high_cmp; } /* Reorder basic blocks using the "simple" algorithm. This tries to diff --git a/gcc/testsuite/gcc.target/aarch64/pr122675-1.c b/gcc/testsuite/gcc.target/aarch64/pr122675-1.c new file mode 100644 index 0000000..8d2982a --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr122675-1.c @@ -0,0 +1,31 @@ +/* Verify that the most likely BB edges are optimized as fallthroughs. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-pic -mtune=generic -march=armv8-a" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**test: +**.LFB[0-9]+: +** .cfi_startproc +**... +** cbz w0, .L[0-9]* +**... +** bl f1 +**... +** ret +**.L[0-9]+: +**... +** ret +**... +*/ + +int f1(void); + +int test(int a) +{ + if (__builtin_expect(!!a, 1)) { + return f1(); + } + return a; +} diff --git a/gcc/testsuite/gcc.target/i386/pr122675-1.c b/gcc/testsuite/gcc.target/i386/pr122675-1.c new file mode 100644 index 0000000..fb41f5b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122675-1.c @@ -0,0 +1,33 @@ +/* Verify that the most likely BB edges are optimized as fallthroughs. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-pic -march=x86-64 -mtune=generic -mgeneral-regs-only" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target lp64 } {^\t?\.} } } */ + +/* +**test: +**.LFB[0-9]+: +** .cfi_startproc +** testl %edi, %edi +** je .L[0-9]* +** subq \$[0-9]*, %rsp +** .cfi_def_cfa_offset [0-9]* +** call f1 +** addq \$[0-9]*, %rsp +** .cfi_def_cfa_offset [0-9]* +** ret +**.L[0-9]+: +** movl %edi, %eax +** ret +**... +*/ + +int f1(void); + +int test(int a) +{ + if (__builtin_expect(!!a, 1)) { + return f1(); + } + return a; +} diff --git a/gcc/testsuite/gcc.target/riscv/pr122675-1.c b/gcc/testsuite/gcc.target/riscv/pr122675-1.c new file mode 100644 index 0000000..6f49ef3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr122675-1.c @@ -0,0 +1,42 @@ +/* Verify that the most likely BB edges are optimized as fallthroughs. */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fno-pic -march=rv64gc -mabi=lp64d" } */ +/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */ +/* { dg-final { check-function-bodies "**" "" "" { target *-*-* } {^\t?\.} } } */ + +/* +**test: +**... +**.LFB[0-9]+: +**... +** .cfi_startproc +**... +** beq a0,zero,.L[0-9]* +**... +** call f1 +**... +** ( +** jr ra +** | +** ret +** ) +**... +**.L[0-9]+: +**... +** ( +** jr ra +** | +** ret +** ) +**... +*/ + +int f1(void); + +int test(int a) +{ + if (__builtin_expect(!!a, 1)) { + return f1(); + } + return a; +} |
