@@ -33,14 +33,13 @@ constexpr char SPIRV_GET_SPEC_CONST_VAL[] = "__spirv_SpecConstant";
33
33
// original symbolic spec constant ID.
34
34
constexpr char SPEC_CONST_SYM_ID_MD_STRING[] = " SYCL_SPEC_CONST_SYM_ID" ;
35
35
36
- static void AssertRelease (bool Cond, const char *Msg) {
36
+ void AssertRelease (bool Cond, const char *Msg) {
37
37
if (!Cond)
38
38
report_fatal_error ((Twine (" SpecConstants.cpp: " ) + Msg).str ().c_str ());
39
39
}
40
40
41
41
StringRef getStringLiteralArg (const CallInst *CI, unsigned ArgNo,
42
- SmallVectorImpl<Instruction *> &DelInsts,
43
- GlobalVariable *&SymGlob) {
42
+ SmallVectorImpl<Instruction *> &DelInsts) {
44
43
Value *V = CI->getArgOperand (ArgNo)->stripPointerCasts ();
45
44
46
45
if (auto *L = dyn_cast<LoadInst>(V)) {
@@ -95,7 +94,6 @@ StringRef getStringLiteralArg(const CallInst *CI, unsigned ArgNo,
95
94
V = Store->getValueOperand ()->stripPointerCasts ();
96
95
}
97
96
const Constant *Init = cast<GlobalVariable>(V)->getInitializer ();
98
- SymGlob = cast<GlobalVariable>(V);
99
97
StringRef Res = cast<ConstantDataArray>(Init)->getAsString ();
100
98
if (Res.size () > 0 && Res[Res.size () - 1 ] == ' \0 ' )
101
99
Res = Res.substr (0 , Res.size () - 1 );
@@ -104,16 +102,16 @@ StringRef getStringLiteralArg(const CallInst *CI, unsigned ArgNo,
104
102
105
103
// TODO support spec constant types other than integer or
106
104
// floating-point.
107
- Value *genDefaultValue (Type *T, Instruction *At ) {
105
+ Value *getDefaultCPPValue (Type *T) {
108
106
if (T->isIntegerTy ())
109
- return ConstantInt::get (T, 0 );
107
+ return Constant::getIntegerValue (T, APInt (T-> getScalarSizeInBits (), 0 ) );
110
108
if (T->isFloatingPointTy ())
111
109
return ConstantFP::get (T, 0.0 );
112
110
llvm_unreachable (" non-numeric specialization constants are NYI" );
113
111
return nullptr ;
114
112
}
115
113
116
- std::string manglePrimitiveType (Type *T) {
114
+ std::string manglePrimitiveType (const Type *T) {
117
115
if (T->isFloatTy ())
118
116
return " f" ;
119
117
if (T->isDoubleTy ())
@@ -139,7 +137,7 @@ std::string manglePrimitiveType(Type *T) {
139
137
140
138
// This is a very basic mangler which can mangle non-templated and non-member
141
139
// functions with primitive types in the signature.
142
- std::string mangleFuncItanium (StringRef BaseName, FunctionType *FT) {
140
+ std::string mangleFuncItanium (StringRef BaseName, const FunctionType *FT) {
143
141
std::string Res =
144
142
(Twine (" _Z" ) + Twine (BaseName.size ()) + Twine (BaseName)).str ();
145
143
for (unsigned I = 0 ; I < FT->getNumParams (); ++I)
@@ -156,7 +154,7 @@ void setSpecConstMetadata(Instruction *I, StringRef SymID, int IntID) {
156
154
I->setMetadata (SPEC_CONST_SYM_ID_MD_STRING, Entry);
157
155
}
158
156
159
- std::pair<StringRef, unsigned > getSpecConstMetadata (Instruction *I) {
157
+ std::pair<StringRef, unsigned > getSpecConstMetadata (const Instruction *I) {
160
158
const MDNode *N = I->getMetadata (SPEC_CONST_SYM_ID_MD_STRING);
161
159
if (!N)
162
160
return std::make_pair (" " , 0 );
@@ -167,13 +165,28 @@ std::pair<StringRef, unsigned> getSpecConstMetadata(Instruction *I) {
167
165
return std::make_pair (MDSym->getString (), ID);
168
166
}
169
167
170
- static Value *getDefaultCPPValue (Type *T) {
171
- if (T->isIntegerTy ())
172
- return Constant::getIntegerValue (T, APInt (T->getScalarSizeInBits (), 0 ));
173
- if (T->isFloatingPointTy ())
174
- return ConstantFP::get (T, 0 );
175
- llvm_unreachable (" unsupported spec const type" );
176
- return nullptr ;
168
+ Instruction *emitSpecConstant (int NumericID, Type *Ty,
169
+ Instruction *InsertBefore) {
170
+ Function *F = InsertBefore->getFunction ();
171
+ // Generate arguments needed by the SPIRV version of the intrinsic
172
+ // - integer constant ID:
173
+ Value *ID = ConstantInt::get (Type::getInt32Ty (F->getContext ()), NumericID);
174
+ // - default value:
175
+ Value *Def = getDefaultCPPValue (Ty);
176
+ // ... Now replace the call with SPIRV intrinsic version.
177
+ Value *Args[] = {ID, Def};
178
+ constexpr size_t NArgs = sizeof (Args) / sizeof (Args[0 ]);
179
+ Type *ArgTys[NArgs] = {nullptr };
180
+ for (unsigned int I = 0 ; I < NArgs; ++I)
181
+ ArgTys[I] = Args[I]->getType ();
182
+ FunctionType *FT = FunctionType::get (Ty, ArgTys, false /* isVarArg*/ );
183
+ Module *M = F->getParent ();
184
+ std::string SPIRVName = mangleFuncItanium (SPIRV_GET_SPEC_CONST_VAL, FT);
185
+ FunctionCallee FC = M->getOrInsertFunction (SPIRVName, FT);
186
+ assert (FC.getCallee () && " SPIRV intrinsic creation failed" );
187
+ CallInst *SpecConstant =
188
+ CallInst::Create (FT, FC.getCallee (), Args, " " , InsertBefore);
189
+ return SpecConstant;
177
190
}
178
191
179
192
} // namespace
@@ -198,10 +211,8 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
198
211
199
212
SmallVector<CallInst *, 32 > SCIntrCalls;
200
213
for (auto *U : F.users ()) {
201
- auto *CI = dyn_cast<CallInst>(U);
202
- if (!CI)
203
- continue ;
204
- SCIntrCalls.push_back (CI);
214
+ if (auto *CI = dyn_cast<CallInst>(U))
215
+ SCIntrCalls.push_back (CI);
205
216
}
206
217
207
218
IRModified = IRModified || (SCIntrCalls.size () > 0 );
@@ -213,8 +224,7 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
213
224
// code can't use this intrinsic directly.
214
225
SmallVector<Instruction *, 3 > DelInsts;
215
226
DelInsts.push_back (CI);
216
- GlobalVariable *SymGlob = nullptr ;
217
- StringRef SymID = getStringLiteralArg (CI, 0 , DelInsts, SymGlob);
227
+ StringRef SymID = getStringLiteralArg (CI, 0 , DelInsts);
218
228
Type *SCTy = CI->getType ();
219
229
220
230
if (SetValAtRT) {
@@ -225,25 +235,7 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
225
235
if (Ins.second )
226
236
Ins.first ->second = NextID++;
227
237
// 3. Transform to spirv intrinsic _Z*__spirv_SpecConstant*.
228
- LLVMContext &Ctx = F.getContext ();
229
- // Generate arguments needed by the SPIRV version of the intrinsic
230
- // - integer constant ID:
231
- Value *ID = ConstantInt::get (Type::getInt32Ty (Ctx), NextID - 1 );
232
- // - default value:
233
- Value *Def = genDefaultValue (SCTy, CI);
234
- // ... Now replace the call with SPIRV intrinsic version.
235
- Value *Args[] = {ID, Def};
236
- constexpr size_t NArgs = sizeof (Args) / sizeof (Args[0 ]);
237
- Type *ArgTys[NArgs] = {nullptr };
238
- for (unsigned int I = 0 ; I < NArgs; ++I)
239
- ArgTys[I] = Args[I]->getType ();
240
- FunctionType *FT = FunctionType::get (SCTy, ArgTys, false /* isVarArg*/ );
241
- Module &M = *F.getParent ();
242
- std::string SPIRVName = mangleFuncItanium (SPIRV_GET_SPEC_CONST_VAL, FT);
243
- FunctionCallee FC = M.getOrInsertFunction (SPIRVName, FT);
244
- assert (FC.getCallee () && " SPIRV intrinsic creation failed" );
245
- CallInst *SPIRVCall =
246
- CallInst::Create (FT, FC.getCallee (), Args, " " , CI);
238
+ auto *SPIRVCall = emitSpecConstant (NextID - 1 , SCTy, CI);
247
239
CI->replaceAllUsesWith (SPIRVCall);
248
240
// Mark the instruction with <symbolic_id, int_id> pair for later
249
241
// recollection by collectSpecConstantMetadata method.
@@ -261,8 +253,6 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
261
253
I->removeFromParent ();
262
254
I->deleteValue ();
263
255
}
264
- // Don't delete SymGlob here, as it may be referenced from multiple
265
- // functions if __sycl_getSpecConstantValue is inlined.
266
256
}
267
257
}
268
258
return IRModified ? PreservedAnalyses::none () : PreservedAnalyses::all ();
0 commit comments