@@ -109,8 +109,6 @@ StringRef getStringLiteralArg(const CallInst *CI, unsigned ArgNo,
109
109
return Res;
110
110
}
111
111
112
- // TODO support spec constant types other than integer or
113
- // floating-point.
114
112
Value *getDefaultCPPValue (Type *T) {
115
113
if (T->isIntegerTy ())
116
114
return Constant::getIntegerValue (T, APInt (T->getScalarSizeInBits (), 0 ));
@@ -167,16 +165,13 @@ std::string manglePrimitiveType(const Type *T) {
167
165
// llvm-spirv doesn't care about the mangling and the only intent here is to
168
166
// make sure that we won't encounter redefinition error when we proceed two
169
167
// spec constants with different types.
170
- if (T->isStructTy ()) {
168
+ if (T->isStructTy ())
171
169
return T->getStructName ().str ();
172
- }
173
- if (T->isArrayTy ()) {
170
+ if (T->isArrayTy ())
174
171
return " A" + manglePrimitiveType (T->getArrayElementType ());
175
- }
176
- if (auto *VecTy = dyn_cast<FixedVectorType>(T)) {
172
+ if (auto *VecTy = dyn_cast<FixedVectorType>(T))
177
173
return " Dv" + std::to_string (VecTy->getNumElements ()) + " _" +
178
174
manglePrimitiveType (VecTy->getElementType ());
179
- }
180
175
llvm_unreachable (" unsupported spec const type" );
181
176
return " " ;
182
177
}
@@ -196,10 +191,9 @@ void setSpecConstSymIDMetadata(Instruction *I, StringRef SymID,
196
191
LLVMContext &Ctx = I->getContext ();
197
192
SmallVector<Metadata *, 4 > MDOperands;
198
193
MDOperands.push_back (MDString::get (Ctx, SymID));
199
- for (unsigned ID : IntIDs) {
194
+ for (unsigned ID : IntIDs)
200
195
MDOperands.push_back (
201
196
ConstantAsMetadata::get (ConstantInt::get (Ctx, APInt (32 , ID))));
202
- }
203
197
MDNode *Entry = MDNode::get (Ctx, MDOperands);
204
198
I->setMetadata (SPEC_CONST_SYM_ID_MD_STRING, Entry);
205
199
}
@@ -218,7 +212,7 @@ getScalarSpecConstMetadata(const Instruction *I) {
218
212
219
213
void collectCompositeElementsInfoRecursive (
220
214
const Type *Ty, unsigned &Index, unsigned &Offset,
221
- std::vector<CompositeSpecConstDescriptor > &Result) {
215
+ std::vector<CompositeSpecConstElementDescriptor > &Result) {
222
216
if (auto *ArrTy = dyn_cast<ArrayType>(Ty)) {
223
217
for (size_t I = 0 ; I < ArrTy->getNumElements (); ++I) {
224
218
// TODO: this is a spot for potential optimization: for arrays we could
@@ -233,14 +227,14 @@ void collectCompositeElementsInfoRecursive(
233
227
}
234
228
} else if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) {
235
229
for (size_t I = 0 ; I < VecTy->getNumElements (); ++I) {
236
- // TODO: this is a spot for potential optimization: for arrays we could
230
+ // TODO: this is a spot for potential optimization: for vectors we could
237
231
// just make a single recursive call here and use it to populate Result
238
232
// in a loop.
239
233
collectCompositeElementsInfoRecursive (VecTy->getElementType (), Index,
240
234
Offset, Result);
241
235
}
242
236
} else { // Assume that we encountered some scalar element
243
- CompositeSpecConstDescriptor Desc;
237
+ CompositeSpecConstElementDescriptor Desc;
244
238
Desc.ID = 0 ; // To be filled later
245
239
Desc.Offset = Offset;
246
240
Desc.Size = Ty->getPrimitiveSizeInBits () / 8 ;
@@ -249,14 +243,16 @@ void collectCompositeElementsInfoRecursive(
249
243
}
250
244
}
251
245
252
- std::pair<StringRef, std::vector<CompositeSpecConstDescriptor >>
246
+ std::pair<StringRef, std::vector<CompositeSpecConstElementDescriptor >>
253
247
getCompositeSpecConstMetadata (const Instruction *I) {
254
248
const MDNode *N = I->getMetadata (SPEC_CONST_SYM_ID_MD_STRING);
255
249
if (!N)
256
- return std::make_pair (" " , std::vector<CompositeSpecConstDescriptor>{});
250
+ return std::make_pair (" " ,
251
+ std::vector<CompositeSpecConstElementDescriptor>{});
257
252
const auto *MDSym = cast<MDString>(N->getOperand (0 ));
258
253
259
- std::vector<CompositeSpecConstDescriptor> Result (N->getNumOperands () - 1 );
254
+ std::vector<CompositeSpecConstElementDescriptor> Result (N->getNumOperands () -
255
+ 1 );
260
256
unsigned Index = 0 , Offset = 0 ;
261
257
collectCompositeElementsInfoRecursive (I->getType (), Index, Offset, Result);
262
258
@@ -269,6 +265,21 @@ getCompositeSpecConstMetadata(const Instruction *I) {
269
265
return std::make_pair (MDSym->getString (), Result);
270
266
}
271
267
268
+ Instruction *emitCall (Type *RetTy, StringRef BaseFunctionName,
269
+ ArrayRef<Value *> Args, Instruction *InsertBefore) {
270
+ SmallVector<Type *, 8 > ArgTys (Args.size ());
271
+ for (unsigned I = 0 ; I < Args.size (); ++I) {
272
+ ArgTys[I] = Args[I]->getType ();
273
+ }
274
+ auto *FT = FunctionType::get (RetTy, ArgTys, false /* isVarArg*/ );
275
+ std::string FunctionName = mangleFuncItanium (BaseFunctionName, FT);
276
+ Module *M = InsertBefore->getFunction ()->getParent ();
277
+ FunctionCallee FC = M->getOrInsertFunction (FunctionName, FT);
278
+ assert (FC.getCallee () && " SPIRV intrinsic creation failed" );
279
+ auto *Call = CallInst::Create (FT, FC.getCallee (), Args, " " , InsertBefore);
280
+ return Call;
281
+ }
282
+
272
283
Instruction *emitSpecConstant (unsigned NumericID, Type *Ty,
273
284
Instruction *InsertBefore) {
274
285
Function *F = InsertBefore->getFunction ();
@@ -279,37 +290,17 @@ Instruction *emitSpecConstant(unsigned NumericID, Type *Ty,
279
290
Value *Def = getDefaultCPPValue (Ty);
280
291
// ... Now replace the call with SPIRV intrinsic version.
281
292
Value *Args[] = {ID, Def};
282
- constexpr size_t NArgs = sizeof (Args) / sizeof (Args[0 ]);
283
- Type *ArgTys[NArgs] = {nullptr };
284
- for (unsigned int I = 0 ; I < NArgs; ++I)
285
- ArgTys[I] = Args[I]->getType ();
286
- FunctionType *FT = FunctionType::get (Ty, ArgTys, false /* isVarArg*/ );
287
- Module *M = F->getParent ();
288
- std::string SPIRVName = mangleFuncItanium (SPIRV_GET_SPEC_CONST_VAL, FT);
289
- FunctionCallee FC = M->getOrInsertFunction (SPIRVName, FT);
290
- assert (FC.getCallee () && " SPIRV intrinsic creation failed" );
291
- CallInst *SpecConstant =
292
- CallInst::Create (FT, FC.getCallee (), Args, " " , InsertBefore);
293
- return SpecConstant;
293
+ return emitCall (Ty, SPIRV_GET_SPEC_CONST_VAL, Args, InsertBefore);
294
294
}
295
295
296
296
Instruction *emitSpecConstantComposite (Type *Ty,
297
297
ArrayRef<Instruction *> Elements,
298
298
Instruction *InsertBefore) {
299
- SmallVector<Type *, 8 > ArgTys (Elements.size ());
300
299
SmallVector<Value *, 8 > Args (Elements.size ());
301
300
for (unsigned I = 0 ; I < Elements.size (); ++I) {
302
- ArgTys[I] = Elements[I]->getType ();
303
301
Args[I] = cast<Value>(Elements[I]);
304
302
}
305
- auto *FT = FunctionType::get (Ty, ArgTys, false /* isVarArg*/ );
306
- Module *M = InsertBefore->getFunction ()->getParent ();
307
- std::string SPIRVName = mangleFuncItanium (SPIRV_GET_SPEC_CONST_COMPOSITE, FT);
308
- FunctionCallee FC = M->getOrInsertFunction (SPIRVName, FT);
309
- assert (FC.getCallee () && " SPIRV intrinsic creation failed" );
310
- CallInst *SpecConstant =
311
- CallInst::Create (FT, FC.getCallee (), Args, " " , InsertBefore);
312
- return SpecConstant;
303
+ return emitCall (Ty, SPIRV_GET_SPEC_CONST_COMPOSITE, Args, InsertBefore);
313
304
}
314
305
315
306
Instruction *
@@ -416,13 +407,14 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
416
407
NextID += GeneratedIDs.size ();
417
408
}
418
409
419
- if (IsComposite)
410
+ if (IsComposite) {
420
411
// __sycl_getCompositeSpecConstant returns through argument, so, the
421
412
// only thing we need to do here is to store into a memory pointed by
422
413
// that argument
423
414
new StoreInst (SPIRVCall, CI->getArgOperand (0 ), CI);
424
- else
415
+ } else {
425
416
CI->replaceAllUsesWith (SPIRVCall);
417
+ }
426
418
427
419
// Mark the instruction with <symbolic_id, int_ids...> list for later
428
420
// recollection by collectSpecConstantMetadata method.
@@ -442,13 +434,14 @@ PreservedAnalyses SpecConstantsPass::run(Module &M,
442
434
// 2a. Spec constant must be resolved at compile time - just replace
443
435
// the intrinsic with default C++ value for the spec constant type.
444
436
Value *Default = getDefaultCPPValue (SCTy);
445
- if (IsComposite)
437
+ if (IsComposite) {
446
438
// __sycl_getCompositeSpecConstant returns through argument, so, the
447
439
// only thing we need to do here is to store into a memory pointed by
448
440
// that argument
449
441
new StoreInst (Default, CI->getArgOperand (0 ), CI);
450
- else
442
+ } else {
451
443
CI->replaceAllUsesWith (Default);
444
+ }
452
445
}
453
446
454
447
for (auto *I : DelInsts) {
0 commit comments