Skip to content

Commit 0eb9a7d

Browse files
[OpaquePtr] Pass pointer type information into mangleBuiltin. (#1549)
This includes a rejigging of the BuiltinFuncMangleInfo to actually act as the source of information to pass this information into. Only some of the call sites of mangleBuiltin have been properly updated to pass in the pointer type element information. The various mutateCallInst* callers have yet to be updated, so those methods are temporarily relying on querying getPointerElementType() to generate this information.
1 parent 6904b38 commit 0eb9a7d

File tree

9 files changed

+256
-99
lines changed

9 files changed

+256
-99
lines changed

include/LLVMSPIRVLib.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ std::unique_ptr<SPIRVModule> readSpirvModule(std::istream &IS,
106106
const SPIRV::TranslatorOpts &Opts,
107107
std::string &ErrMsg);
108108

109+
/// This contains a pair of the pointer element type and an indirection
110+
/// parameter (to capture cases where an array of OpenCL types is used).
111+
typedef llvm::PointerIntPair<llvm::Type *, 1, bool> PointerIndirectPair;
112+
109113
} // End namespace SPIRV
110114

111115
namespace llvm {
@@ -156,8 +160,13 @@ bool regularizeLlvmForSpirv(Module *M, std::string &ErrMsg,
156160
const SPIRV::TranslatorOpts &Opts);
157161

158162
/// \brief Mangle OpenCL builtin function function name.
163+
/// If any type in ArgTypes is a pointer type, the corresponding entry in
164+
/// ArgPointerTypes should contain the type should point to. If there are no
165+
/// pointer-typed arguments in ArgTypes, then ArgPointerTypes may be empty.
159166
void mangleOpenClBuiltin(const std::string &UnmangledName,
160-
ArrayRef<Type *> ArgTypes, std::string &MangledName);
167+
ArrayRef<Type *> ArgTypes,
168+
ArrayRef<SPIRV::PointerIndirectPair> ArgPointerTypes,
169+
std::string &MangledName);
161170

162171
/// Create a pass for translating LLVM to SPIR-V.
163172
ModulePass *createLLVMToSPIRVLegacy(SPIRV::SPIRVModule *);

lib/SPIRV/OCLToSPIRV.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,8 @@ void OCLToSPIRVBase::visitCallReadImageWithSampler(CallInst *CI,
10091009
Value *SampledImgArgs[] = {Args[0], Args[1]};
10101010
auto SampledImg = addCallInstSPIRV(
10111011
M, getSPIRVFuncName(OpSampledImage), SampledImgTy, SampledImgArgs,
1012-
nullptr, CI, kSPIRVName::TempSampledImage);
1012+
nullptr, {ArgStructTys[0], ArgStructTys[1]}, CI,
1013+
kSPIRVName::TempSampledImage);
10131014

10141015
Args[0] = SampledImg;
10151016
Args.erase(Args.begin() + 1, Args.begin() + 2);
@@ -1645,13 +1646,16 @@ void OCLToSPIRVBase::visitSubgroupAVCWrapperBuiltinCall(
16451646
getSubgroupAVCIntelTyKind(CI->getCalledFunction()->getName());
16461647
std::string MCETName =
16471648
std::string(kOCLSubgroupsAVCIntel::TypePrefix) + "mce_" + TyKind + "_t";
1648-
auto *MCETy =
1649-
PointerType::get(getSubgroupAVCIntelMCEType(M, MCETName), SPIRAS_Private);
1649+
auto *MCESTy = getSubgroupAVCIntelMCEType(M, MCETName);
1650+
auto *MCETy = PointerType::get(MCESTy, SPIRAS_Private);
16501651
std::string ToMCEFName = Prefix + OpKind + "_convert_to_mce_" + TyKind;
16511652
Op ToMCEOC = OpNop;
16521653
OCLSPIRVSubgroupAVCIntelBuiltinMap::find(ToMCEFName, &ToMCEOC);
16531654
assert(ToMCEOC != OpNop && "Invalid Subgroup AVC Intel built-in call");
16541655

1656+
SmallVector<StructType *, 2> ParamTys;
1657+
getParameterTypes(CI, ParamTys);
1658+
16551659
if (std::strcmp(TyKind, "payload") == 0) {
16561660
// Wrapper built-ins which take the 'payload_t' argument return it as
16571661
// the result: two conversion calls required.
@@ -1666,16 +1670,16 @@ void OCLToSPIRVBase::visitSubgroupAVCWrapperBuiltinCall(
16661670
[=](CallInst *, std::vector<Value *> &Args, Type *&Ret) {
16671671
Ret = MCETy;
16681672
// Create conversion function call for the last operand
1669-
Args[Args.size() - 1] =
1670-
addCallInstSPIRV(M, getSPIRVFuncName(ToMCEOC), MCETy,
1671-
Args[Args.size() - 1], nullptr, CI, "");
1673+
Args[Args.size() - 1] = addCallInstSPIRV(
1674+
M, getSPIRVFuncName(ToMCEOC), MCETy, Args[Args.size() - 1],
1675+
nullptr, {ParamTys[Args.size() - 1]}, CI, "");
16721676

16731677
return getSPIRVFuncName(WrappedOC);
16741678
},
16751679
[=](CallInst *NewCI) -> Instruction * {
16761680
// Create conversion function call for the return result
16771681
return addCallInstSPIRV(M, getSPIRVFuncName(FromMCEOC), CI->getType(),
1678-
NewCI, nullptr, CI, "");
1682+
NewCI, nullptr, {MCESTy}, CI, "");
16791683
},
16801684
&Attrs);
16811685
} else {
@@ -1686,9 +1690,9 @@ void OCLToSPIRVBase::visitSubgroupAVCWrapperBuiltinCall(
16861690
[=](CallInst *, std::vector<Value *> &Args) {
16871691
// Create conversion function call for the last
16881692
// operand
1689-
Args[Args.size() - 1] =
1690-
addCallInstSPIRV(M, getSPIRVFuncName(ToMCEOC), MCETy,
1691-
Args[Args.size() - 1], nullptr, CI, "");
1693+
Args[Args.size() - 1] = addCallInstSPIRV(
1694+
M, getSPIRVFuncName(ToMCEOC), MCETy, Args[Args.size() - 1],
1695+
nullptr, {ParamTys[Args.size() - 1]}, CI, "");
16921696

16931697
return getSPIRVFuncName(WrappedOC);
16941698
},
@@ -1726,6 +1730,7 @@ void OCLToSPIRVBase::visitSubgroupAVCBuiltinCallWithSampler(
17261730
"Invalid Subgroup AVC Intel built-in call");
17271731
auto SamplerIt = Args.begin() + (TyIt - ParamTys.begin());
17281732
auto *SamplerVal = *SamplerIt;
1733+
auto *SamplerTy = *TyIt;
17291734
Args.erase(SamplerIt);
17301735
ParamTys.erase(TyIt);
17311736

@@ -1745,7 +1750,8 @@ void OCLToSPIRVBase::visitSubgroupAVCBuiltinCallWithSampler(
17451750

17461751
Value *SampledImgArgs[] = {Args[I], SamplerVal};
17471752
Args[I] = addCallInstSPIRV(M, getSPIRVFuncName(OpVmeImageINTEL),
1748-
SampledImgTy, SampledImgArgs, nullptr, CI,
1753+
SampledImgTy, SampledImgArgs, nullptr,
1754+
{ParamTys[I], SamplerTy}, CI,
17491755
kSPIRVName::TempSampledImage);
17501756
}
17511757
return getSPIRVFuncName(OC);

lib/SPIRV/OCLUtil.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,9 +1154,11 @@ class OCLBuiltinFuncMangleInfo : public SPIRV::BuiltinFuncMangleInfo {
11541154
} else if (NameRef.startswith("vstore")) {
11551155
addUnsignedArg(1);
11561156
} else if (NameRef.startswith("ndrange_")) {
1157-
addUnsignedArg(-1);
1157+
addUnsignedArgs(0, 2);
11581158
if (NameRef[8] == '2' || NameRef[8] == '3') {
1159-
setArgAttr(-1, SPIR::ATTR_CONST);
1159+
setArgAttr(0, SPIR::ATTR_CONST);
1160+
setArgAttr(1, SPIR::ATTR_CONST);
1161+
setArgAttr(2, SPIR::ATTR_CONST);
11601162
}
11611163
} else if (NameRef.contains("umax")) {
11621164
addUnsignedArg(-1);
@@ -1602,7 +1604,9 @@ Value *SPIRV::transSPIRVMemorySemanticsIntoOCLMemFenceFlags(
16021604

16031605
void llvm::mangleOpenClBuiltin(const std::string &UniqName,
16041606
ArrayRef<Type *> ArgTypes,
1607+
ArrayRef<PointerIndirectPair> PointerElementTys,
16051608
std::string &MangledName) {
16061609
OCLUtil::OCLBuiltinFuncMangleInfo BtnInfo(ArgTypes);
1610+
BtnInfo.fillPointerElementTypes(PointerElementTys);
16071611
MangledName = SPIRV::mangleBuiltin(UniqName, ArgTypes, &BtnInfo);
16081612
}

lib/SPIRV/SPIRVInternal.h

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,11 @@ struct BuiltinArgTypeMangleInfo {
457457
bool IsLocalArgBlock;
458458
SPIR::TypePrimitiveEnum Enum;
459459
unsigned Attr;
460+
PointerIndirectPair PointerElementType;
460461
BuiltinArgTypeMangleInfo()
461462
: IsSigned(true), IsVoidPtr(false), IsEnum(false), IsSampler(false),
462463
IsAtomic(false), IsLocalArgBlock(false), Enum(SPIR::PRIMITIVE_NONE),
463-
Attr(0) {}
464+
Attr(0), PointerElementType(nullptr, false) {}
464465
};
465466

466467
/// Information for mangling builtin function.
@@ -469,92 +470,61 @@ class BuiltinFuncMangleInfo {
469470
/// Translate builtin function name and set
470471
/// argument attributes and unsigned args.
471472
BuiltinFuncMangleInfo(const std::string &UniqName = "")
472-
: LocalArgBlockIdx(-1), VarArgIdx(-1), DontMangle(false) {
473+
: VarArgIdx(-1), DontMangle(false) {
473474
if (!UniqName.empty())
474475
init(UniqName);
475476
}
476477
virtual ~BuiltinFuncMangleInfo() {}
477478
const std::string &getUnmangledName() const { return UnmangledName; }
478-
void addUnsignedArg(int Ndx) { UnsignedArgs.insert(Ndx); }
479+
void addUnsignedArg(int Ndx) {
480+
if (Ndx == -1)
481+
return addUnsignedArgs(0, 10); // 10 is enough for everybody, right?
482+
getTypeMangleInfo(Ndx).IsSigned = false;
483+
}
479484
void addUnsignedArgs(int StartNdx, int StopNdx) {
480485
assert(StartNdx < StopNdx && "wrong parameters");
481486
for (int I = StartNdx; I <= StopNdx; ++I)
482487
addUnsignedArg(I);
483488
}
484-
void addVoidPtrArg(int Ndx) { VoidPtrArgs.insert(Ndx); }
485-
void addSamplerArg(int Ndx) { SamplerArgs.insert(Ndx); }
486-
void addAtomicArg(int Ndx) { AtomicArgs.insert(Ndx); }
487-
void setLocalArgBlock(int Ndx) {
488-
assert(0 <= Ndx && "it is not allowed to set less than zero index");
489-
LocalArgBlockIdx = Ndx;
489+
void addVoidPtrArg(unsigned Ndx) { getTypeMangleInfo(Ndx).IsVoidPtr = true; }
490+
void addSamplerArg(unsigned Ndx) { getTypeMangleInfo(Ndx).IsSampler = true; }
491+
void addAtomicArg(unsigned Ndx) { getTypeMangleInfo(Ndx).IsAtomic = true; }
492+
void setLocalArgBlock(unsigned Ndx) {
493+
getTypeMangleInfo(Ndx).IsLocalArgBlock = true;
490494
}
491-
void setEnumArg(int Ndx, SPIR::TypePrimitiveEnum Enum) {
492-
EnumArgs[Ndx] = Enum;
495+
void setEnumArg(unsigned Ndx, SPIR::TypePrimitiveEnum Enum) {
496+
auto &Info = getTypeMangleInfo(Ndx);
497+
Info.IsEnum = true;
498+
Info.Enum = Enum;
499+
}
500+
void setArgAttr(unsigned Ndx, unsigned Attr) {
501+
getTypeMangleInfo(Ndx).Attr = Attr;
493502
}
494-
void setArgAttr(int Ndx, unsigned Attr) { Attrs[Ndx] = Attr; }
495503
void setVarArg(int Ndx) {
496504
assert(0 <= Ndx && "it is not allowed to set less than zero index");
497505
VarArgIdx = Ndx;
498506
}
499507
void setAsDontMangle() { DontMangle = true; }
500-
bool isArgUnsigned(int Ndx) {
501-
return UnsignedArgs.count(-1) || UnsignedArgs.count(Ndx);
502-
}
503-
bool isArgVoidPtr(int Ndx) {
504-
return VoidPtrArgs.count(-1) || VoidPtrArgs.count(Ndx);
505-
}
506-
bool isArgSampler(int Ndx) { return SamplerArgs.count(Ndx); }
507-
bool isArgAtomic(int Ndx) { return AtomicArgs.count(Ndx); }
508-
bool isLocalArgBlock(int Ndx) { return LocalArgBlockIdx == Ndx; }
509-
bool isArgEnum(int Ndx, SPIR::TypePrimitiveEnum *Enum = nullptr) {
510-
auto Loc = EnumArgs.find(Ndx);
511-
if (Loc == EnumArgs.end())
512-
Loc = EnumArgs.find(-1);
513-
if (Loc == EnumArgs.end())
514-
return false;
515-
if (Enum)
516-
*Enum = Loc->second;
517-
return true;
518-
}
519508
bool avoidMangling() { return DontMangle; }
520-
unsigned getArgAttr(int Ndx) {
521-
auto Loc = Attrs.find(Ndx);
522-
if (Loc == Attrs.end())
523-
Loc = Attrs.find(-1);
524-
if (Loc == Attrs.end())
525-
return 0;
526-
return Loc->second;
527-
}
528509
// get ellipsis index, single ellipsis at the end of the function is possible
529510
// only return value < 0 if none
530511
int getVarArg() const { return VarArgIdx; }
531-
BuiltinArgTypeMangleInfo getTypeMangleInfo(int Ndx) {
532-
BuiltinArgTypeMangleInfo Info;
533-
Info.IsSigned = !isArgUnsigned(Ndx);
534-
Info.IsVoidPtr = isArgVoidPtr(Ndx);
535-
Info.IsEnum = isArgEnum(Ndx, &Info.Enum);
536-
Info.IsSampler = isArgSampler(Ndx);
537-
Info.IsAtomic = isArgAtomic(Ndx);
538-
Info.IsLocalArgBlock = isLocalArgBlock(Ndx);
539-
Info.Attr = getArgAttr(Ndx);
512+
BuiltinArgTypeMangleInfo &getTypeMangleInfo(unsigned Ndx) {
513+
while (Ndx >= ArgInfo.size())
514+
ArgInfo.emplace_back();
515+
BuiltinArgTypeMangleInfo &Info = ArgInfo[Ndx];
540516
return Info;
541517
}
542518
virtual void init(StringRef UniqUnmangledName) {
543519
UnmangledName = UniqUnmangledName.str();
544520
}
545521

522+
void fillPointerElementTypes(ArrayRef<PointerIndirectPair>);
523+
546524
protected:
547525
std::string UnmangledName;
548-
std::set<int> UnsignedArgs; // unsigned arguments, or -1 if all are unsigned
549-
std::set<int> VoidPtrArgs; // void pointer arguments, or -1 if all are void
550-
// pointer
551-
std::set<int> SamplerArgs; // sampler arguments
552-
std::set<int> AtomicArgs; // atomic arguments
553-
std::map<int, SPIR::TypePrimitiveEnum> EnumArgs; // enum arguments
554-
std::map<int, unsigned> Attrs; // argument attributes
555-
int LocalArgBlockIdx; // index of a block with local arguments, idx < 0 if
556-
// none
557-
int VarArgIdx; // index of ellipsis argument, idx < 0 if none
526+
std::vector<BuiltinArgTypeMangleInfo> ArgInfo;
527+
int VarArgIdx; // index of ellipsis argument, idx < 0 if none
558528
private:
559529
bool DontMangle; // clang doesn't apply mangling for some builtin functions
560530
// (i.e. enqueue_kernel)
@@ -598,7 +568,8 @@ void removeFnAttr(CallInst *Call, Attribute::AttrKind Attr);
598568
void addFnAttr(CallInst *Call, Attribute::AttrKind Attr);
599569
void saveLLVMModule(Module *M, const std::string &OutputFile);
600570
std::string mapSPIRVTypeToOCLType(SPIRVType *Ty, bool Signed);
601-
std::string mapLLVMTypeToOCLType(const Type *Ty, bool Signed);
571+
std::string mapLLVMTypeToOCLType(const Type *Ty, bool Signed,
572+
Type *PointerElementType = nullptr);
602573
SPIRVDecorate *mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target);
603574

604575
/// Add decorations to a SPIR-V entry.
@@ -682,7 +653,8 @@ StringRef dePrefixSPIRVName(StringRef R, SmallVectorImpl<StringRef> &Postfix);
682653
/// Get a canonical function name for a SPIR-V op code.
683654
std::string getSPIRVFuncName(Op OC, StringRef PostFix = "");
684655

685-
std::string getSPIRVFuncName(Op OC, const Type *PRetTy, bool IsSigned = false);
656+
std::string getSPIRVFuncName(Op OC, const Type *PRetTy, bool IsSigned = false,
657+
Type *PointerElementType = nullptr);
686658

687659
std::string getSPIRVFuncName(SPIRVBuiltinVariableKind BVKind);
688660

@@ -785,6 +757,7 @@ CallInst *addCallInst(Module *M, StringRef FuncName, Type *RetTy,
785757
/// Add a call instruction for SPIR-V builtin function.
786758
CallInst *addCallInstSPIRV(Module *M, StringRef FuncName, Type *RetTy,
787759
ArrayRef<Value *> Args, AttributeList *Attrs,
760+
ArrayRef<Type *> PointerElementTypes,
788761
Instruction *Pos, StringRef InstName);
789762

790763
/// Add a call of spir_block_bind function.
@@ -889,7 +862,8 @@ std::string getPostfix(Decoration Dec, unsigned Value = 0);
889862
/// Get postfix _R{ReturnType} for return type
890863
/// The returned postfix does not includ "_" at the beginning
891864
std::string getPostfixForReturnType(CallInst *CI, bool IsSigned = false);
892-
std::string getPostfixForReturnType(const Type *PRetTy, bool IsSigned = false);
865+
std::string getPostfixForReturnType(const Type *PRetTy, bool IsSigned = false,
866+
Type *PointerElementType = nullptr);
893867

894868
Constant *getScalarOrVectorConstantInt(Type *T, uint64_t V,
895869
bool IsSigned = false);
@@ -1013,6 +987,7 @@ inline void getParameterTypes(CallInst *CI,
1013987
/// manner
1014988
std::string getSPIRVFriendlyIRFunctionName(OCLExtOpKind ExtOpId,
1015989
ArrayRef<Type *> ArgTys,
990+
ArrayRef<PointerIndirectPair> PETs,
1016991
Type *RetTy = nullptr);
1017992

1018993
/// Mangle a function in SPIR-V friendly IR manner
@@ -1024,7 +999,8 @@ std::string getSPIRVFriendlyIRFunctionName(OCLExtOpKind ExtOpId,
1024999
/// \param Types of arguments of SPIR-V built-in function
10251000
/// \return IA64 mangled name.
10261001
std::string getSPIRVFriendlyIRFunctionName(const std::string &UniqName,
1027-
spv::Op OC, ArrayRef<Type *> ArgTys);
1002+
spv::Op OC, ArrayRef<Type *> ArgTys,
1003+
ArrayRef<PointerIndirectPair> PETs);
10281004

10291005
/// Cast a function to a void(void) funtion pointer.
10301006
Constant *castToVoidFuncPtr(Function *F);

0 commit comments

Comments
 (0)