Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions include/LLVMSPIRVExtensions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ EXT(SPV_INTEL_io_pipes)
EXT(SPV_INTEL_inline_assembly)
EXT(SPV_INTEL_arbitrary_precision_integers)
EXT(SPV_INTEL_optimization_hints)
EXT(SPV_INTEL_float_controls2)
EXT(SPV_INTEL_vector_compute)
1 change: 1 addition & 0 deletions lib/SPIRV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_llvm_library(LLVMSPIRVLib
OCL21ToSPIRV.cpp
OCLTypeToSPIRV.cpp
OCLUtil.cpp
VectorComputeUtil.cpp
SPIRVLowerBool.cpp
SPIRVLowerConstExpr.cpp
SPIRVLowerMemmove.cpp
Expand Down
53 changes: 53 additions & 0 deletions lib/SPIRV/PreprocessMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "SPIRVInternal.h"
#include "SPIRVMDBuilder.h"
#include "SPIRVMDWalker.h"
#include "VectorComputeUtil.h"

#include "llvm/ADT/Triple.h"
#include "llvm/IR/IRBuilder.h"
Expand Down Expand Up @@ -69,6 +70,8 @@ class PreprocessMetadata : public ModulePass {
bool runOnModule(Module &M) override;
void visit(Module *M);
void preprocessOCLMetadata(Module *M, SPIRVMDBuilder *B, SPIRVMDWalker *W);
void preprocessVectorComputeMetadata(Module *M, SPIRVMDBuilder *B,
SPIRVMDWalker *W);

static char ID;

Expand Down Expand Up @@ -100,6 +103,7 @@ void PreprocessMetadata::visit(Module *M) {
SPIRVMDWalker W(*M);

preprocessOCLMetadata(M, &B, &W);
preprocessVectorComputeMetadata(M, &B, &W);

// Create metadata representing (empty so far) list
// of OpExecutionMode instructions
Expand Down Expand Up @@ -243,6 +247,55 @@ void PreprocessMetadata::preprocessOCLMetadata(Module *M, SPIRVMDBuilder *B,
B->eraseNamedMD(kSPIR2MD::FPContract);
}

void PreprocessMetadata::preprocessVectorComputeMetadata(Module *M,
SPIRVMDBuilder *B,
SPIRVMDWalker *W) {
using namespace VectorComputeUtil;

auto EM = B->addNamedMD(kSPIRVMD::ExecutionMode);

for (auto &F : *M) {
// Add VC float control execution modes
// RoundMode and FloatMode are always same for all types in VC
// While Denorm could be different for double, float and half
auto Attrs = F.getAttributes();
if (Attrs.hasFnAttribute(kVCMetadata::VCFloatControl)) {
SPIRVWord Mode = 0;
Attrs
.getAttribute(AttributeList::FunctionIndex,
kVCMetadata::VCFloatControl)
.getValueAsString()
.getAsInteger(0, Mode);
spv::ExecutionMode ExecRoundMode =
VCRoundModeExecModeMap::map(getVCRoundMode(Mode));
spv::ExecutionMode ExecFloatMode =
VCFloatModeExecModeMap::map(getVCFloatMode(Mode));
VCFloatTypeSizeMap::foreach (
[&](VCFloatType FloatType, unsigned TargetWidth) {
EM.addOp().add(&F).add(ExecRoundMode).add(TargetWidth).done();
EM.addOp().add(&F).add(ExecFloatMode).add(TargetWidth).done();
EM.addOp()
.add(&F)
.add(VCDenormModeExecModeMap::map(
getVCDenormPreserve(Mode, FloatType)))
.add(TargetWidth)
.done();
});
}
if (Attrs.hasFnAttribute(kVCMetadata::VCSLMSize)) {
SPIRVWord SLMSize = 0;
Attrs.getAttribute(AttributeList::FunctionIndex, kVCMetadata::VCSLMSize)
.getValueAsString()
.getAsInteger(0, SLMSize);
EM.addOp()
.add(&F)
.add(spv::ExecutionModeSharedLocalMemorySizeINTEL)
.add(SLMSize)
.done();
}
}
}

} // namespace SPIRV

INITIALIZE_PASS(PreprocessMetadata, "preprocess-metadata",
Expand Down
97 changes: 93 additions & 4 deletions lib/SPIRV/SPIRVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "SPIRVType.h"
#include "SPIRVUtil.h"
#include "SPIRVValue.h"
#include "VectorComputeUtil.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/Analysis/LoopInfo.h"
Expand Down Expand Up @@ -108,7 +109,7 @@ const static char *Restrict = "restrict";
const static char *Pipe = "pipe";
} // namespace kOCLTypeQualifierName

static bool isOpenCLKernel(SPIRVFunction *BF) {
static bool isKernel(SPIRVFunction *BF) {
return BF->getModule()->isEntryPoint(ExecutionModelKernel, BF->getId());
}

Expand Down Expand Up @@ -1530,14 +1531,34 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
assert(BB && "Invalid BB");
return mapValue(BV, new AllocaInst(Ty, 0, BV->getName(), BB));
}
auto AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS);
SPIRAddressSpace AddrSpace;

bool IsVectorCompute =
BVar->hasDecorate(DecorationVectorComputeVariableINTEL);
if (IsVectorCompute) {
AddrSpace = VectorComputeUtil::getVCGlobalVarAddressSpace(BS);
if (!Initializer)
Initializer = UndefValue::get(Ty);
} else
AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS);

auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy, Initializer,
BV->getName(), 0,
GlobalVariable::NotThreadLocal, AddrSpace);
LVar->setUnnamedAddr((IsConst && Ty->isArrayTy() &&
Ty->getArrayElementType()->isIntegerTy(8))
? GlobalValue::UnnamedAddr::Global
: GlobalValue::UnnamedAddr::None);

if (IsVectorCompute) {
LVar->addAttribute(kVCMetadata::VCGlobalVariable);
SPIRVWord Offset;
if (BVar->hasDecorate(DecorationGlobalVariableOffsetINTEL, 0, &Offset))
LVar->addAttribute(kVCMetadata::VCByteOffset, utostr(Offset));
if (BVar->hasDecorate(DecorationVolatile))
LVar->addAttribute(kVCMetadata::VCVolatile);
}

SPIRVBuiltinVariableKind BVKind;
if (BVar->isBuiltin(&BVKind))
BuiltinGVMap[LVar] = BVKind;
Expand Down Expand Up @@ -2403,7 +2424,7 @@ Function *SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
if (Loc != FuncMap.end())
return Loc->second;

auto IsKernel = BM->isEntryPoint(ExecutionModelKernel, BF->getId());
auto IsKernel = isKernel(BF);
auto Linkage = IsKernel ? GlobalValue::ExternalLinkage : transLinkageType(BF);
FunctionType *FT = dyn_cast<FunctionType>(transType(BF->getFunctionType()));
Function *F = cast<Function>(
Expand Down Expand Up @@ -3217,7 +3238,7 @@ bool SPIRVToLLVM::transFPContractMetadata() {
bool ContractOff = false;
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
SPIRVFunction *BF = BM->getFunction(I);
if (!isOpenCLKernel(BF))
if (!isKernel(BF))
continue;
if (BF->getExecutionMode(ExecutionModeContractionOff)) {
ContractOff = true;
Expand Down Expand Up @@ -3295,6 +3316,7 @@ bool SPIRVToLLVM::transMetadata() {
assert(F && "Invalid translated function");

transOCLMetadata(BF);
transVectorComputeMetadata(BF);

if (F->getCallingConv() != CallingConv::SPIR_KERNEL)
continue;
Expand Down Expand Up @@ -3435,6 +3457,73 @@ bool SPIRVToLLVM::transOCLMetadata(SPIRVFunction *BF) {
return true;
}

bool SPIRVToLLVM::transVectorComputeMetadata(SPIRVFunction *BF) {
using namespace VectorComputeUtil;
Function *F = static_cast<Function *>(getTranslatedValue(BF));
assert(F && "Invalid translated function");

if (BF->hasDecorate(DecorationStackCallINTEL))
F->addFnAttr(kVCMetadata::VCStackCall);

bool IsVectorCompute = BF->hasDecorate(DecorationVectorComputeFunctionINTEL);
if (!IsVectorCompute)
return true;
F->addFnAttr(kVCMetadata::VCFunction);

for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
++I) {
auto ArgNo = I->getArgNo();
SPIRVFunctionParameter *BA = BF->getArgument(ArgNo);
SPIRVWord Kind;
if (BA->hasDecorate(DecorationFuncParamIOKind, 0, &Kind)) {
Attribute Attr = Attribute::get(*Context, kVCMetadata::VCArgumentIOKind,
std::to_string(Kind));
F->addAttribute(ArgNo + 1, Attr);
}
}

// Do not add float control if there is no any
bool IsVCFloatControl = false;
unsigned FloatControl = 0;
// RoundMode and FloatMode are always same for all types in Cm
// While Denorm could be different for double, float and half
VCRoundModeExecModeMap::foreach ([&](VCRoundMode VCRM, ExecutionMode EM) {
if (BF->getExecutionMode(EM)) {
IsVCFloatControl = true;
FloatControl |= getVCFloatControl(VCRM);
}
});
VCFloatModeExecModeMap::foreach ([&](VCFloatMode VCFM, ExecutionMode EM) {
if (BF->getExecutionMode(EM)) {
IsVCFloatControl = true;
FloatControl |= getVCFloatControl(VCFM);
}
});
VCDenormModeExecModeMap::foreach ([&](VCDenormMode VCDM, ExecutionMode EM) {
auto ExecModes = BF->getExecutionModeRange(EM);
for (auto It = ExecModes.first; It != ExecModes.second; It++) {
IsVCFloatControl = true;
unsigned TargetWidth = (*It).second->getLiterals()[0];
VCFloatType FloatType = VCFloatTypeSizeMap::rmap(TargetWidth);
FloatControl |= getVCFloatControl(VCDM, FloatType);
}
});
if (IsVCFloatControl) {
Attribute Attr = Attribute::get(*Context, kVCMetadata::VCFloatControl,
std::to_string(FloatControl));
F->addAttribute(AttributeList::FunctionIndex, Attr);
}

if (auto EM = BF->getExecutionMode(ExecutionModeSharedLocalMemorySizeINTEL)) {
unsigned int SLMSize = EM->getLiterals()[0];
Attribute Attr = Attribute::get(*Context, kVCMetadata::VCSLMSize,
std::to_string(SLMSize));
F->addAttribute(AttributeList::FunctionIndex, Attr);
}

return true;
}

bool SPIRVToLLVM::transAlign(SPIRVValue *BV, Value *V) {
if (auto AL = dyn_cast<AllocaInst>(V)) {
SPIRVWord Align = 0;
Expand Down
1 change: 1 addition & 0 deletions lib/SPIRV/SPIRVReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class SPIRVToLLVM {
bool transFPContractMetadata();
bool transMetadata();
bool transOCLMetadata(SPIRVFunction *BF);
bool transVectorComputeMetadata(SPIRVFunction *BF);
Value *transAsmINTEL(SPIRVAsmINTEL *BA);
CallInst *transAsmCallINTEL(SPIRVAsmCallINTEL *BI, Function *F,
BasicBlock *BB);
Expand Down
Loading