Skip to content

Commit

Permalink
Add list of vector compute metadata to GenXMetadata.h
Browse files Browse the repository at this point in the history
Add GenXSPIRVWriterAdaptor and GenXSPIRVReaderAdaptor
  • Loading branch information
NikitaRudenkoIntel authored and aus-intel committed Jun 22, 2020
1 parent cce6e48 commit d7c5f99
Show file tree
Hide file tree
Showing 6 changed files with 527 additions and 1 deletion.
20 changes: 19 additions & 1 deletion GenXIntrinsics/include/llvm/GenXIntrinsics/GenXMetadata.h
Expand Up @@ -47,12 +47,30 @@ const static char OCLRuntime[] = "oclrt";
const static char ReferencedIndirectly[] = "referenced-indirectly";
} // namespace FunctionMD

namespace VCModuleMD {
const static char VCGlobalVariable[] = "VCGlobalVariable";
const static char VCVolatile[] = "VCVolatile";
const static char VCByteOffset[] = "VCByteOffset";
} // namespace VCModuleMD

namespace VCFunctionMD {
const static char VCFunction[] = "VCFunction";
const static char VCStackCall[] = "VCStackCall";
const static char VCArgumentIOKind[] = "VCArgumentIOKind";
const static char VCFloatControl[] = "VCFloatControl";
const static char VCSLMSize[] = "VCSLMSize";
const static char VCArgumentKind[] = "VCArgumentKind";
const static char VCArgumentDesc[] = "VCArgumentDesc";
} // namespace VCFunctionMD

namespace SPIRVParams {
const static char SPIRVMemoryModel[] = "spirv.MemoryModel";
const static char SPIRVSIMDSubgroupSize[] = "intel_reqd_sub_group_size";
const static unsigned SPIRVMemoryModelSimple = 0;
const static unsigned SPIRVMemoryModelOCL = 2;
const static unsigned SPIRVAddressingModel32 = 1;
const static unsigned SPIRVAddressingModel64 = 2;
} // namespace SPIRVMD
} // namespace SPIRVParams

enum KernelMDOp {
FunctionRef, // Reference to Function
Expand Down
@@ -0,0 +1,57 @@
/*===================== begin_copyright_notice ==================================
Copyright (c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
======================= end_copyright_notice ==================================*/
///
/// GenXSPIRVReaderAdaptor
/// ---------------------------
/// This pass converts metadata from SPIRV format to whichever used in backend

#include "llvm/ADT/StringRef.h"
#include "llvm/Pass.h"

namespace llvm {
namespace genx {
class GenXSPIRVReaderAdaptor final : public ModulePass {

public:
static char ID;
explicit GenXSPIRVReaderAdaptor() : ModulePass(ID) {}
llvm::StringRef getPassName() const override {
return "GenX SPIRVReader Adaptor";
}
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnModule(Module &M) override;

private:
bool runOnFunction(Function &F);
};

} // namespace genx
} // namespace llvm

namespace llvm {
void initializeGenXSPIRVReaderAdaptorPass(PassRegistry &);
ModulePass *createGenXSPIRVReaderAdaptorPass();
} // namespace llvm
@@ -0,0 +1,57 @@
/*===================== begin_copyright_notice ==================================
Copyright (c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
======================= end_copyright_notice ==================================*/
///
/// GenXSPIRVWriterAdaptor
/// ---------------------------
/// This pass converts metadata to SPIRV format from whichever used in frontend

#include "llvm/ADT/StringRef.h"
#include "llvm/Pass.h"

namespace llvm {
namespace genx {
class GenXSPIRVWriterAdaptor final : public ModulePass {

public:
static char ID;
explicit GenXSPIRVWriterAdaptor() : ModulePass(ID) {}
llvm::StringRef getPassName() const override {
return "GenX SPIRVWriter Adaptor";
}
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnModule(Module &M) override;

private:
bool runOnFunction(Function &F);
};

} // namespace genx
} // namespace llvm

namespace llvm {
void initializeGenXSPIRVWriterAdaptorPass(PassRegistry &);
ModulePass *createGenXSPIRVWriterAdaptorPass();
} // namespace llvm
4 changes: 4 additions & 0 deletions GenXIntrinsics/lib/GenXIntrinsics/CMakeLists.txt
Expand Up @@ -3,6 +3,8 @@ if(BUILD_EXTERNAL)
GenXIntrinsics.cpp
GenXRestoreIntrAttr.cpp
GenXSimdCFLowering.cpp
GenXSPIRVReaderAdaptor.cpp
GenXSPIRVWriterAdaptor.cpp
)
llvm_update_compile_flags(LLVMGenXIntrinsics)
add_dependencies(LLVMGenXIntrinsics GenXIntrinsicsGen)
Expand All @@ -21,6 +23,8 @@ else()
GenXIntrinsics.cpp
GenXRestoreIntrAttr.cpp
GenXSimdCFLowering.cpp
GenXSPIRVReaderAdaptor.cpp
GenXSPIRVWriterAdaptor.cpp
ADDITIONAL_HEADER_DIRS
${GENX_INTRINSICS_MAIN_INCLUDE_DIR}/llvm/GenXIntrinsics

Expand Down
181 changes: 181 additions & 0 deletions GenXIntrinsics/lib/GenXIntrinsics/GenXSPIRVReaderAdaptor.cpp
@@ -0,0 +1,181 @@
/*===================== begin_copyright_notice ==================================
Copyright (c) 2017 Intel Corporation
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
======================= end_copyright_notice ==================================*/
///
/// GenXSPIRVReaderAdaptor
/// ---------------------------
/// This pass converts metadata from SPIRV format to whichever used in backend

#include "llvm/GenXIntrinsics/GenXSPIRVReaderAdaptor.h"
#include "llvm/GenXIntrinsics/GenXMetadata.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"

using namespace llvm;
using namespace genx;

char GenXSPIRVReaderAdaptor::ID = 0;

INITIALIZE_PASS_BEGIN(GenXSPIRVReaderAdaptor, "GenXSPIRVReaderAdaptor",
"GenXSPIRVReaderAdaptor", false, false)
INITIALIZE_PASS_END(GenXSPIRVReaderAdaptor, "GenXSPIRVReaderAdaptor",
"GenXSPIRVReaderAdaptor", false, false)

ModulePass *llvm::createGenXSPIRVReaderAdaptorPass() {
return new GenXSPIRVReaderAdaptor();
}

void GenXSPIRVReaderAdaptor::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
}

bool GenXSPIRVReaderAdaptor::runOnModule(Module &M) {
auto TargetTriple = StringRef(M.getTargetTriple());
if (TargetTriple.startswith("spir")) {
if (TargetTriple.startswith("spir64"))
M.setTargetTriple("genx64");
else
M.setTargetTriple("genx");
}

for (auto &&GV : M.getGlobalList()) {
if (!GV.hasAttribute(VCModuleMD::VCGlobalVariable))
continue;
if (GV.hasAttribute(VCModuleMD::VCVolatile))
GV.addAttribute(FunctionMD::GenXVolatile);
if (GV.hasAttribute(VCModuleMD::VCByteOffset)) {
auto Offset =
GV.getAttribute(VCModuleMD::VCByteOffset).getValueAsString();
GV.addAttribute(FunctionMD::GenXByteOffset, Offset);
}
}

for (auto &&F : M)
runOnFunction(F);

return true;
}

bool GenXSPIRVReaderAdaptor::runOnFunction(Function &F) {
auto Attrs = F.getAttributes();
if (!Attrs.hasFnAttribute(VCFunctionMD::VCFunction))
return true;

if (Attrs.hasFnAttribute(VCFunctionMD::VCStackCall)) {
F.addFnAttr(FunctionMD::CMStackCall);
F.addFnAttr(Attribute::NoInline);
}

auto &&Context = F.getContext();
if (Attrs.hasFnAttribute(VCFunctionMD::VCFloatControl)) {
auto FloatControl = unsigned(0);
Attrs
.getAttribute(AttributeList::FunctionIndex,
VCFunctionMD::VCFloatControl)
.getValueAsString()
.getAsInteger(0, FloatControl);

auto Attr = Attribute::get(Context, FunctionMD::CMFloatControl,
std::to_string(FloatControl));
F.addAttribute(AttributeList::FunctionIndex, Attr);
}

if (auto *ReqdSubgroupSize =
F.getMetadata(SPIRVParams::SPIRVSIMDSubgroupSize)) {
auto SIMDSize =
mdconst::dyn_extract<ConstantInt>(ReqdSubgroupSize->getOperand(0))
->getZExtValue();
Attribute Attr = Attribute::get(Context, FunctionMD::OCLRuntime,
std::to_string(SIMDSize));
F.addAttribute(AttributeList::FunctionIndex, Attr);
}

if (!(F.getCallingConv() == CallingConv::SPIR_KERNEL))
return true;
F.addFnAttr(FunctionMD::CMGenXMain);
F.setDLLStorageClass(llvm::GlobalVariable::DLLExportStorageClass);

auto *FunctionRef = ValueAsMetadata::get(&F);
auto KernelName = F.getName();
auto ArgKinds = llvm::SmallVector<llvm::Metadata *, 8>();
auto SLMSize = unsigned(0);
auto ArgOffset = unsigned(0);
auto ArgIOKinds = llvm::SmallVector<llvm::Metadata *, 8>();
auto ArgDescs = llvm::SmallVector<llvm::Metadata *, 8>();

llvm::Type *I32Ty = llvm::Type::getInt32Ty(Context);

if (Attrs.hasFnAttribute(VCFunctionMD::VCSLMSize)) {
Attrs.getAttribute(AttributeList::FunctionIndex, VCFunctionMD::VCSLMSize)
.getValueAsString()
.getAsInteger(0, SLMSize);
}

for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
auto ArgNo = I->getArgNo();
auto ArgKind = unsigned(0);
auto ArgIOKind = unsigned(0);
auto ArgDesc = std::string();
if (Attrs.hasAttribute(ArgNo + 1, VCFunctionMD::VCArgumentKind)) {
Attrs.getAttribute(ArgNo + 1, VCFunctionMD::VCArgumentKind)
.getValueAsString()
.getAsInteger(0, ArgKind);
}
if (Attrs.hasAttribute(ArgNo + 1, VCFunctionMD::VCArgumentIOKind)) {
Attrs.getAttribute(ArgNo + 1, VCFunctionMD::VCArgumentIOKind)
.getValueAsString()
.getAsInteger(0, ArgIOKind);
}
if (Attrs.hasAttribute(ArgNo + 1, VCFunctionMD::VCArgumentDesc)) {
ArgDesc = Attrs.getAttribute(ArgNo + 1, VCFunctionMD::VCArgumentDesc)
.getValueAsString()
.str();
}
ArgKinds.push_back(
llvm::ValueAsMetadata::get(llvm::ConstantInt::get(I32Ty, ArgKind)));
ArgIOKinds.push_back(
llvm::ValueAsMetadata::get(llvm::ConstantInt::get(I32Ty, ArgIOKind)));
ArgDescs.push_back(llvm::MDString::get(Context, ArgDesc));
}

auto KernelMD = std::vector<llvm::Metadata *>();
KernelMD.push_back(FunctionRef);
KernelMD.push_back(llvm::MDString::get(Context, KernelName));
KernelMD.push_back(llvm::MDNode::get(Context, ArgKinds));
KernelMD.push_back(ConstantAsMetadata::get(ConstantInt::get(I32Ty, SLMSize)));
KernelMD.push_back(
ConstantAsMetadata::get(ConstantInt::get(I32Ty, ArgOffset)));
KernelMD.push_back(llvm::MDNode::get(Context, ArgIOKinds));
KernelMD.push_back(llvm::MDNode::get(Context, ArgDescs));
KernelMD.push_back(ConstantAsMetadata::get(ConstantInt::get(I32Ty, 0)));

NamedMDNode *KernelMDs =
F.getParent()->getOrInsertNamedMetadata(FunctionMD::GenXKernels);
llvm::MDNode *Node = MDNode::get(F.getContext(), KernelMD);
KernelMDs->addOperand(Node);
return true;
}

0 comments on commit d7c5f99

Please sign in to comment.