]> granicus.if.org Git - llvm/commit
[GVNSink] GVNSink pass
authorJames Molloy <james.molloy@arm.com>
Thu, 25 May 2017 12:51:11 +0000 (12:51 +0000)
committerJames Molloy <james.molloy@arm.com>
Thu, 25 May 2017 12:51:11 +0000 (12:51 +0000)
commit9693a6db68198e4994eb40365f3d1507e187a508
treec5472d6e656a1f71370c12fc110389fa99e61e69
parent4fde77f8f1a8e4482e69b6a7484bc7d1b99b3c0a
[GVNSink] GVNSink pass

This patch provides an initial prototype for a pass that sinks instructions based on GVN information, similar to GVNHoist. It is not yet ready for commiting but I've uploaded it to gather some initial thoughts.

This pass attempts to sink instructions into successors, reducing static
instruction count and enabling if-conversion.
We use a variant of global value numbering to decide what can be sunk.
Consider:

[ %a1 = add i32 %b, 1  ]   [ %c1 = add i32 %d, 1  ]
[ %a2 = xor i32 %a1, 1 ]   [ %c2 = xor i32 %c1, 1 ]
                 \           /
           [ %e = phi i32 %a2, %c2 ]
           [ add i32 %e, 4         ]

GVN would number %a1 and %c1 differently because they compute different
results - the VN of an instruction is a function of its opcode and the
transitive closure of its operands. This is the key property for hoisting
and CSE.

What we want when sinking however is for a numbering that is a function of
the *uses* of an instruction, which allows us to answer the question "if I
replace %a1 with %c1, will it contribute in an equivalent way to all
successive instructions?". The (new) PostValueTable class in GVN provides this
mapping.

This pass has some shown really impressive improvements especially for codesize already on internal benchmarks, so I have high hopes it can replace all the sinking logic in SimplifyCFG.

Differential revision: https://reviews.llvm.org/D24805

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303850 91177308-0d34-0410-b5e6-96231b3b80d8
14 files changed:
include/llvm/InitializePasses.h
include/llvm/Transforms/Scalar.h
include/llvm/Transforms/Scalar/GVN.h
include/llvm/Transforms/Utils/Local.h
lib/Transforms/IPO/PassManagerBuilder.cpp
lib/Transforms/Scalar/CMakeLists.txt
lib/Transforms/Scalar/GVNSink.cpp [new file with mode: 0644]
lib/Transforms/Scalar/Scalar.cpp
lib/Transforms/Utils/Local.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
test/Transforms/GVNSink/dither.ll [new file with mode: 0644]
test/Transforms/GVNSink/indirect-call.ll [new file with mode: 0644]
test/Transforms/GVNSink/sink-common-code.ll [new file with mode: 0644]
test/Transforms/GVNSink/struct.ll [new file with mode: 0644]