Changes in v2: 1. Search backward from exit basic blocks with only sibcalls. 2. Add anycall_p to return true for call and conditional sibcall. 3. Replace CALL_P with anycall_p in except.cc to handle exceptions with conditional sibcalls. 4. Update the gate function to follow the tree tailcall pass.
--- Conditional and unconditional branch targets can be either a label or a symbol. For conditional jump: (jump_insn 7 6 14 2 (set (pc) (if_then_else (eq (reg:CCZ 17 flags) (const_int 0 [0])) (label_ref:DI 23) (pc))) "x.c":8:5 1458 {jcc} (expr_list:REG_DEAD (reg:CCZ 17 flags) (int_list:REG_BR_PROB 217325348 (nil))) ... (code_label 23 20 8 4 4 (nil) [1 uses]) (note 8 23 9 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (call_insn/j 9 8 10 4 (call (mem:QI (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7f4cff3c0b00 bar>) [0 bar S1 A8]) (const_int 0 [0])) "x.c":8:14 discrim 1 1469 {sibcall_di} (expr_list:REG_CALL_DECL (symbol_ref:DI ("bar") [flags 0x41] <function_dec l 0x7f4cff3c0b00 bar>) (nil)) (nil)) they can be changed to (jump_insn 7 6 14 2 (set (pc) (if_then_else (eq (reg:CCZ 17 flags) (const_int 0 [0])) ((symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7fffe99c0c00 foo>) (pc))) "x.c":8:5 1458 {jcc} (expr_list:REG_DEAD (reg:CCZ 17 flags) (int_list:REG_BR_PROB 217325348 (nil))) if the call is a sibcall. For jump table: (jump_table_data 16 15 17 (addr_vec:DI [ (label_ref:DI 18) (label_ref:DI 22) (label_ref:DI 26) (label_ref:DI 30) (label_ref:DI 34) ])) ... (code_label 30 17 31 4 5 (nil) [1 uses]) (note 31 30 32 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (call_insn/j 32 31 33 4 (call (mem:QI (symbol_ref:DI ("bar3") [flags 0x41] <function_decl 0x7f21be3c0e00 bar3>) [0 bar3 S1 A8]) (const_int 0 [0])) "j.c":15:13 1469 {sibcall_di} (expr_list:REG_CALL_DECL (symbol_ref:DI ("bar3") [flags 0x41] <function_decl 0x7f21be3c0e00 bar3>) (nil)) (nil)) They can be changed to (jump_table_data 16 15 17 (addr_vec:DI [ (symbol_ref:DI ("bar0") [flags 0x41] <function_decl 0x7f4f1c5c0b00 bar0>) (symbol_ref:DI ("bar1") [flags 0x41] <function_decl 0x7f4f1c5c0c00 bar1>) (symbol_ref:DI ("bar2") [flags 0x41] <function_decl 0x7f4f1c5c0d00 bar2>) (symbol_ref:DI ("bar3") [flags 0x41] <function_decl 0x7f4f1c5c0e00 bar3>) (symbol_ref:DI ("bar4") [flags 0x41] <function_decl 0x7f4f1c5c0f00 bar4>) ])) if bar0/bar1/bar2/bar3/bar4 calls are sibcalls. Instead of supporting symbol reference in jump label and jump table in the full RTL optimization pipeline, which requires very invasive changes to GCC RTL infrastructure, support symbol reference in jump label and jump table for the pass which turning REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes and after. Searching backward from exit basic blocks with only sibcalls, check the last instruction in each predecessor. If the last instruction is a conditional jump and its target is the exit block, change the conditional jump target to the sibcall target, decrement the destination basic block entry label use count, redirect the edge to the exit basic block and call delete_unreachable_blocks to delete the unreachable basic blocks. Repeat it until there is no conditional jump to update. If the jump table entry points to a target basic block with only a direct sibcall, change the entry to point to the sibcall target, decrement the target basic block entry label use count and redirect the edge to the exit basic block. H.J. Lu (3): Support symbol reference in jump label and jump table x86: Add a pass to fold tail call x86: Fold sibcall targets into jump table gcc/config/i386/i386-expand.cc | 5 +- gcc/config/i386/i386-features.cc | 327 +++++++++++++++++++++ gcc/config/i386/i386-passes.def | 1 + gcc/config/i386/i386-protos.h | 3 + gcc/config/i386/i386.cc | 12 + gcc/config/i386/i386.md | 9 +- gcc/config/i386/predicates.md | 4 + gcc/doc/rtl.texi | 24 +- gcc/dwarf2cfi.cc | 20 +- gcc/except.cc | 11 +- gcc/final.cc | 26 +- gcc/function-abi.cc | 2 +- gcc/jump.cc | 36 +++ gcc/print-rtl.cc | 2 + gcc/rtl.h | 32 ++ gcc/rtlanal.cc | 5 +- gcc/testsuite/gcc.target/i386/pr14721-1a.c | 54 ++++ gcc/testsuite/gcc.target/i386/pr14721-1b.c | 37 +++ gcc/testsuite/gcc.target/i386/pr14721-1c.c | 37 +++ gcc/testsuite/gcc.target/i386/pr14721-2a.c | 58 ++++ gcc/testsuite/gcc.target/i386/pr14721-2b.c | 41 +++ gcc/testsuite/gcc.target/i386/pr14721-2c.c | 43 +++ gcc/testsuite/gcc.target/i386/pr14721-3a.c | 56 ++++ gcc/testsuite/gcc.target/i386/pr14721-3b.c | 40 +++ gcc/testsuite/gcc.target/i386/pr14721-3c.c | 39 +++ gcc/testsuite/gcc.target/i386/pr47253-10.c | 15 + gcc/testsuite/gcc.target/i386/pr47253-1a.c | 24 ++ gcc/testsuite/gcc.target/i386/pr47253-1b.c | 17 ++ gcc/testsuite/gcc.target/i386/pr47253-2a.c | 29 ++ gcc/testsuite/gcc.target/i386/pr47253-2b.c | 17 ++ gcc/testsuite/gcc.target/i386/pr47253-3a.c | 32 ++ gcc/testsuite/gcc.target/i386/pr47253-3b.c | 20 ++ gcc/testsuite/gcc.target/i386/pr47253-3c.c | 20 ++ gcc/testsuite/gcc.target/i386/pr47253-4a.c | 26 ++ gcc/testsuite/gcc.target/i386/pr47253-4b.c | 18 ++ gcc/testsuite/gcc.target/i386/pr47253-5.c | 15 + gcc/testsuite/gcc.target/i386/pr47253-6.c | 15 + gcc/testsuite/gcc.target/i386/pr47253-7a.c | 52 ++++ gcc/testsuite/gcc.target/i386/pr47253-7b.c | 36 +++ gcc/testsuite/gcc.target/i386/pr47253-8.c | 74 +++++ gcc/testsuite/gcc.target/i386/pr47253-9.c | 22 ++ 41 files changed, 1330 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-1c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-2c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr14721-3c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-10.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-1b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-2a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-2b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-3a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-3b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-3c.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-4a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-4b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-5.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-6.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-7a.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-7b.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-8.c create mode 100644 gcc/testsuite/gcc.target/i386/pr47253-9.c -- 2.49.0