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

Reply via email to