Skip to content

Commit aa70922

Browse files
authored
[ESIMD] Do simd<T, N>* to <N x T> arg/ret type conv when possible. (#6835)
Today, `simd<T, N> foo(simd<T, N> x)` is codegenerated by clang as `void foo(simd<T, N>* sret(simd<T, N>) %res, simd<T, N>* %x)` for the SPIRV target (unless `__regcall` is specified), which is then converted to `void foo(<N x T>* sret(<N x T>) %res, <N x T>* %x)` in the LowerESIMDVecArg, then to `<N x T> foo(<N x T> %x)` in the VC BE. With the opaque pointers this becomes impossible, and the optimization must happen in the "ESIMD FE". This patch implements it. It also changes `lowerEsimdConstructs` in sycl-post-link.cpp to use new pass manager to avoid the old pass manager-related boiler plate code in new ESIMD transformations. Signed-off-by: Konstantin S Bobrovsky <[email protected]>
1 parent 4a440da commit aa70922

File tree

14 files changed

+930
-78
lines changed

14 files changed

+930
-78
lines changed

llvm/include/llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// Utility functions for processing ESIMD code.
99
//===----------------------------------------------------------------------===//
1010

11+
#include "llvm/ADT/SmallPtrSet.h"
1112
#include "llvm/IR/Function.h"
1213

1314
#include <functional>
@@ -19,24 +20,40 @@ constexpr char ATTR_DOUBLE_GRF[] = "esimd-double-grf";
1920
constexpr char ESIMD_MARKER_MD[] = "sycl_explicit_simd";
2021

2122
using CallGraphNodeAction = std::function<void(Function *)>;
22-
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction NodeF,
23-
bool ErrorOnNonCallUse);
2423

2524
// Traverses call graph starting from given function up the call chain applying
2625
// given action to each function met on the way. If \c ErrorOnNonCallUse
2726
// parameter is true, then no functions' uses are allowed except calls.
2827
// Otherwise, any function where use of the current one happened is added to the
2928
// call graph as if the use was a call.
29+
// Functions which are part of the visited set ('Visited' parameter) are not
30+
// traversed.
31+
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction NodeF,
32+
SmallPtrSetImpl<Function *> &Visited,
33+
bool ErrorOnNonCallUse);
34+
35+
template <class CallGraphNodeActionF>
36+
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
37+
SmallPtrSetImpl<Function *> &Visited,
38+
bool ErrorOnNonCallUse) {
39+
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
40+
ErrorOnNonCallUse);
41+
}
42+
3043
template <class CallGraphNodeActionF>
3144
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
3245
bool ErrorOnNonCallUse = true) {
33-
traverseCallgraphUp(F, CallGraphNodeAction{ActionF}, ErrorOnNonCallUse);
46+
SmallPtrSet<Function *, 32> Visited;
47+
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
48+
ErrorOnNonCallUse);
3449
}
3550

3651
// Tells whether given function is a ESIMD kernel.
3752
bool isESIMDKernel(const Function &F);
3853
// Tells whether given function is a ESIMD function.
3954
bool isESIMD(const Function &F);
55+
// Tells whether given function is a kernel.
56+
bool isKernel(const Function &F);
4057

4158
/// Reports and error with the message \p Msg concatenated with the optional
4259
/// \p OptMsg if \p Condition is false.
@@ -48,5 +65,22 @@ inline void assert_and_diag(bool Condition, StringRef Msg,
4865
}
4966
}
5067

68+
/// Tells if this value is a bit cast or address space cast.
69+
bool isCast(const Value *V);
70+
71+
/// Climbs up the use-def chain of given value until a value which is not a
72+
/// bit cast or address space cast is met.
73+
const Value *stripCasts(const Value *V);
74+
Value *stripCasts(Value *V);
75+
76+
/// Collects uses of given value "looking through" casts. I.e. if a use is a
77+
/// cast (chain), then uses of the result of the cast (chain) are collected.
78+
void collectUsesLookThroughCasts(const Value *V,
79+
SmallPtrSetImpl<const Use *> &Uses);
80+
81+
/// Unwraps a presumably simd* type to extract the native vector type encoded
82+
/// in it. Returns nullptr if failed to do so.
83+
Type *getVectorTyOrNull(StructType *STy);
84+
5185
} // namespace esimd
5286
} // namespace llvm

llvm/include/llvm/SYCLLowerIR/ESIMD/LowerESIMD.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@ class ESIMDLowerVecArgPass : public PassInfoMixin<ESIMDLowerVecArgPass> {
6969
ModulePass *createESIMDLowerVecArgPass();
7070
void initializeESIMDLowerVecArgLegacyPassPass(PassRegistry &);
7171

72+
// - Converts simd* function parameters and return values passed by pointer to
73+
// pass-by-value
74+
// (where possible)
75+
// - Converts globals of type simd* to simd::raw_vector_t* globals (llvm vector
76+
// type pointer)
77+
class ESIMDOptimizeVecArgCallConvPass
78+
: public PassInfoMixin<ESIMDOptimizeVecArgCallConvPass> {
79+
public:
80+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
81+
};
82+
7283
// Lowers calls to __esimd_set_kernel_properties
7384
class SYCLLowerESIMDKernelPropsPass
7485
: public PassInfoMixin<SYCLLowerESIMDKernelPropsPass> {

llvm/lib/Passes/PassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
129129
MODULE_PASS("LowerESIMD", SYCLLowerESIMDPass())
130130
MODULE_PASS("lower-esimd-kernel-props", SYCLLowerESIMDKernelPropsPass())
131131
MODULE_PASS("ESIMDLowerVecArg", ESIMDLowerVecArgPass())
132+
MODULE_PASS("esimd-opt-call-conv", ESIMDOptimizeVecArgCallConvPass())
132133
MODULE_PASS("esimd-verifier", ESIMDVerifierPass())
133134
MODULE_PASS("lower-invoke-simd", SYCLLowerInvokeSimdPass())
134135
MODULE_PASS("SYCLMutatePrintfAddrspace", SYCLMutatePrintfAddrspacePass())

llvm/lib/SYCLLowerIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ add_llvm_component_library(LLVMSYCLLowerIR
5454
ESIMD/ESIMDUtils.cpp
5555
ESIMD/ESIMDVerifier.cpp
5656
ESIMD/LowerESIMDKernelAttrs.cpp
57+
ESIMD/ESIMDOptimizeVecArgCallConv.cpp
5758
LowerInvokeSimd.cpp
5859
LowerWGScope.cpp
5960
LowerWGLocalMemory.cpp

0 commit comments

Comments
 (0)