Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] Allow specification of double GRF mode for SYCL #6914

Merged
merged 5 commits into from
Oct 13, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions llvm/include/llvm/SYCLLowerIR/CallgraphUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//===------------ CallgraphUtils.h - Callgraph utility functions
sarnex marked this conversation as resolved.
Show resolved Hide resolved
//------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Utility functions for traversing callgraphs.
//===----------------------------------------------------------------------===//
#pragma once

#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Function.h"

#include <functional>
namespace llvm {
namespace sycl {
namespace utils {
using CallGraphNodeAction = std::function<void(Function *)>;

// Traverses call graph starting from given function up the call chain applying
// given action to each function met on the way. If \c ErrorOnNonCallUse
// parameter is true, then no functions' uses are allowed except calls.
// Otherwise, any function where use of the current one happened is added to the
// call graph as if the use was a call.
// Functions which are part of the visited set ('Visited' parameter) are not
// traversed.
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction NodeF,
SmallPtrSetImpl<Function *> &Visited,
bool ErrorOnNonCallUse);

template <class CallGraphNodeActionF>
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
SmallPtrSetImpl<Function *> &Visited,
bool ErrorOnNonCallUse) {
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
ErrorOnNonCallUse);
}

template <class CallGraphNodeActionF>
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
bool ErrorOnNonCallUse = true) {
SmallPtrSet<Function *, 32> Visited;
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
ErrorOnNonCallUse);
}
} // namespace utils
} // namespace sycl
} // namespace llvm
32 changes: 0 additions & 32 deletions llvm/include/llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,43 +11,11 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Function.h"

#include <functional>

namespace llvm {
namespace esimd {

constexpr char ATTR_DOUBLE_GRF[] = "esimd-double-grf";
constexpr char ESIMD_MARKER_MD[] = "sycl_explicit_simd";

using CallGraphNodeAction = std::function<void(Function *)>;

// Traverses call graph starting from given function up the call chain applying
// given action to each function met on the way. If \c ErrorOnNonCallUse
// parameter is true, then no functions' uses are allowed except calls.
// Otherwise, any function where use of the current one happened is added to the
// call graph as if the use was a call.
// Functions which are part of the visited set ('Visited' parameter) are not
// traversed.
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction NodeF,
SmallPtrSetImpl<Function *> &Visited,
bool ErrorOnNonCallUse);

template <class CallGraphNodeActionF>
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
SmallPtrSetImpl<Function *> &Visited,
bool ErrorOnNonCallUse) {
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
ErrorOnNonCallUse);
}

template <class CallGraphNodeActionF>
void traverseCallgraphUp(Function *F, CallGraphNodeActionF ActionF,
bool ErrorOnNonCallUse = true) {
SmallPtrSet<Function *, 32> Visited;
traverseCallgraphUp(F, CallGraphNodeAction(ActionF), Visited,
ErrorOnNonCallUse);
}

// Tells whether given function is a ESIMD kernel.
bool isESIMDKernel(const Function &F);
// Tells whether given function is a ESIMD function.
Expand Down
27 changes: 27 additions & 0 deletions llvm/include/llvm/SYCLLowerIR/LowerKernelProps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===---- LowerKernelProps.h - lower kernel properties -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Lowers SYCL kernel properties into attributes used by sycl-post-link
//===----------------------------------------------------------------------===//

#pragma once

#include "llvm/IR/PassManager.h"

namespace sycl {
namespace kernel_props {
constexpr char ATTR_DOUBLE_GRF[] = "double-grf";
}
} // namespace sycl
namespace llvm {
// Lowers calls to __sycl_set_kernel_properties
class SYCLLowerKernelPropsPass
: public PassInfoMixin<SYCLLowerKernelPropsPass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
};
} // namespace llvm
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#include "llvm/SYCLLowerIR/ESIMD/ESIMDVerifier.h"
#include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h"
#include "llvm/SYCLLowerIR/LowerInvokeSimd.h"
#include "llvm/SYCLLowerIR/LowerKernelProps.h"
#include "llvm/SYCLLowerIR/LowerWGLocalMemory.h"
#include "llvm/SYCLLowerIR/LowerWGScope.h"
#include "llvm/SYCLLowerIR/MutatePrintfAddrspace.h"
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ MODULE_PASS("memprof-module", ModuleMemProfilerPass())
MODULE_PASS("poison-checking", PoisonCheckingPass())
MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
MODULE_PASS("LowerESIMD", SYCLLowerESIMDPass())
MODULE_PASS("lower-esimd-kernel-props", SYCLLowerESIMDKernelPropsPass())
MODULE_PASS("lower-kernel-props", SYCLLowerKernelPropsPass())
MODULE_PASS("ESIMDLowerVecArg", ESIMDLowerVecArgPass())
MODULE_PASS("esimd-opt-call-conv", ESIMDOptimizeVecArgCallConvPass())
MODULE_PASS("esimd-verifier", ESIMDVerifierPass())
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/SYCLLowerIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ set_property(GLOBAL PROPERTY LLVMGenXIntrinsics_BINARY_PROP ${LLVMGenXIntrinsics

add_llvm_component_library(LLVMSYCLLowerIR
ESIMD/LowerESIMD.cpp
ESIMD/LowerESIMDKernelProps.cpp
ESIMD/LowerESIMDVLoadVStore.cpp
ESIMD/LowerESIMDVecArg.cpp
ESIMD/ESIMDUtils.cpp
ESIMD/ESIMDVerifier.cpp
ESIMD/LowerESIMDKernelAttrs.cpp
ESIMD/ESIMDOptimizeVecArgCallConv.cpp
CallgraphUtils.cpp
LowerInvokeSimd.cpp
LowerKernelProps.cpp
LowerWGScope.cpp
LowerWGLocalMemory.cpp
MutatePrintfAddrspace.cpp
Expand Down
73 changes: 73 additions & 0 deletions llvm/lib/SYCLLowerIR/CallgraphUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===------------ CallgraphUtils.cpp - Callgraph utility functions
//------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Utility functions for traversing callgraphs.
//===----------------------------------------------------------------------===//
#include "llvm/SYCLLowerIR/CallgraphUtils.h"
#include "llvm/IR/Instructions.h"

namespace llvm {
namespace sycl {
namespace utils {
void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction ActionF,
SmallPtrSetImpl<Function *> &FunctionsVisited,
bool ErrorOnNonCallUse) {
SmallVector<Function *, 32> Worklist;

if (FunctionsVisited.count(F) == 0)
Worklist.push_back(F);

while (!Worklist.empty()) {
Function *CurF = Worklist.pop_back_val();
FunctionsVisited.insert(CurF);
// Apply the action function.
ActionF(CurF);

// Update all callers as well.
for (auto It = CurF->use_begin(); It != CurF->use_end(); It++) {
auto FCall = It->getUser();
auto ErrMsg =
llvm::Twine(__FILE__ " ") +
"Function use other than call detected while traversing call\n"
"graph up to a kernel";
if (!isa<CallInst>(FCall)) {
// A use other than a call is met...
if (ErrorOnNonCallUse) {
// ... non-call is an error - report
llvm::report_fatal_error(ErrMsg);
} else {
// ... non-call is OK - add using function to the worklist
if (auto *I = dyn_cast<Instruction>(FCall)) {
auto UseF = I->getFunction();

if (FunctionsVisited.count(UseF) == 0) {
Worklist.push_back(UseF);
}
}
}
} else {
auto *CI = cast<CallInst>(FCall);

if ((CI->getCalledFunction() != CurF)) {
// CurF is used in a call, but not as the callee.
if (ErrorOnNonCallUse)
llvm::report_fatal_error(ErrMsg);
} else {
auto FCaller = CI->getFunction();

if (!FunctionsVisited.count(FCaller)) {
Worklist.push_back(FCaller);
}
}
}
}
}
}
} // namespace utils
} // namespace sycl
} // namespace llvm
55 changes: 0 additions & 55 deletions llvm/lib/SYCLLowerIR/ESIMD/ESIMDUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,6 @@
namespace llvm {
namespace esimd {

void traverseCallgraphUp(llvm::Function *F, CallGraphNodeAction ActionF,
SmallPtrSetImpl<Function *> &FunctionsVisited,
bool ErrorOnNonCallUse) {
SmallVector<Function *, 32> Worklist;

if (FunctionsVisited.count(F) == 0)
Worklist.push_back(F);

while (!Worklist.empty()) {
Function *CurF = Worklist.pop_back_val();
FunctionsVisited.insert(CurF);
// Apply the action function.
ActionF(CurF);

// Update all callers as well.
for (auto It = CurF->use_begin(); It != CurF->use_end(); It++) {
auto FCall = It->getUser();
auto ErrMsg =
llvm::Twine(__FILE__ " ") +
"Function use other than call detected while traversing call\n"
"graph up to a kernel";
if (!isa<CallInst>(FCall)) {
// A use other than a call is met...
if (ErrorOnNonCallUse) {
// ... non-call is an error - report
llvm::report_fatal_error(ErrMsg);
} else {
// ... non-call is OK - add using function to the worklist
if (auto *I = dyn_cast<Instruction>(FCall)) {
auto UseF = I->getFunction();

if (FunctionsVisited.count(UseF) == 0) {
Worklist.push_back(UseF);
}
}
}
} else {
auto *CI = cast<CallInst>(FCall);

if ((CI->getCalledFunction() != CurF)) {
// CurF is used in a call, but not as the callee.
if (ErrorOnNonCallUse)
llvm::report_fatal_error(ErrMsg);
} else {
auto FCaller = CI->getFunction();

if (!FunctionsVisited.count(FCaller)) {
Worklist.push_back(FCaller);
}
}
}
}
}
}

bool isESIMD(const Function &F) {
return F.getMetadata(ESIMD_MARKER_MD) != nullptr;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/SYCLLowerIR/ESIMD/ESIMDVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ static const char *LegalSYCLFunctions[] = {
"^sycl::_V1::exp<.+>",
"^sycl::_V1::bit_cast<.+>",
"^sycl::_V1::operator.+<.+>",
"^sycl::_V1::ext::intel::experimental::set_kernel_properties",
"^sycl::_V1::ext::oneapi::sub_group::.+",
"^sycl::_V1::ext::oneapi::experimental::spec_constant<.+>::.+",
"^sycl::_V1::ext::oneapi::experimental::this_sub_group",
Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/SYCLLowerIR/ESIMD/LowerESIMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h"
#include "llvm/SYCLLowerIR/CallgraphUtils.h"
#include "llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h"

#include "llvm/ADT/DenseMap.h"
Expand Down Expand Up @@ -977,7 +978,7 @@ static void translateSLMInit(CallInst &CI) {
*F->getParent(), genx::KernelMDOp::SLMSize, NewVal};
// TODO: Keep track of traversed functions (use 4-argument version of
// traverseCallgraphUp) to avoid repeating traversals over same function.
esimd::traverseCallgraphUp(F, SetMaxSLMSize);
sycl::utils::traverseCallgraphUp(F, SetMaxSLMSize);
}

// This function sets/updates VCNamedBarrierCount attribute to the kernels
Expand All @@ -995,7 +996,7 @@ static void translateNbarrierInit(CallInst &CI) {
*F->getParent(), genx::KernelMDOp::NBarrierCnt, NewVal};
// TODO: Keep track of traversed functions to avoid repeating traversals
// over same function.
esimd::traverseCallgraphUp(F, SetMaxNBarrierCnt);
sycl::utils::traverseCallgraphUp(F, SetMaxNBarrierCnt);
}

static void translatePackMask(CallInst &CI) {
Expand Down Expand Up @@ -1771,8 +1772,8 @@ size_t SYCLLowerESIMDPass::runOnFunction(Function &F,
ToErase.push_back(CI);
continue;
}
assert(!Name.startswith("__esimd_set_kernel_properties") &&
"__esimd_set_kernel_properties must have been lowered");
assert(!Name.startswith("__sycl_set_kernel_properties") &&
"__sycl_set_kernel_properties must have been lowered");

if (Name.empty() || !Name.startswith(ESIMD_INTRIN_PREF1))
continue;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/SYCLLowerIR/ESIMD/LowerESIMDKernelAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// Finds and adds sycl_explicit_simd attributes to wrapper functions that wrap
// ESIMD kernel functions

#include "llvm/SYCLLowerIR/CallgraphUtils.h"
#include "llvm/SYCLLowerIR/ESIMD/ESIMDUtils.h"
#include "llvm/SYCLLowerIR/ESIMD/LowerESIMD.h"

Expand All @@ -26,7 +27,7 @@ SYCLFixupESIMDKernelWrapperMDPass::run(Module &M, ModuleAnalysisManager &MAM) {
if (llvm::esimd::isESIMD(F)) {
// TODO: Keep track of traversed functions to avoid repeating traversals
// over same function.
llvm::esimd::traverseCallgraphUp(
sycl::utils::traverseCallgraphUp(
&F,
[&](Function *GraphNode) {
if (!llvm::esimd::isESIMD(*GraphNode)) {
Expand Down
Loading