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.

If the branch edge destination is a basic block with only a direct
sibcall, change the jcc target to the sibcall target, decrement the
destination basic block entry label use count and redirect the edge
to the exit basic block.

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.

Call delete_unreachable_blocks to delete the unreachable basic blocks at
the end if edges are redirected.

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             |   4 +-
 gcc/config/i386/i386-features.cc           | 280 +++++++++++++++++++++
 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/final.cc                               |  26 +-
 gcc/function-abi.cc                        |   2 +-
 gcc/jump.cc                                |  36 +++
 gcc/print-rtl.cc                           |   2 +
 gcc/rtl.h                                  |   8 +
 gcc/rtlanal.cc                             |   4 +-
 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-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 ++++++
 38 files changed, 1214 insertions(+), 21 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-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

-- 
2.48.1

Reply via email to