@@ -70,8 +70,8 @@ bool OCLTypeToSPIRVLegacy::runOnModule(Module &M) {
70
70
return runOCLTypeToSPIRV (M);
71
71
}
72
72
73
- OCLTypeToSPIRVBase OCLTypeToSPIRVPass::run (llvm::Module &M,
74
- llvm::ModuleAnalysisManager &MAM) {
73
+ OCLTypeToSPIRVBase & OCLTypeToSPIRVPass::run (llvm::Module &M,
74
+ llvm::ModuleAnalysisManager &MAM) {
75
75
runOCLTypeToSPIRV (M);
76
76
return *this ;
77
77
}
@@ -104,11 +104,12 @@ bool OCLTypeToSPIRVBase::runOCLTypeToSPIRV(Module &Module) {
104
104
return false ;
105
105
}
106
106
107
- void OCLTypeToSPIRVBase::addAdaptedType (Value *V, Type *T) {
107
+ void OCLTypeToSPIRVBase::addAdaptedType (Value *V, Type *Ty,
108
+ unsigned AddrSpace) {
108
109
LLVM_DEBUG (dbgs () << " [add adapted type] " ;
109
110
V->printAsOperand (dbgs (), true , M);
110
- dbgs () << " => " << *T << ' \n ' );
111
- AdaptedTy[V] = T ;
111
+ dbgs () << " => " << *Ty << ' \n ' );
112
+ AdaptedTy[V] = {Ty, AddrSpace} ;
112
113
}
113
114
114
115
void OCLTypeToSPIRVBase::addWork (Function *F) {
@@ -117,34 +118,6 @@ void OCLTypeToSPIRVBase::addWork(Function *F) {
117
118
WorkSet.insert (F);
118
119
}
119
120
120
- // / Find index of \param V as argument of function call \param CI.
121
- static unsigned getArgIndex (CallInst *CI, Value *V) {
122
- for (unsigned AI = 0 , AE = CI->arg_size (); AI != AE; ++AI) {
123
- if (CI->getArgOperand (AI) == V)
124
- return AI;
125
- }
126
- llvm_unreachable (" Not argument of function call" );
127
- return ~0U ;
128
- }
129
-
130
- // / Find index of \param V as argument of function call \param CI.
131
- static unsigned getArgIndex (Function *F, Value *V) {
132
- auto A = F->arg_begin (), E = F->arg_end ();
133
- for (unsigned I = 0 ; A != E; ++I, ++A) {
134
- if (&(*A) == V)
135
- return I;
136
- }
137
- llvm_unreachable (" Not argument of function" );
138
- return ~0U ;
139
- }
140
-
141
- // / Get i-th argument of a function.
142
- static Argument *getArg (Function *F, unsigned I) {
143
- auto AI = F->arg_begin ();
144
- std::advance (AI, I);
145
- return &(*AI);
146
- }
147
-
148
121
// / Create a new function type if \param F has arguments in AdaptedTy, and
149
122
// / propagates the adapted arguments to functions called by \param F.
150
123
void OCLTypeToSPIRVBase::adaptFunction (Function *F) {
@@ -158,15 +131,17 @@ void OCLTypeToSPIRVBase::adaptFunction(Function *F) {
158
131
auto Loc = AdaptedTy.find (&I);
159
132
auto Found = (Loc != AdaptedTy.end ());
160
133
Changed |= Found;
161
- ArgTys.push_back (Found ? Loc->second : I.getType ());
134
+ ArgTys.push_back (Found ? Loc->second . first : I.getType ());
162
135
163
136
if (Found) {
164
- for (auto U : I.users ()) {
165
- if (auto CI = dyn_cast<CallInst>(U)) {
166
- auto ArgIndex = getArgIndex (CI, &I);
137
+ auto *Ty = Loc->second .first ;
138
+ unsigned AddrSpace = Loc->second .second ;
139
+ for (auto &U : I.uses ()) {
140
+ if (auto *CI = dyn_cast<CallInst>(U.getUser ())) {
141
+ auto ArgIndex = CI->getArgOperandNo (&U);
167
142
auto CF = CI->getCalledFunction ();
168
143
if (AdaptedTy.count (CF) == 0 ) {
169
- addAdaptedType (getArg (CF, ArgIndex), Loc-> second );
144
+ addAdaptedType (CF-> getArg (ArgIndex), Ty, AddrSpace );
170
145
addWork (CF);
171
146
}
172
147
}
@@ -179,7 +154,7 @@ void OCLTypeToSPIRVBase::adaptFunction(Function *F) {
179
154
180
155
auto FT = F->getFunctionType ();
181
156
FT = FunctionType::get (FT->getReturnType (), ArgTys, FT->isVarArg ());
182
- addAdaptedType (F, FT);
157
+ addAdaptedType (F, FT, 0 );
183
158
}
184
159
185
160
// Handle functions with sampler arguments that don't get called by
@@ -204,15 +179,10 @@ void OCLTypeToSPIRVBase::adaptArgumentsBySamplerUse(Module &M) {
204
179
AdaptedTy.count (SamplerArg) != 0 ) // Already traced this, move on.
205
180
continue ;
206
181
207
- if (SamplerArg->getType ()->isPointerTy () &&
208
- isSPIRVStructType (SamplerArg->getType ()->getPointerElementType (),
209
- kSPIRVTypeName ::Sampler))
210
- return ;
211
-
212
- addAdaptedType (SamplerArg, getSamplerType (&M));
182
+ addAdaptedType (SamplerArg, getSamplerStructType (&M), SPIRAS_Constant);
213
183
auto Caller = cast<Argument>(SamplerArg)->getParent ();
214
184
addWork (Caller);
215
- TraceArg (Caller, getArgIndex (Caller, SamplerArg) );
185
+ TraceArg (Caller, Idx );
216
186
}
217
187
};
218
188
@@ -235,20 +205,28 @@ void OCLTypeToSPIRVBase::adaptFunctionArguments(Function *F) {
235
205
if (TypeMD)
236
206
return ;
237
207
bool Changed = false ;
238
- auto FT = F->getFunctionType ();
239
- auto PI = FT->param_begin ();
240
208
auto Arg = F->arg_begin ();
241
- for (unsigned I = 0 ; I < F->arg_size (); ++I, ++PI, ++Arg) {
242
- auto NewTy = *PI;
243
- if (isPointerToOpaqueStructType (NewTy)) {
244
- auto STName = NewTy->getPointerElementType ()->getStructName ();
209
+ SmallVector<StructType *, 4 > ParamTys;
210
+ getParameterTypes (F, ParamTys);
211
+
212
+ // If we couldn't get any information from demangling, there is nothing that
213
+ // can be done.
214
+ if (ParamTys.empty ())
215
+ return ;
216
+
217
+ for (unsigned I = 0 ; I < F->arg_size (); ++I, ++Arg) {
218
+ StructType *NewTy = ParamTys[I];
219
+ if (NewTy && NewTy->isOpaque ()) {
220
+ auto STName = NewTy->getStructName ();
245
221
if (!hasAccessQualifiedName (STName))
246
222
continue ;
247
223
if (STName.startswith (kSPR2TypeName ::ImagePrefix)) {
248
224
auto Ty = STName.str ();
249
225
auto AccStr = getAccessQualifierFullName (Ty);
250
- addAdaptedType (&*Arg, getOrCreateOpaquePtrType (
251
- M, mapOCLTypeNameToSPIRV (Ty, AccStr)));
226
+ addAdaptedType (
227
+ &*Arg,
228
+ getOrCreateOpaqueStructType (M, mapOCLTypeNameToSPIRV (Ty, AccStr)),
229
+ SPIRAS_Global);
252
230
Changed = true ;
253
231
}
254
232
}
@@ -269,16 +247,18 @@ void OCLTypeToSPIRVBase::adaptArgumentsByMetadata(Function *F) {
269
247
for (unsigned I = 0 , E = TypeMD->getNumOperands (); I != E; ++I, ++Arg) {
270
248
auto OCLTyStr = getMDOperandAsString (TypeMD, I);
271
249
if (OCLTyStr == OCL_TYPE_NAME_SAMPLER_T) {
272
- addAdaptedType (&(*Arg), getSamplerType (M));
250
+ addAdaptedType (&(*Arg), getSamplerStructType (M), SPIRAS_Constant );
273
251
Changed = true ;
274
252
} else if (OCLTyStr.startswith (" image" ) && OCLTyStr.endswith (" _t" )) {
275
253
auto Ty = (Twine (" opencl." ) + OCLTyStr).str ();
276
254
if (StructType::getTypeByName (F->getContext (), Ty)) {
277
255
auto AccMD = F->getMetadata (SPIR_MD_KERNEL_ARG_ACCESS_QUAL);
278
256
assert (AccMD && " Invalid access qualifier metadata" );
279
257
auto AccStr = getMDOperandAsString (AccMD, I);
280
- addAdaptedType (&(*Arg), getOrCreateOpaquePtrType (
281
- M, mapOCLTypeNameToSPIRV (Ty, AccStr)));
258
+ addAdaptedType (
259
+ &(*Arg),
260
+ getOrCreateOpaqueStructType (M, mapOCLTypeNameToSPIRV (Ty, AccStr)),
261
+ SPIRAS_Global);
282
262
Changed = true ;
283
263
}
284
264
}
@@ -315,14 +295,15 @@ void OCLTypeToSPIRVBase::adaptArgumentsByMetadata(Function *F) {
315
295
// opencl data type x and access qualifier y, and use opencl.image_x.y to
316
296
// represent image_x type with access qualifier y.
317
297
//
318
- Type *OCLTypeToSPIRVBase::getAdaptedType (Value *V) {
319
- auto Loc = AdaptedTy.find (V);
320
- if (Loc != AdaptedTy.end ())
321
- return Loc->second ;
322
-
323
- if (auto F = dyn_cast<Function>(V))
324
- return F->getFunctionType ();
325
- return V->getType ();
298
+ std::pair<Type *, Type *>
299
+ OCLTypeToSPIRVBase::getAdaptedArgumentType (Function *F, unsigned ArgNo) {
300
+ Value *Arg = F->getArg (ArgNo);
301
+ auto Loc = AdaptedTy.find (Arg);
302
+ if (Loc == AdaptedTy.end ())
303
+ return {nullptr , nullptr };
304
+ Type *PointeeTy = Loc->second .first ;
305
+ Type *PointerTy = PointerType::get (PointeeTy, Loc->second .second );
306
+ return {PointerTy, PointeeTy};
326
307
}
327
308
328
309
} // namespace SPIRV
0 commit comments