From 9b11203e33f999933aaa99bba779ffd7cd329849 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 2 Oct 2020 14:12:06 +0200 Subject: [PATCH] Add -fbit-tests option. gcc/ChangeLog: * common.opt: Add new -fbit-tests option. * doc/invoke.texi: Document the option. * tree-switch-conversion.c (bit_test_cluster::find_bit_tests): Use the option. * tree-switch-conversion.h (is_enabled): New function. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/switch-4.c: New test. --- gcc/common.opt | 4 ++++ gcc/doc/invoke.texi | 8 +++++++- gcc/testsuite/gcc.dg/tree-ssa/switch-4.c | 25 ++++++++++++++++++++++++ gcc/tree-switch-conversion.c | 3 +++ gcc/tree-switch-conversion.h | 6 ++++++ 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/switch-4.c diff --git a/gcc/common.opt b/gcc/common.opt index d4cbb2f86a5..7d0e0d9c88a 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1940,6 +1940,10 @@ fjump-tables Common Var(flag_jump_tables) Init(1) Optimization Use jump tables for sufficiently large switch statements. +fbit-tests +Common Var(flag_bit_tests) Init(1) Optimization +Use bit tests for sufficiently large switch statements. + fkeep-inline-functions Common Report Var(flag_keep_inline_functions) Generate code for functions even if they are fully inlined. diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 32f90ef2022..271373c381b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -638,7 +638,7 @@ Objective-C and Objective-C++ Dialects}. -fno-gnu-unique @gol -finhibit-size-directive -fcommon -fno-ident @gol -fpcc-struct-return -fpic -fPIC -fpie -fPIE -fno-plt @gol --fno-jump-tables @gol +-fno-jump-tables -fno-bit-tests @gol -frecord-gcc-switches @gol -freg-struct-return -fshort-enums -fshort-wchar @gol -fverbose-asm -fpack-struct[=@var{n}] @gol @@ -15989,6 +15989,12 @@ building code that forms part of a dynamic linker and cannot reference the address of a jump table. On some targets, jump tables do not require a GOT and this option is not needed. +@item -fno-bit-tests +@opindex fno-bit-tests +@opindex fbit-tests +Do not use bit tests for switch statements even where it would be +more efficient than other code generation strategies. + @item -ffixed-@var{reg} @opindex ffixed Treat the register named @var{reg} as a fixed register; generated code diff --git a/gcc/testsuite/gcc.dg/tree-ssa/switch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/switch-4.c new file mode 100644 index 00000000000..5953ef34e9b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/switch-4.c @@ -0,0 +1,25 @@ +/* { dg-do compile { target { { x86_64-*-* aarch64-*-* ia64-*-* powerpc64-*-* } && lp64 } } } */ +/* { dg-options "-O2 -fno-bit-tests -fdump-tree-switchlower1" } */ + +int global; + +int foo (int x) +{ + switch (x) { + case 0: + case 10: + return 1; + case 20: + case 30: + case 62: + return 2; + case 1000: + case 1010: + case 1025 ... 1030: + return 1; + default: + return 0; + } +} + +/* { dg-final { scan-tree-dump-not "BT:" "switchlower1" } } */ diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 03a1fe632d0..426462e856b 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1310,6 +1310,9 @@ jump_table_cluster::is_beneficial (const vec &, vec bit_test_cluster::find_bit_tests (vec &clusters) { + if (!is_enabled ()) + return clusters.copy (); + unsigned l = clusters.length (); auto_vec min; min.reserve (l + 1); diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h index dbfd9eecba2..7515e952eb3 100644 --- a/gcc/tree-switch-conversion.h +++ b/gcc/tree-switch-conversion.h @@ -411,6 +411,12 @@ public: basic_block case_bb, profile_probability prob); + /* Return whether bit test expansion is allowed. */ + static inline bool is_enabled (void) + { + return flag_bit_tests; + } + /* True when the jump table handles an entire switch statement. */ bool m_handles_entire_switch; -- 2.30.2