Skip to content

Commit 4bfbb34

Browse files
jcranmer-intelFznamznon
authored andcommitted
Add a unified getSPIRVType interface. (#1716)
We have a couple of interfaces that create the custom SPIR-V types. Again, in preparation for an eventual OpaqueType-based interface for types, these functions are being replaced with a more centralized, uniform basis for constructing these types. Some of the related helper methods that were previously used to build the names for struct types are now obsoleted by this change and have been removed. Original commit: KhronosGroup/SPIRV-LLVM-Translator@8784853
1 parent 7abfd91 commit 4bfbb34

11 files changed

+209
-310
lines changed

llvm-spirv/lib/SPIRV/OCLToSPIRV.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,9 +1383,11 @@ void OCLToSPIRVBase::visitCallEnqueueKernel(CallInst *CI,
13831383

13841384
// If no event arguments in original call, add dummy ones
13851385
if (!HasEvents) {
1386-
Args.push_back(getInt32(M, 0)); // dummy num events
1387-
Args.push_back(getOCLNullClkEventPtr(M)); // dummy wait events
1388-
Args.push_back(getOCLNullClkEventPtr(M)); // dummy ret event
1386+
Args.push_back(getInt32(M, 0)); // dummy num events
1387+
Value *Null = Constant::getNullValue(PointerType::get(
1388+
getSPIRVType(OpTypeDeviceEvent, true), SPIRAS_Generic));
1389+
Args.push_back(Null); // dummy wait events
1390+
Args.push_back(Null); // dummy ret event
13891391
}
13901392

13911393
// Invoke: Pointer to invoke function

llvm-spirv/lib/SPIRV/OCLTypeToSPIRV.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ OCLTypeToSPIRVBase &OCLTypeToSPIRVPass::run(llvm::Module &M,
7676
return *this;
7777
}
7878

79-
OCLTypeToSPIRVBase::OCLTypeToSPIRVBase() : M(nullptr), Ctx(nullptr) {}
79+
OCLTypeToSPIRVBase::OCLTypeToSPIRVBase()
80+
: BuiltinCallHelper(ManglingRules::None), M(nullptr), Ctx(nullptr) {}
8081

8182
bool OCLTypeToSPIRVBase::runOCLTypeToSPIRV(Module &Module) {
8283
LLVM_DEBUG(dbgs() << "Enter OCLTypeToSPIRV:\n");
84+
initialize(Module);
8385
M = &Module;
8486
Ctx = &M->getContext();
8587
AdaptedTy.clear();
@@ -179,8 +181,7 @@ void OCLTypeToSPIRVBase::adaptArgumentsBySamplerUse(Module &M) {
179181
AdaptedTy.count(SamplerArg) != 0) // Already traced this, move on.
180182
continue;
181183

182-
addAdaptedType(SamplerArg, TypedPointerType::get(getSamplerStructType(&M),
183-
SPIRAS_Constant));
184+
addAdaptedType(SamplerArg, getSPIRVType(OpTypeSampler));
184185
auto Caller = cast<Argument>(SamplerArg)->getParent();
185186
addWork(Caller);
186187
TraceArg(Caller, cast<Argument>(SamplerArg)->getArgNo());
@@ -224,11 +225,10 @@ void OCLTypeToSPIRVBase::adaptFunctionArguments(Function *F) {
224225
continue;
225226
if (STName.startswith(kSPR2TypeName::ImagePrefix)) {
226227
auto Ty = STName.str();
227-
auto AccStr = getAccessQualifierFullName(Ty);
228-
addAdaptedType(&*Arg, TypedPointerType::get(
229-
getOrCreateOpaqueStructType(
230-
M, mapOCLTypeNameToSPIRV(Ty, AccStr)),
231-
SPIRAS_Global));
228+
auto Acc = getAccessQualifier(Ty);
229+
auto Desc = getImageDescriptor(ParamTys[I]);
230+
addAdaptedType(
231+
&*Arg, getSPIRVType(OpTypeImage, Type::getVoidTy(*Ctx), Desc, Acc));
232232
Changed = true;
233233
}
234234
}
@@ -249,19 +249,19 @@ void OCLTypeToSPIRVBase::adaptArgumentsByMetadata(Function *F) {
249249
for (unsigned I = 0, E = TypeMD->getNumOperands(); I != E; ++I, ++Arg) {
250250
auto OCLTyStr = getMDOperandAsString(TypeMD, I);
251251
if (OCLTyStr == OCL_TYPE_NAME_SAMPLER_T) {
252-
addAdaptedType(&(*Arg), TypedPointerType::get(getSamplerStructType(M),
253-
SPIRAS_Constant));
252+
addAdaptedType(&(*Arg), getSPIRVType(OpTypeSampler));
254253
Changed = true;
255254
} else if (OCLTyStr.startswith("image") && OCLTyStr.endswith("_t")) {
256255
auto Ty = (Twine("opencl.") + OCLTyStr).str();
257-
if (StructType::getTypeByName(F->getContext(), Ty)) {
256+
if (auto *STy = StructType::getTypeByName(F->getContext(), Ty)) {
257+
auto *ImageTy = TypedPointerType::get(STy, SPIRAS_Global);
258+
auto Desc = getImageDescriptor(ImageTy);
258259
auto AccMD = F->getMetadata(SPIR_MD_KERNEL_ARG_ACCESS_QUAL);
259260
assert(AccMD && "Invalid access qualifier metadata");
260-
auto AccStr = getMDOperandAsString(AccMD, I);
261-
addAdaptedType(&(*Arg), TypedPointerType::get(
262-
getOrCreateOpaqueStructType(
263-
M, mapOCLTypeNameToSPIRV(Ty, AccStr)),
264-
SPIRAS_Global));
261+
auto Acc = SPIRSPIRVAccessQualifierMap::map(
262+
getMDOperandAsString(AccMD, I).str());
263+
addAdaptedType(
264+
&*Arg, getSPIRVType(OpTypeImage, Type::getVoidTy(*Ctx), Desc, Acc));
265265
Changed = true;
266266
}
267267
}

llvm-spirv/lib/SPIRV/OCLTypeToSPIRV.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define SPIRV_OCLTYPETOSPIRV_H
4444

4545
#include "LLVMSPIRVLib.h"
46+
#include "SPIRVBuiltinHelper.h"
4647
#include "llvm/IR/Function.h"
4748
#include "llvm/IR/LLVMContext.h"
4849
#include "llvm/IR/PassManager.h"
@@ -53,7 +54,7 @@
5354

5455
namespace SPIRV {
5556

56-
class OCLTypeToSPIRVBase {
57+
class OCLTypeToSPIRVBase : protected BuiltinCallHelper {
5758
public:
5859
OCLTypeToSPIRVBase();
5960

llvm-spirv/lib/SPIRV/OCLUtil.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ unsigned transVecTypeHint(MDNode *Node) {
864864
}
865865

866866
SPIRAddressSpace getOCLOpaqueTypeAddrSpace(Op OpCode) {
867-
switch (OpCode) {
867+
switch ((unsigned)OpCode) {
868868
case OpTypeQueue:
869869
return SPIRV_QUEUE_T_ADDR_SPACE;
870870
case OpTypeEvent:
@@ -878,10 +878,13 @@ SPIRAddressSpace getOCLOpaqueTypeAddrSpace(Op OpCode) {
878878
return SPIRV_PIPE_ADDR_SPACE;
879879
case OpTypeImage:
880880
case OpTypeSampledImage:
881+
case OpTypeVmeImageINTEL:
881882
return SPIRV_IMAGE_ADDR_SPACE;
882883
case OpConstantSampler:
883884
case OpTypeSampler:
884885
return SPIRV_SAMPLER_T_ADDR_SPACE;
886+
case internal::OpTypeJointMatrixINTEL:
887+
return SPIRAS_Global;
885888
default:
886889
if (isSubgroupAvcINTELTypeOpCode(OpCode))
887890
return SPIRV_AVC_INTEL_T_ADDR_SPACE;

llvm-spirv/lib/SPIRV/SPIRVBuiltinHelper.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,17 @@ Type *BuiltinCallHelper::adjustImageType(Type *T, StringRef OldImageKind,
242242
Type *StructTy = TypedPtrTy->getElementType();
243243
// Adapt opencl.* struct type names to spirv.* struct type names.
244244
if (isOCLImageType(T)) {
245+
if (OldImageKind != kSPIRVTypeName::Image)
246+
report_fatal_error("Type was not an image type");
245247
auto ImageTypeName = StructTy->getStructName();
246-
StringRef Acc = kAccessQualName::ReadOnly;
248+
auto Desc =
249+
map<SPIRVTypeImageDescriptor>(getImageBaseTypeName(ImageTypeName));
250+
spv::AccessQualifier Acc = AccessQualifierReadOnly;
247251
if (hasAccessQualifiedName(ImageTypeName))
248-
Acc = getAccessQualifierFullName(ImageTypeName);
249-
StructTy = getOrCreateOpaqueStructType(
250-
M, mapOCLTypeNameToSPIRV(ImageTypeName, Acc));
252+
Acc = getAccessQualifier(ImageTypeName);
253+
auto NewImageType = SPIRVOpaqueTypeOpCodeMap::map(NewImageKind.str());
254+
return getSPIRVType(NewImageType, Type::getVoidTy(M->getContext()), Desc,
255+
Acc);
251256
}
252257

253258
// Change type name (e.g., spirv.Image -> spirv.SampledImg) if necessary.
@@ -263,6 +268,53 @@ Type *BuiltinCallHelper::adjustImageType(Type *T, StringRef OldImageKind,
263268
report_fatal_error("Expected type to be a SPIRV image type");
264269
}
265270

271+
Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode, bool UseRealType) {
272+
return getSPIRVType(TypeOpcode, "", {}, UseRealType);
273+
}
274+
275+
Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
276+
spv::AccessQualifier Access,
277+
bool UseRealType) {
278+
return getSPIRVType(TypeOpcode, "", {(unsigned)Access}, UseRealType);
279+
}
280+
281+
Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode, Type *InnerType,
282+
SPIRVTypeImageDescriptor Desc,
283+
Optional<spv::AccessQualifier> Access,
284+
bool UseRealType) {
285+
return getSPIRVType(TypeOpcode, convertTypeToPostfix(InnerType),
286+
{(unsigned)Desc.Dim, (unsigned)Desc.Depth,
287+
(unsigned)Desc.Arrayed, (unsigned)Desc.MS,
288+
(unsigned)Desc.Sampled, (unsigned)Desc.Format,
289+
(unsigned)Access.value_or(AccessQualifierReadOnly)},
290+
UseRealType);
291+
}
292+
293+
Type *BuiltinCallHelper::getSPIRVType(spv::Op TypeOpcode,
294+
StringRef InnerTypeName,
295+
ArrayRef<unsigned> Parameters,
296+
bool UseRealType) {
297+
std::string FullName;
298+
{
299+
raw_string_ostream OS(FullName);
300+
OS << kSPIRVTypeName::PrefixAndDelim
301+
<< SPIRVOpaqueTypeOpCodeMap::rmap(TypeOpcode);
302+
if (!InnerTypeName.empty() || !Parameters.empty())
303+
OS << kSPIRVTypeName::Delimiter;
304+
if (!InnerTypeName.empty())
305+
OS << kSPIRVTypeName::PostfixDelim << InnerTypeName;
306+
for (unsigned IntParam : Parameters)
307+
OS << kSPIRVTypeName::PostfixDelim << IntParam;
308+
}
309+
auto *STy = StructType::getTypeByName(M->getContext(), FullName);
310+
if (!STy)
311+
STy = StructType::create(M->getContext(), FullName);
312+
313+
unsigned AddrSpace = getOCLOpaqueTypeAddrSpace(TypeOpcode);
314+
return UseRealType ? (Type *)PointerType::get(STy, AddrSpace)
315+
: TypedPointerType::get(STy, AddrSpace);
316+
}
317+
266318
BuiltinCallMutator::ValueTypePair
267319
BuiltinCallHelper::getCallValue(CallInst *CI, unsigned ArgNo) {
268320
Function *CalledFunc = CI->getCalledFunction();

llvm-spirv/lib/SPIRV/SPIRVBuiltinHelper.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
#include "LLVMSPIRVLib.h"
4444
#include "libSPIRV/SPIRVOpCode.h"
45+
#include "libSPIRV/SPIRVType.h"
46+
#include "llvm/ADT/Optional.h"
4547
#include "llvm/ADT/SmallVector.h"
4648
#include "llvm/IR/Attributes.h"
4749
#include "llvm/IR/IRBuilder.h"
@@ -310,6 +312,40 @@ class BuiltinCallHelper {
310312
llvm::Type *adjustImageType(llvm::Type *T, llvm::StringRef OldImageKind,
311313
llvm::StringRef NewImageKind);
312314

315+
/// Create a new type representing a SPIR-V opaque type that takes no
316+
/// parameters (such as sampler types).
317+
///
318+
/// If UseRealType is false, a typed pointer type may be returned; if it is
319+
/// true, a pointer type will be used instead.
320+
llvm::Type *getSPIRVType(spv::Op TypeOpcode, bool UseRealType = false);
321+
322+
/// Create a new type representing a SPIR-V opaque type that takes only an
323+
/// access qualifier (such as pipe types).
324+
///
325+
/// If UseRealType is false, a typed pointer type may be returned; if it is
326+
/// true, a pointer type will be used instead.
327+
llvm::Type *getSPIRVType(spv::Op TypeOpcode, spv::AccessQualifier Access,
328+
bool UseRealType = false);
329+
330+
/// Create a new type representing a SPIR-V opaque type that is an image type
331+
/// of some kind.
332+
///
333+
/// If UseRealType is false, a typed pointer type may be returned; if it is
334+
/// true, a pointer type will be used instead.
335+
llvm::Type *getSPIRVType(spv::Op TypeOpcode, llvm::Type *InnerType,
336+
SPIRVTypeImageDescriptor Desc,
337+
llvm::Optional<spv::AccessQualifier> Access,
338+
bool UseRealType = false);
339+
340+
/// Create a new type representing a SPIR-V opaque type that takes arbitrary
341+
/// parameters.
342+
///
343+
/// If UseRealType is false, a typed pointer type may be returned; if it is
344+
/// true, a pointer type will be used instead.
345+
llvm::Type *getSPIRVType(spv::Op TypeOpcode, llvm::StringRef InnerTypeName,
346+
llvm::ArrayRef<unsigned> Parameters,
347+
bool UseRealType = false);
348+
313349
private:
314350
llvm::SmallVector<llvm::Type *, 4> CachedParameterTypes;
315351
llvm::Function *CachedFunc = nullptr;

llvm-spirv/lib/SPIRV/SPIRVInternal.h

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,6 @@ bool isSupportedTriple(Triple T);
560560
void removeFnAttr(CallInst *Call, Attribute::AttrKind Attr);
561561
void addFnAttr(CallInst *Call, Attribute::AttrKind Attr);
562562
void saveLLVMModule(Module *M, const std::string &OutputFile);
563-
std::string mapSPIRVTypeToOCLType(SPIRVType *Ty, bool Signed);
564563
std::string mapLLVMTypeToOCLType(const Type *Ty, bool Signed,
565564
Type *PointerElementType = nullptr);
566565
SPIRVDecorate *mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target);
@@ -570,12 +569,7 @@ SPIRVDecorate *mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target);
570569
SPIRVValue *addDecorations(SPIRVValue *Target,
571570
const SmallVectorImpl<std::string> &Decs);
572571

573-
PointerType *getOrCreateOpaquePtrType(Module *M, const std::string &Name,
574-
unsigned AddrSpace = SPIRAS_Global);
575572
StructType *getOrCreateOpaqueStructType(Module *M, StringRef Name);
576-
PointerType *getSamplerType(Module *M);
577-
Type *getSamplerStructType(Module *M);
578-
PointerType *getSPIRVOpaquePtrType(Module *M, Op OC);
579573
void getFunctionTypeParameterTypes(llvm::FunctionType *FT,
580574
std::vector<Type *> &ArgTys);
581575
Function *getOrCreateFunction(Module *M, Type *RetTy, ArrayRef<Type *> ArgTypes,
@@ -584,10 +578,6 @@ Function *getOrCreateFunction(Module *M, Type *RetTy, ArrayRef<Type *> ArgTypes,
584578
AttributeList *Attrs = nullptr,
585579
bool TakeName = true);
586580

587-
PointerType *getOCLClkEventType(Module *M);
588-
PointerType *getOCLClkEventPtrType(Module *M);
589-
Constant *getOCLNullClkEventPtr(Module *M);
590-
591581
/// Get function call arguments.
592582
/// \param Start Starting index.
593583
/// \param End Ending index.
@@ -736,11 +726,6 @@ CallInst *addCallInstSPIRV(Module *M, StringRef FuncName, Type *RetTy,
736726
ArrayRef<Type *> PointerElementTypes,
737727
Instruction *Pos, StringRef InstName);
738728

739-
/// Add a call of spir_block_bind function.
740-
CallInst *addBlockBind(Module *M, Function *InvokeFunc, Value *BlkCtx,
741-
Value *CtxLen, Value *CtxAlign, Instruction *InsPos,
742-
StringRef InstName = SPIR_TEMP_NAME_PREFIX_BLOCK);
743-
744729
typedef std::pair<std::vector<Value *>::iterator,
745730
std::vector<Value *>::iterator>
746731
ValueVecRange;
@@ -858,11 +843,6 @@ std::string getSPIRVTypeName(StringRef BaseTyName, StringRef Postfixes = "");
858843
/// Checks if given type name is either ConstantSampler or ConsantPipeStorage.
859844
bool isSPIRVConstantName(StringRef TyName);
860845

861-
/// Get the postfixes of SPIR-V image type name as in spirv.Image.postfixes.
862-
std::string getSPIRVImageTypePostfixes(StringRef SampledType,
863-
SPIRVTypeImageDescriptor Desc,
864-
SPIRVAccessQualifierKind Acc);
865-
866846
/// Get the sampled type name used in postfix of image type in SPIR-V
867847
/// friendly LLVM IR.
868848
std::string getSPIRVImageSampledTypeName(SPIRVType *Ty);
@@ -871,16 +851,16 @@ std::string getSPIRVImageSampledTypeName(SPIRVType *Ty);
871851
Type *getLLVMTypeForSPIRVImageSampledTypePostfix(StringRef Postfix,
872852
LLVMContext &Ctx);
873853

854+
/// Convert an LLVM type to a string postfix name.
855+
std::string convertTypeToPostfix(Type *T);
856+
874857
/// Return the unqualified and unsuffixed base name of an image type.
875858
/// E.g. opencl.image2d_ro_t.3 -> image2d_t
876859
std::string getImageBaseTypeName(StringRef Name);
877860

878861
/// Extract the image type descriptor from the given image type.
879862
SPIRVTypeImageDescriptor getImageDescriptor(Type *Ty);
880863

881-
/// Map OpenCL opaque type name to SPIR-V type name.
882-
std::string mapOCLTypeNameToSPIRV(StringRef Name, StringRef Acc = "");
883-
884864
/// Check if access qualifier is encoded in the type name.
885865
bool hasAccessQualifiedName(StringRef TyName);
886866

@@ -890,9 +870,6 @@ SPIRVAccessQualifierKind getAccessQualifier(StringRef TyName);
890870
/// Get access qualifier from the type name.
891871
StringRef getAccessQualifierPostfix(SPIRVAccessQualifierKind Access);
892872

893-
/// Get access qualifier from the type name.
894-
StringRef getAccessQualifierFullName(StringRef TyName);
895-
896873
bool eraseUselessFunctions(Module *M);
897874

898875
/// Erase a function if it is declaration, has internal linkage and has no use.
@@ -978,6 +955,7 @@ template <> inline void SPIRVMap<std::string, Op, SPIRVOpaqueType>::init() {
978955
_SPIRV_OP(ReserveId)
979956
_SPIRV_OP(Sampler)
980957
_SPIRV_OP(SampledImage)
958+
_SPIRV_OP(PipeStorage)
981959
// SPV_INTEL_device_side_avc_motion_estimation types
982960
_SPIRV_OP(AvcMcePayloadINTEL)
983961
_SPIRV_OP(AvcImePayloadINTEL)
@@ -991,7 +969,9 @@ template <> inline void SPIRVMap<std::string, Op, SPIRVOpaqueType>::init() {
991969
_SPIRV_OP(AvcImeDualReferenceStreaminINTEL)
992970
_SPIRV_OP(AvcRefResultINTEL)
993971
_SPIRV_OP(AvcSicResultINTEL)
972+
_SPIRV_OP(VmeImageINTEL)
994973
#undef _SPIRV_OP
974+
add("JointMatrixINTEL", internal::OpTypeJointMatrixINTEL);
995975
}
996976

997977
// Check if the module contains llvm.loop.* metadata

0 commit comments

Comments
 (0)