1 //===- SPIRVReader.cpp - Converts SPIR-V to LLVM ----------------*- C++ -*-===//
2 //
3 // The LLVM/SPIR-V Translator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal with the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // Redistributions of source code must retain the above copyright notice,
18 // this list of conditions and the following disclaimers.
19 // Redistributions in binary form must reproduce the above copyright notice,
20 // this list of conditions and the following disclaimers in the documentation
21 // and/or other materials provided with the distribution.
22 // Neither the names of Advanced Micro Devices, Inc., nor the names of its
23 // contributors may be used to endorse or promote products derived from this
24 // Software without specific prior written permission.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
31 // THE SOFTWARE.
32 //
33 //===----------------------------------------------------------------------===//
34 /// \file
35 ///
36 /// This file implements conversion of SPIR-V binary to LLVM IR.
37 ///
38 //===----------------------------------------------------------------------===//
39 #include "SPIRVUtil.h"
40 #include "SPIRVType.h"
41 #include "SPIRVValue.h"
42 #include "SPIRVModule.h"
43 #include "SPIRVFunction.h"
44 #include "SPIRVBasicBlock.h"
45 #include "SPIRVInstruction.h"
46 #include "SPIRVExtInst.h"
47 #include "SPIRVInternal.h"
48 #include "SPIRVMDBuilder.h"
49 #include "OCLUtil.h"
50
51 #include "llvm/ADT/DenseMap.h"
52 #include "llvm/ADT/StringSwitch.h"
53 #include "llvm/IR/Constants.h"
54 #include "llvm/IR/DerivedTypes.h"
55 #include "llvm/IR/DIBuilder.h"
56 #include "llvm/IR/Instructions.h"
57 #include "llvm/IR/Metadata.h"
58 #include "llvm/IR/Module.h"
59 #include "llvm/IR/Operator.h"
60 #include "llvm/IR/Type.h"
61 #include "llvm/IR/LegacyPassManager.h"
62 #include "llvm/Support/Casting.h"
63 #include "llvm/Support/Debug.h"
64 #include "llvm/Support/Dwarf.h"
65 #include "llvm/Support/FileSystem.h"
66 #include "llvm/Support/raw_ostream.h"
67 #include "llvm/Support/CommandLine.h"
68
69 #include <algorithm>
70 #include <cstdlib>
71 #include <functional>
72 #include <fstream>
73 #include <iostream>
74 #include <iterator>
75 #include <map>
76 #include <set>
77 #include <sstream>
78 #include <string>
79
80 #define DEBUG_TYPE "spirv"
81
82 using namespace std;
83 using namespace llvm;
84 using namespace SPIRV;
85 using namespace OCLUtil;
86
87 namespace SPIRV{
88
89 cl::opt<bool> SPIRVEnableStepExpansion("spirv-expand-step", cl::init(true),
90 cl::desc("Enable expansion of OpenCL step and smoothstep function"));
91
92 cl::opt<bool> SPIRVGenKernelArgNameMD("spirv-gen-kernel-arg-name-md",
93 cl::init(false), cl::desc("Enable generating OpenCL kernel argument name "
94 "metadata"));
95
96 cl::opt<bool> SPIRVGenImgTypeAccQualPostfix("spirv-gen-image-type-acc-postfix",
97 cl::init(false), cl::desc("Enable generating access qualifier postfix"
98 " in OpenCL image type names"));
99
100 // Prefix for placeholder global variable name.
101 const char* kPlaceholderPrefix = "placeholder.";
102
103 // Save the translated LLVM before validation for debugging purpose.
104 static bool DbgSaveTmpLLVM = true;
105 static const char *DbgTmpLLVMFileName = "_tmp_llvmbil.ll";
106
107 typedef std::pair < unsigned, AttributeSet > AttributeWithIndex;
108
109 static bool
isOpenCLKernel(SPIRVFunction * BF)110 isOpenCLKernel(SPIRVFunction *BF) {
111 return BF->getModule()->isEntryPoint(ExecutionModelKernel, BF->getId());
112 }
113
114 static void
dumpLLVM(Module * M,const std::string & FName)115 dumpLLVM(Module *M, const std::string &FName) {
116 std::error_code EC;
117 raw_fd_ostream FS(FName, EC, sys::fs::F_None);
118 if (EC) {
119 FS << *M;
120 FS.close();
121 }
122 }
123
124 static MDNode*
getMDNodeStringIntVec(LLVMContext * Context,const std::string & Str,const std::vector<SPIRVWord> & IntVals)125 getMDNodeStringIntVec(LLVMContext *Context, const std::string& Str,
126 const std::vector<SPIRVWord>& IntVals) {
127 std::vector<Metadata*> ValueVec;
128 ValueVec.push_back(MDString::get(*Context, Str));
129 for (auto &I:IntVals)
130 ValueVec.push_back(ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(*Context), I)));
131 return MDNode::get(*Context, ValueVec);
132 }
133
134 static MDNode*
getMDTwoInt(LLVMContext * Context,unsigned Int1,unsigned Int2)135 getMDTwoInt(LLVMContext *Context, unsigned Int1, unsigned Int2) {
136 std::vector<Metadata*> ValueVec;
137 ValueVec.push_back(ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(*Context), Int1)));
138 ValueVec.push_back(ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(*Context), Int2)));
139 return MDNode::get(*Context, ValueVec);
140 }
141
142 #if 0
143 // this function is currently unneeded
144 static MDNode*
145 getMDString(LLVMContext *Context, const std::string& Str) {
146 std::vector<Metadata*> ValueVec;
147 if (!Str.empty())
148 ValueVec.push_back(MDString::get(*Context, Str));
149 return MDNode::get(*Context, ValueVec);
150 }
151 #endif
152
153 static void
addOCLVersionMetadata(LLVMContext * Context,Module * M,const std::string & MDName,unsigned Major,unsigned Minor)154 addOCLVersionMetadata(LLVMContext *Context, Module *M,
155 const std::string &MDName, unsigned Major, unsigned Minor) {
156 NamedMDNode *NamedMD = M->getOrInsertNamedMetadata(MDName);
157 NamedMD->addOperand(getMDTwoInt(Context, Major, Minor));
158 }
159
160 static void
addNamedMetadataStringSet(LLVMContext * Context,Module * M,const std::string & MDName,const std::set<std::string> & StrSet)161 addNamedMetadataStringSet(LLVMContext *Context, Module *M,
162 const std::string &MDName, const std::set<std::string> &StrSet) {
163 NamedMDNode *NamedMD = M->getOrInsertNamedMetadata(MDName);
164 std::vector<Metadata*> ValueVec;
165 for (auto &&Str : StrSet) {
166 ValueVec.push_back(MDString::get(*Context, Str));
167 }
168 NamedMD->addOperand(MDNode::get(*Context, ValueVec));
169 }
170
171 static void
addOCLKernelArgumentMetadata(LLVMContext * Context,std::vector<llvm::Metadata * > & KernelMD,const std::string & MDName,SPIRVFunction * BF,std::function<Metadata * (SPIRVFunctionParameter *)> Func)172 addOCLKernelArgumentMetadata(LLVMContext *Context,
173 std::vector<llvm::Metadata*> &KernelMD, const std::string &MDName,
174 SPIRVFunction *BF, std::function<Metadata *(SPIRVFunctionParameter *)>Func){
175 std::vector<Metadata*> ValueVec;
176 ValueVec.push_back(MDString::get(*Context, MDName));
177 BF->foreachArgument([&](SPIRVFunctionParameter *Arg) {
178 ValueVec.push_back(Func(Arg));
179 });
180 KernelMD.push_back(MDNode::get(*Context, ValueVec));
181 }
182
183 class SPIRVToLLVMDbgTran {
184 public:
SPIRVToLLVMDbgTran(SPIRVModule * TBM,Module * TM)185 SPIRVToLLVMDbgTran(SPIRVModule *TBM, Module *TM)
186 :BM(TBM), M(TM), SpDbg(BM), Builder(*M){
187 Enable = BM->hasDebugInfo();
188 }
189
createCompileUnit()190 void createCompileUnit() {
191 if (!Enable)
192 return;
193 auto File = SpDbg.getEntryPointFileStr(ExecutionModelKernel, 0);
194 std::string BaseName;
195 std::string Path;
196 splitFileName(File, BaseName, Path);
197 Builder.createCompileUnit(dwarf::DW_LANG_C99,
198 BaseName, Path, "spirv", false, "", 0, "", DICompileUnit::DebugEmissionKind::LineTablesOnly);
199 }
200
addDbgInfoVersion()201 void addDbgInfoVersion() {
202 if (!Enable)
203 return;
204 M->addModuleFlag(Module::Warning, "Dwarf Version",
205 dwarf::DWARF_VERSION);
206 M->addModuleFlag(Module::Warning, "Debug Info Version",
207 DEBUG_METADATA_VERSION);
208 }
209
getDIFile(const std::string & FileName)210 DIFile* getDIFile(const std::string &FileName){
211 return getOrInsert(FileMap, FileName, [=](){
212 std::string BaseName;
213 std::string Path;
214 splitFileName(FileName, BaseName, Path);
215 if (!BaseName.empty())
216 return Builder.createFile(BaseName, Path);
217 else
218 return Builder.createFile("","");//DIFile();
219 });
220 }
221
getDISubprogram(SPIRVFunction * SF,Function * F)222 DISubprogram* getDISubprogram(SPIRVFunction *SF, Function *F){
223 return getOrInsert(FuncMap, F, [=](){
224 auto DF = getDIFile(SpDbg.getFunctionFileStr(SF));
225 auto FN = F->getName();
226 auto LN = SpDbg.getFunctionLineNo(SF);
227 Metadata *Args[] = {Builder.createUnspecifiedType("")};
228 return Builder.createFunction(static_cast<DIScope*>(DF), FN, FN, DF, LN,
229 Builder.createSubroutineType(Builder.getOrCreateTypeArray(Args)),
230 Function::isInternalLinkage(F->getLinkage()),
231 true, LN);
232 });
233 }
234
transDbgInfo(SPIRVValue * SV,Value * V)235 void transDbgInfo(SPIRVValue *SV, Value *V) {
236 if (!Enable || !SV->hasLine())
237 return;
238 if (auto I = dyn_cast<Instruction>(V)) {
239 assert(SV->isInst() && "Invalid instruction");
240 auto SI = static_cast<SPIRVInstruction *>(SV);
241 assert(SI->getParent() &&
242 SI->getParent()->getParent() &&
243 "Invalid instruction");
244 auto Line = SV->getLine();
245 I->setDebugLoc(DebugLoc::get(Line->getLine(), Line->getColumn(),
246 getDISubprogram(SI->getParent()->getParent(),
247 I->getParent()->getParent())));
248 }
249 }
250
finalize()251 void finalize() {
252 if (!Enable)
253 return;
254 Builder.finalize();
255 }
256
257 private:
258 SPIRVModule *BM;
259 Module *M;
260 SPIRVDbgInfo SpDbg;
261 DIBuilder Builder;
262 bool Enable;
263 std::unordered_map<std::string, DIFile*> FileMap;
264 std::unordered_map<Function *, DISubprogram*> FuncMap;
265
splitFileName(const std::string & FileName,std::string & BaseName,std::string & Path)266 void splitFileName(const std::string &FileName,
267 std::string &BaseName,
268 std::string &Path) {
269 auto Loc = FileName.find_last_of("/\\");
270 if (Loc != std::string::npos) {
271 BaseName = FileName.substr(Loc + 1);
272 Path = FileName.substr(0, Loc);
273 } else {
274 BaseName = FileName;
275 Path = ".";
276 }
277 }
278 };
279
280 class SPIRVToLLVM {
281 public:
SPIRVToLLVM(Module * LLVMModule,SPIRVModule * TheSPIRVModule)282 SPIRVToLLVM(Module *LLVMModule, SPIRVModule *TheSPIRVModule)
283 :M(LLVMModule), BM(TheSPIRVModule), DbgTran(BM, M){
284 assert(M);
285 Context = &M->getContext();
286 }
287
288 std::string getOCLBuiltinName(SPIRVInstruction* BI);
289 std::string getOCLConvertBuiltinName(SPIRVInstruction *BI);
290 std::string getOCLGenericCastToPtrName(SPIRVInstruction *BI);
291
292 Type *transType(SPIRVType *BT, bool IsClassMember = false);
293 std::string transTypeToOCLTypeName(SPIRVType *BT, bool IsSigned = true);
294 std::vector<Type *> transTypeVector(const std::vector<SPIRVType *>&);
295 bool translate();
296 bool transAddressingModel();
297
298 Value *transValue(SPIRVValue *, Function *F, BasicBlock *,
299 bool CreatePlaceHolder = true);
300 Value *transValueWithoutDecoration(SPIRVValue *, Function *F, BasicBlock *,
301 bool CreatePlaceHolder = true);
302 bool transDecoration(SPIRVValue *, Value *);
303 bool transAlign(SPIRVValue *, Value *);
304 Instruction *transOCLBuiltinFromExtInst(SPIRVExtInst *BC, BasicBlock *BB);
305 std::vector<Value *> transValue(const std::vector<SPIRVValue *>&, Function *F,
306 BasicBlock *);
307 Function *transFunction(SPIRVFunction *F);
308 bool transFPContractMetadata();
309 bool transKernelMetadata();
310 bool transNonTemporalMetadata(Instruction *I);
311 bool transSourceLanguage();
312 bool transSourceExtension();
313 void transGeneratorMD();
314 Value *transConvertInst(SPIRVValue* BV, Function* F, BasicBlock* BB);
315 Instruction *transBuiltinFromInst(const std::string& FuncName,
316 SPIRVInstruction* BI, BasicBlock* BB);
317 Instruction *transOCLBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB);
318 Instruction *transSPIRVBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB);
319 Instruction *transOCLBarrierFence(SPIRVInstruction* BI, BasicBlock *BB);
320 void transOCLVectorLoadStore(std::string& UnmangledName,
321 std::vector<SPIRVWord> &BArgs);
322
323 /// Post-process translated LLVM module for OpenCL.
324 bool postProcessOCL();
325
326 /// \brief Post-process OpenCL builtin functions returning struct type.
327 ///
328 /// Some OpenCL builtin functions are translated to SPIR-V instructions with
329 /// struct type result, e.g. NDRange creation functions. Such functions
330 /// need to be post-processed to return the struct through sret argument.
331 bool postProcessOCLBuiltinReturnStruct(Function *F);
332
333 /// \brief Post-process OpenCL builtin functions having block argument.
334 ///
335 /// These functions are translated to functions with function pointer type
336 /// argument first, then post-processed to have block argument.
337 bool postProcessOCLBuiltinWithFuncPointer(Function *F,
338 Function::arg_iterator I);
339
340 /// \brief Post-process OpenCL builtin functions having array argument.
341 ///
342 /// These functions are translated to functions with array type argument
343 /// first, then post-processed to have pointer arguments.
344 bool postProcessOCLBuiltinWithArrayArguments(Function *F,
345 const std::string &DemangledName);
346
347 /// \brief Post-process OpImageSampleExplicitLod.
348 /// sampled_image = __spirv_SampledImage__(image, sampler);
349 /// return __spirv_ImageSampleExplicitLod__(sampled_image, image_operands,
350 /// ...);
351 /// =>
352 /// read_image(image, sampler, ...)
353 /// \return transformed call instruction.
354 Instruction *postProcessOCLReadImage(SPIRVInstruction *BI, CallInst *CI,
355 const std::string &DemangledName);
356
357 /// \brief Post-process OpImageWrite.
358 /// return write_image(image, coord, color, image_operands, ...);
359 /// =>
360 /// write_image(image, coord, ..., color)
361 /// \return transformed call instruction.
362 CallInst *postProcessOCLWriteImage(SPIRVInstruction *BI, CallInst *CI,
363 const std::string &DemangledName);
364
365 /// \brief Post-process OpBuildNDRange.
366 /// OpBuildNDRange GlobalWorkSize, LocalWorkSize, GlobalWorkOffset
367 /// =>
368 /// call ndrange_XD(GlobalWorkOffset, GlobalWorkSize, LocalWorkSize)
369 /// \return transformed call instruction.
370 CallInst *postProcessOCLBuildNDRange(SPIRVInstruction *BI, CallInst *CI,
371 const std::string &DemangledName);
372
373 /// \brief Expand OCL builtin functions with scalar argument, e.g.
374 /// step, smoothstep.
375 /// gentype func (fp edge, gentype x)
376 /// =>
377 /// gentype func (gentype edge, gentype x)
378 /// \return transformed call instruction.
379 CallInst *expandOCLBuiltinWithScalarArg(CallInst* CI,
380 const std::string &FuncName);
381
382 /// \brief Post-process OpGroupAll and OpGroupAny instructions translation.
383 /// i1 func (<n x i1> arg)
384 /// =>
385 /// i32 func (<n x i32> arg)
386 /// \return transformed call instruction.
387 Instruction *postProcessGroupAllAny(CallInst *CI,
388 const std::string &DemangledName);
389
390 typedef DenseMap<SPIRVType *, Type *> SPIRVToLLVMTypeMap;
391 typedef DenseMap<SPIRVValue *, Value *> SPIRVToLLVMValueMap;
392 typedef DenseMap<SPIRVFunction *, Function *> SPIRVToLLVMFunctionMap;
393 typedef DenseMap<GlobalVariable *, SPIRVBuiltinVariableKind> BuiltinVarMap;
394
395 // A SPIRV value may be translated to a load instruction of a placeholder
396 // global variable. This map records load instruction of these placeholders
397 // which are supposed to be replaced by the real values later.
398 typedef std::map<SPIRVValue *, LoadInst*> SPIRVToLLVMPlaceholderMap;
399 private:
400 Module *M;
401 BuiltinVarMap BuiltinGVMap;
402 LLVMContext *Context;
403 SPIRVModule *BM;
404 SPIRVToLLVMTypeMap TypeMap;
405 SPIRVToLLVMValueMap ValueMap;
406 SPIRVToLLVMFunctionMap FuncMap;
407 SPIRVToLLVMPlaceholderMap PlaceholderMap;
408 SPIRVToLLVMDbgTran DbgTran;
409
mapType(SPIRVType * BT,Type * T)410 Type *mapType(SPIRVType *BT, Type *T) {
411 SPIRVDBG(dbgs() << *T << '\n';)
412 TypeMap[BT] = T;
413 return T;
414 }
415
416 // If a value is mapped twice, the existing mapped value is a placeholder,
417 // which must be a load instruction of a global variable whose name starts
418 // with kPlaceholderPrefix.
mapValue(SPIRVValue * BV,Value * V)419 Value *mapValue(SPIRVValue *BV, Value *V) {
420 auto Loc = ValueMap.find(BV);
421 if (Loc != ValueMap.end()) {
422 if (Loc->second == V)
423 return V;
424 auto LD = dyn_cast<LoadInst>(Loc->second);
425 auto Placeholder = dyn_cast<GlobalVariable>(LD->getPointerOperand());
426 assert (LD && Placeholder &&
427 Placeholder->getName().startswith(kPlaceholderPrefix) &&
428 "A value is translated twice");
429 // Replaces placeholders for PHI nodes
430 LD->replaceAllUsesWith(V);
431 LD->dropAllReferences();
432 LD->removeFromParent();
433 Placeholder->dropAllReferences();
434 Placeholder->removeFromParent();
435 }
436 ValueMap[BV] = V;
437 return V;
438 }
439
isSPIRVBuiltinVariable(GlobalVariable * GV,SPIRVBuiltinVariableKind * Kind=nullptr)440 bool isSPIRVBuiltinVariable(GlobalVariable *GV,
441 SPIRVBuiltinVariableKind *Kind = nullptr) {
442 auto Loc = BuiltinGVMap.find(GV);
443 if (Loc == BuiltinGVMap.end())
444 return false;
445 if (Kind)
446 *Kind = Loc->second;
447 return true;
448 }
449 // OpenCL function always has NoUnwound attribute.
450 // Change this if it is no longer true.
isFuncNoUnwind() const451 bool isFuncNoUnwind() const { return true;}
452 bool isSPIRVCmpInstTransToLLVMInst(SPIRVInstruction *BI) const;
453 bool transOCLBuiltinsFromVariables();
454 bool transOCLBuiltinFromVariable(GlobalVariable *GV,
455 SPIRVBuiltinVariableKind Kind);
456 MDString *transOCLKernelArgTypeName(SPIRVFunctionParameter *);
457
mapFunction(SPIRVFunction * BF,Function * F)458 Value *mapFunction(SPIRVFunction *BF, Function *F) {
459 SPIRVDBG(spvdbgs() << "[mapFunction] " << *BF << " -> ";
460 dbgs() << *F << '\n';)
461 FuncMap[BF] = F;
462 return F;
463 }
464
465 Value *getTranslatedValue(SPIRVValue *BV);
466 Type *getTranslatedType(SPIRVType *BT);
467
getErrorLog()468 SPIRVErrorLog &getErrorLog() {
469 return BM->getErrorLog();
470 }
471
setCallingConv(CallInst * Call)472 void setCallingConv(CallInst *Call) {
473 Function *F = Call->getCalledFunction();
474 assert(F);
475 Call->setCallingConv(F->getCallingConv());
476 }
477
478 void setAttrByCalledFunc(CallInst *Call);
479 Type *transFPType(SPIRVType* T);
480 BinaryOperator *transShiftLogicalBitwiseInst(SPIRVValue* BV, BasicBlock* BB,
481 Function* F);
482 void transFlags(llvm::Value* V);
483 Instruction *transCmpInst(SPIRVValue* BV, BasicBlock* BB, Function* F);
484 void transOCLBuiltinFromInstPreproc(SPIRVInstruction* BI, Type *&RetTy,
485 std::vector<SPIRVValue *> &Args);
486 Instruction* transOCLBuiltinPostproc(SPIRVInstruction* BI,
487 CallInst* CI, BasicBlock* BB, const std::string &DemangledName);
488 std::string transOCLImageTypeName(SPIRV::SPIRVTypeImage* ST);
489 std::string transOCLSampledImageTypeName(SPIRV::SPIRVTypeSampledImage* ST);
490 std::string transOCLPipeTypeName(SPIRV::SPIRVTypePipe* ST,
491 bool UseSPIRVFriendlyFormat = false, int PipeAccess = 0);
492 std::string transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage* PST);
493 std::string transOCLImageTypeAccessQualifier(SPIRV::SPIRVTypeImage* ST);
494 std::string transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe* ST);
495
496 Value *oclTransConstantSampler(SPIRV::SPIRVConstantSampler* BCS);
497 Value * oclTransConstantPipeStorage(SPIRV::SPIRVConstantPipeStorage* BCPS);
498 void setName(llvm::Value* V, SPIRVValue* BV);
499 void insertImageNameAccessQualifier(SPIRV::SPIRVTypeImage* ST, std::string &Name);
500 template<class Source, class Func>
501 bool foreachFuncCtlMask(Source, Func);
502 llvm::GlobalValue::LinkageTypes transLinkageType(const SPIRVValue* V);
503 Instruction *transOCLAllAny(SPIRVInstruction* BI, BasicBlock *BB);
504 Instruction *transOCLRelational(SPIRVInstruction* BI, BasicBlock *BB);
505
506 CallInst *transOCLBarrier(BasicBlock *BB, SPIRVWord ExecScope,
507 SPIRVWord MemSema, SPIRVWord MemScope);
508
509 CallInst *transOCLMemFence(BasicBlock *BB,
510 SPIRVWord MemSema, SPIRVWord MemScope);
511 };
512
513 Type *
getTranslatedType(SPIRVType * BV)514 SPIRVToLLVM::getTranslatedType(SPIRVType *BV){
515 auto Loc = TypeMap.find(BV);
516 if (Loc != TypeMap.end())
517 return Loc->second;
518 return nullptr;
519 }
520
521 Value *
getTranslatedValue(SPIRVValue * BV)522 SPIRVToLLVM::getTranslatedValue(SPIRVValue *BV){
523 auto Loc = ValueMap.find(BV);
524 if (Loc != ValueMap.end())
525 return Loc->second;
526 return nullptr;
527 }
528
529 void
setAttrByCalledFunc(CallInst * Call)530 SPIRVToLLVM::setAttrByCalledFunc(CallInst *Call) {
531 Function *F = Call->getCalledFunction();
532 assert(F);
533 if (F->isIntrinsic()) {
534 return;
535 }
536 Call->setCallingConv(F->getCallingConv());
537 Call->setAttributes(F->getAttributes());
538 }
539
540 bool
transOCLBuiltinsFromVariables()541 SPIRVToLLVM::transOCLBuiltinsFromVariables(){
542 std::vector<GlobalVariable *> WorkList;
543 for (auto I = M->global_begin(), E = M->global_end(); I != E; ++I) {
544 SPIRVBuiltinVariableKind Kind;
545 auto I1 = static_cast<GlobalVariable*>(I);
546 if (!isSPIRVBuiltinVariable(I1, &Kind))
547 continue;
548 if (!transOCLBuiltinFromVariable(I1, Kind))
549 return false;
550 WorkList.push_back(I1);
551 }
552 for (auto &I:WorkList) {
553 I->dropAllReferences();
554 I->removeFromParent();
555 }
556 return true;
557 }
558
559 // For integer types shorter than 32 bit, unsigned/signedness can be inferred
560 // from zext/sext attribute.
561 MDString *
transOCLKernelArgTypeName(SPIRVFunctionParameter * Arg)562 SPIRVToLLVM::transOCLKernelArgTypeName(SPIRVFunctionParameter *Arg) {
563 auto Ty = Arg->isByVal() ? Arg->getType()->getPointerElementType() :
564 Arg->getType();
565 return MDString::get(*Context, transTypeToOCLTypeName(Ty, !Arg->isZext()));
566 }
567
568 // Variable like GlobalInvolcationId[x] -> get_global_id(x).
569 // Variable like WorkDim -> get_work_dim().
570 bool
transOCLBuiltinFromVariable(GlobalVariable * GV,SPIRVBuiltinVariableKind Kind)571 SPIRVToLLVM::transOCLBuiltinFromVariable(GlobalVariable *GV,
572 SPIRVBuiltinVariableKind Kind) {
573 std::string FuncName = SPIRSPIRVBuiltinVariableMap::rmap(Kind);
574 std::string MangledName;
575 Type *ReturnTy = GV->getType()->getPointerElementType();
576 bool IsVec = ReturnTy->isVectorTy();
577 if (IsVec)
578 ReturnTy = cast<VectorType>(ReturnTy)->getElementType();
579 std::vector<Type*> ArgTy;
580 if (IsVec)
581 ArgTy.push_back(Type::getInt32Ty(*Context));
582 MangleOpenCLBuiltin(FuncName, ArgTy, MangledName);
583 Function *Func = M->getFunction(MangledName);
584 if (!Func) {
585 FunctionType *FT = FunctionType::get(ReturnTy, ArgTy, false);
586 Func = Function::Create(FT, GlobalValue::ExternalLinkage, MangledName, M);
587 Func->setCallingConv(CallingConv::SPIR_FUNC);
588 Func->addFnAttr(Attribute::NoUnwind);
589 Func->addFnAttr(Attribute::ReadNone);
590 }
591 std::vector<Instruction *> Deletes;
592 std::vector<Instruction *> Uses;
593 for (auto UI = GV->user_begin(), UE = GV->user_end(); UI != UE; ++UI) {
594 assert (isa<LoadInst>(*UI) && "Unsupported use");
595 auto LD = dyn_cast<LoadInst>(*UI);
596 if (!IsVec) {
597 Uses.push_back(LD);
598 Deletes.push_back(LD);
599 continue;
600 }
601 for (auto LDUI = LD->user_begin(), LDUE = LD->user_end(); LDUI != LDUE;
602 ++LDUI) {
603 assert(isa<ExtractElementInst>(*LDUI) && "Unsupported use");
604 auto EEI = dyn_cast<ExtractElementInst>(*LDUI);
605 Uses.push_back(EEI);
606 Deletes.push_back(EEI);
607 }
608 Deletes.push_back(LD);
609 }
610 for (auto &I:Uses) {
611 std::vector<Value *> Arg;
612 if (auto EEI = dyn_cast<ExtractElementInst>(I))
613 Arg.push_back(EEI->getIndexOperand());
614 auto Call = CallInst::Create(Func, Arg, "", I);
615 Call->takeName(I);
616 setAttrByCalledFunc(Call);
617 SPIRVDBG(dbgs() << "[transOCLBuiltinFromVariable] " << *I << " -> " <<
618 *Call << '\n';)
619 I->replaceAllUsesWith(Call);
620 }
621 for (auto &I:Deletes) {
622 I->dropAllReferences();
623 I->removeFromParent();
624 }
625 return true;
626 }
627
628 Type *
transFPType(SPIRVType * T)629 SPIRVToLLVM::transFPType(SPIRVType* T) {
630 switch(T->getFloatBitWidth()) {
631 case 16: return Type::getHalfTy(*Context);
632 case 32: return Type::getFloatTy(*Context);
633 case 64: return Type::getDoubleTy(*Context);
634 default:
635 llvm_unreachable("Invalid type");
636 return nullptr;
637 }
638 }
639
640 std::string
transOCLImageTypeName(SPIRV::SPIRVTypeImage * ST)641 SPIRVToLLVM::transOCLImageTypeName(SPIRV::SPIRVTypeImage* ST) {
642 std::string Name = std::string(kSPR2TypeName::OCLPrefix)
643 + rmap<std::string>(ST->getDescriptor());
644 if (SPIRVGenImgTypeAccQualPostfix)
645 SPIRVToLLVM::insertImageNameAccessQualifier(ST, Name);
646 return Name;
647 }
648
649 std::string
transOCLSampledImageTypeName(SPIRV::SPIRVTypeSampledImage * ST)650 SPIRVToLLVM::transOCLSampledImageTypeName(SPIRV::SPIRVTypeSampledImage* ST) {
651 return getSPIRVTypeName(kSPIRVTypeName::SampledImg,
652 getSPIRVImageTypePostfixes(getSPIRVImageSampledTypeName(
653 ST->getImageType()->getSampledType()),
654 ST->getImageType()->getDescriptor(),
655 ST->getImageType()->getAccessQualifier()));
656 }
657
658 std::string
transOCLPipeTypeName(SPIRV::SPIRVTypePipe * PT,bool UseSPIRVFriendlyFormat,int PipeAccess)659 SPIRVToLLVM::transOCLPipeTypeName(SPIRV::SPIRVTypePipe* PT,
660 bool UseSPIRVFriendlyFormat, int PipeAccess){
661 if (!UseSPIRVFriendlyFormat)
662 return kSPR2TypeName::Pipe;
663 else
664 return std::string(kSPIRVTypeName::PrefixAndDelim)
665 + kSPIRVTypeName::Pipe
666 + kSPIRVTypeName::Delimiter
667 + kSPIRVTypeName::PostfixDelim
668 + PipeAccess;
669 }
670
671 std::string
transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage * PST)672 SPIRVToLLVM::transOCLPipeStorageTypeName(SPIRV::SPIRVTypePipeStorage* PST) {
673 return std::string(kSPIRVTypeName::PrefixAndDelim)
674 + kSPIRVTypeName::PipeStorage;
675 }
676
677 Type *
transType(SPIRVType * T,bool IsClassMember)678 SPIRVToLLVM::transType(SPIRVType *T, bool IsClassMember) {
679 auto Loc = TypeMap.find(T);
680 if (Loc != TypeMap.end())
681 return Loc->second;
682
683 SPIRVDBG(spvdbgs() << "[transType] " << *T << " -> ";)
684 T->validate();
685 switch(T->getOpCode()) {
686 case OpTypeVoid:
687 return mapType(T, Type::getVoidTy(*Context));
688 case OpTypeBool:
689 return mapType(T, Type::getInt1Ty(*Context));
690 case OpTypeInt:
691 return mapType(T, Type::getIntNTy(*Context, T->getIntegerBitWidth()));
692 case OpTypeFloat:
693 return mapType(T, transFPType(T));
694 case OpTypeArray:
695 return mapType(T, ArrayType::get(transType(T->getArrayElementType()),
696 T->getArrayLength()));
697 case OpTypePointer:
698 return mapType(T, PointerType::get(transType(
699 T->getPointerElementType(), IsClassMember),
700 SPIRSPIRVAddrSpaceMap::rmap(T->getPointerStorageClass())));
701 case OpTypeVector:
702 return mapType(T, VectorType::get(transType(T->getVectorComponentType()),
703 T->getVectorComponentCount()));
704 case OpTypeOpaque:
705 return mapType(T, StructType::create(*Context, T->getName()));
706 case OpTypeFunction: {
707 auto FT = static_cast<SPIRVTypeFunction *>(T);
708 auto RT = transType(FT->getReturnType());
709 std::vector<Type *> PT;
710 for (size_t I = 0, E = FT->getNumParameters(); I != E; ++I)
711 PT.push_back(transType(FT->getParameterType(I)));
712 return mapType(T, FunctionType::get(RT, PT, false));
713 }
714 case OpTypeImage: {
715 auto ST = static_cast<SPIRVTypeImage *>(T);
716 if (ST->isOCLImage())
717 return mapType(T, getOrCreateOpaquePtrType(M,
718 transOCLImageTypeName(ST)));
719 else
720 llvm_unreachable("Unsupported image type");
721 return nullptr;
722 }
723 case OpTypeSampler:
724 return mapType(T, Type::getInt32Ty(*Context));
725 case OpTypeSampledImage: {
726 auto ST = static_cast<SPIRVTypeSampledImage *>(T);
727 return mapType(T, getOrCreateOpaquePtrType(M,
728 transOCLSampledImageTypeName(ST)));
729 }
730 case OpTypeStruct: {
731 auto ST = static_cast<SPIRVTypeStruct *>(T);
732 auto Name = ST->getName();
733 if (!Name.empty()) {
734 if (auto OldST = M->getTypeByName(Name))
735 OldST->setName("");
736 }
737 auto *StructTy = StructType::create(*Context, Name);
738 mapType(ST, StructTy);
739 SmallVector<Type *, 4> MT;
740 for (size_t I = 0, E = ST->getMemberCount(); I != E; ++I)
741 MT.push_back(transType(ST->getMemberType(I), true));
742 StructTy->setBody(MT, ST->isPacked());
743 return StructTy;
744 }
745 case OpTypePipe: {
746 auto PT = static_cast<SPIRVTypePipe *>(T);
747 return mapType(T, getOrCreateOpaquePtrType(M,
748 transOCLPipeTypeName(PT, IsClassMember, PT->getAccessQualifier()),
749 getOCLOpaqueTypeAddrSpace(T->getOpCode())));
750
751 }
752 case OpTypePipeStorage: {
753 auto PST = static_cast<SPIRVTypePipeStorage *>(T);
754 return mapType(T, getOrCreateOpaquePtrType(M,
755 transOCLPipeStorageTypeName(PST),
756 getOCLOpaqueTypeAddrSpace(T->getOpCode())));
757 }
758 default: {
759 auto OC = T->getOpCode();
760 if (isOpaqueGenericTypeOpCode(OC))
761 return mapType(T, getOrCreateOpaquePtrType(M,
762 OCLOpaqueTypeOpCodeMap::rmap(OC),
763 getOCLOpaqueTypeAddrSpace(OC)));
764 llvm_unreachable("Not implemented");
765 }
766 }
767 return 0;
768 }
769
770 std::string
transTypeToOCLTypeName(SPIRVType * T,bool IsSigned)771 SPIRVToLLVM::transTypeToOCLTypeName(SPIRVType *T, bool IsSigned) {
772 switch(T->getOpCode()) {
773 case OpTypeVoid:
774 return "void";
775 case OpTypeBool:
776 return "bool";
777 case OpTypeInt: {
778 std::string Prefix = IsSigned ? "" : "u";
779 switch(T->getIntegerBitWidth()) {
780 case 8:
781 return Prefix + "char";
782 case 16:
783 return Prefix + "short";
784 case 32:
785 return Prefix + "int";
786 case 64:
787 return Prefix + "long";
788 default:
789 llvm_unreachable("invalid integer size");
790 return Prefix + std::string("int") + T->getIntegerBitWidth() + "_t";
791 }
792 }
793 break;
794 case OpTypeFloat:
795 switch(T->getFloatBitWidth()){
796 case 16:
797 return "half";
798 case 32:
799 return "float";
800 case 64:
801 return "double";
802 default:
803 llvm_unreachable("invalid floating pointer bitwidth");
804 return std::string("float") + T->getFloatBitWidth() + "_t";
805 }
806 break;
807 case OpTypeArray:
808 return "array";
809 case OpTypePointer:
810 return transTypeToOCLTypeName(T->getPointerElementType()) + "*";
811 case OpTypeVector:
812 return transTypeToOCLTypeName(T->getVectorComponentType()) +
813 T->getVectorComponentCount();
814 case OpTypeOpaque:
815 return T->getName();
816 case OpTypeFunction:
817 llvm_unreachable("Unsupported");
818 return "function";
819 case OpTypeStruct: {
820 auto Name = T->getName();
821 if (Name.find("struct.") == 0)
822 Name[6] = ' ';
823 else if (Name.find("union.") == 0)
824 Name[5] = ' ';
825 return Name;
826 }
827 case OpTypePipe:
828 return "pipe";
829 case OpTypeSampler:
830 return "sampler_t";
831 case OpTypeImage: {
832 std::string Name;
833 Name = rmap<std::string>(static_cast<SPIRVTypeImage *>(T)->getDescriptor());
834 if (SPIRVGenImgTypeAccQualPostfix) {
835 auto ST = static_cast<SPIRVTypeImage *>(T);
836 insertImageNameAccessQualifier(ST, Name);
837 }
838 return Name;
839 }
840 default:
841 if (isOpaqueGenericTypeOpCode(T->getOpCode())) {
842 return OCLOpaqueTypeOpCodeMap::rmap(T->getOpCode());
843 }
844 llvm_unreachable("Not implemented");
845 return "unknown";
846 }
847 }
848
849 std::vector<Type *>
transTypeVector(const std::vector<SPIRVType * > & BT)850 SPIRVToLLVM::transTypeVector(const std::vector<SPIRVType *> &BT) {
851 std::vector<Type *> T;
852 for (auto I: BT)
853 T.push_back(transType(I));
854 return T;
855 }
856
857 std::vector<Value *>
transValue(const std::vector<SPIRVValue * > & BV,Function * F,BasicBlock * BB)858 SPIRVToLLVM::transValue(const std::vector<SPIRVValue *> &BV, Function *F,
859 BasicBlock *BB) {
860 std::vector<Value *> V;
861 for (auto I: BV)
862 V.push_back(transValue(I, F, BB));
863 return V;
864 }
865
866 bool
isSPIRVCmpInstTransToLLVMInst(SPIRVInstruction * BI) const867 SPIRVToLLVM::isSPIRVCmpInstTransToLLVMInst(SPIRVInstruction* BI) const {
868 auto OC = BI->getOpCode();
869 return isCmpOpCode(OC) &&
870 !(OC >= OpLessOrGreater && OC <= OpUnordered);
871 }
872
873 void
transFlags(llvm::Value * V)874 SPIRVToLLVM::transFlags(llvm::Value* V) {
875 if(!isa<Instruction>(V))
876 return;
877 auto OC = cast<Instruction>(V)->getOpcode();
878 if (OC == Instruction::AShr || OC == Instruction::LShr) {
879 cast<BinaryOperator>(V)->setIsExact();
880 return;
881 }
882 }
883
884 void
setName(llvm::Value * V,SPIRVValue * BV)885 SPIRVToLLVM::setName(llvm::Value* V, SPIRVValue* BV) {
886 auto Name = BV->getName();
887 if (!Name.empty() && (!V->hasName() || Name != V->getName()))
888 V->setName(Name);
889 }
890
insertImageNameAccessQualifier(SPIRV::SPIRVTypeImage * ST,std::string & Name)891 void SPIRVToLLVM::insertImageNameAccessQualifier(SPIRV::SPIRVTypeImage* ST, std::string &Name) {
892 std::string QName = rmap<std::string>(ST->getAccessQualifier());
893 // transform: read_only -> ro, write_only -> wo, read_write -> rw
894 QName = QName.substr(0,1) + QName.substr(QName.find("_") + 1, 1) + "_";
895 assert(!Name.empty() && "image name should not be empty");
896 Name.insert(Name.size() - 1, QName);
897 }
898
899 Value *
transValue(SPIRVValue * BV,Function * F,BasicBlock * BB,bool CreatePlaceHolder)900 SPIRVToLLVM::transValue(SPIRVValue *BV, Function *F, BasicBlock *BB,
901 bool CreatePlaceHolder){
902 SPIRVToLLVMValueMap::iterator Loc = ValueMap.find(BV);
903 if (Loc != ValueMap.end() && (!PlaceholderMap.count(BV) || CreatePlaceHolder))
904 return Loc->second;
905
906 SPIRVDBG(spvdbgs() << "[transValue] " << *BV << " -> ";)
907 BV->validate();
908
909 auto V = transValueWithoutDecoration(BV, F, BB, CreatePlaceHolder);
910 if (!V) {
911 SPIRVDBG(dbgs() << " Warning ! nullptr\n";)
912 return nullptr;
913 }
914 setName(V, BV);
915 if (!transDecoration(BV, V)) {
916 assert (0 && "trans decoration fail");
917 return nullptr;
918 }
919 transFlags(V);
920
921 SPIRVDBG(dbgs() << *V << '\n';)
922
923 return V;
924 }
925
926 Value *
transConvertInst(SPIRVValue * BV,Function * F,BasicBlock * BB)927 SPIRVToLLVM::transConvertInst(SPIRVValue* BV, Function* F, BasicBlock* BB) {
928 SPIRVUnary* BC = static_cast<SPIRVUnary*>(BV);
929 auto Src = transValue(BC->getOperand(0), F, BB, BB ? true : false);
930 auto Dst = transType(BC->getType());
931 CastInst::CastOps CO = Instruction::BitCast;
932 bool IsExt = Dst->getScalarSizeInBits()
933 > Src->getType()->getScalarSizeInBits();
934 switch (BC->getOpCode()) {
935 case OpPtrCastToGeneric:
936 case OpGenericCastToPtr:
937 CO = Instruction::AddrSpaceCast;
938 break;
939 case OpSConvert:
940 CO = IsExt ? Instruction::SExt : Instruction::Trunc;
941 break;
942 case OpUConvert:
943 CO = IsExt ? Instruction::ZExt : Instruction::Trunc;
944 break;
945 case OpFConvert:
946 CO = IsExt ? Instruction::FPExt : Instruction::FPTrunc;
947 break;
948 default:
949 CO = static_cast<CastInst::CastOps>(OpCodeMap::rmap(BC->getOpCode()));
950 }
951 assert(CastInst::isCast(CO) && "Invalid cast op code");
952 SPIRVDBG(if (!CastInst::castIsValid(CO, Src, Dst)) {
953 spvdbgs() << "Invalid cast: " << *BV << " -> ";
954 dbgs() << "Op = " << CO << ", Src = " << *Src << " Dst = " << *Dst << '\n';
955 })
956 if (BB)
957 return CastInst::Create(CO, Src, Dst, BV->getName(), BB);
958 return ConstantExpr::getCast(CO, dyn_cast<Constant>(Src), Dst);
959 }
960
transShiftLogicalBitwiseInst(SPIRVValue * BV,BasicBlock * BB,Function * F)961 BinaryOperator *SPIRVToLLVM::transShiftLogicalBitwiseInst(SPIRVValue* BV,
962 BasicBlock* BB,Function* F) {
963 SPIRVBinary* BBN = static_cast<SPIRVBinary*>(BV);
964 assert(BB && "Invalid BB");
965 Instruction::BinaryOps BO;
966 auto OP = BBN->getOpCode();
967 if (isLogicalOpCode(OP))
968 OP = IntBoolOpMap::rmap(OP);
969 BO = static_cast<Instruction::BinaryOps>(OpCodeMap::rmap(OP));
970 auto Inst = BinaryOperator::Create(BO,
971 transValue(BBN->getOperand(0), F, BB),
972 transValue(BBN->getOperand(1), F, BB), BV->getName(), BB);
973 return Inst;
974 }
975
976 Instruction *
transCmpInst(SPIRVValue * BV,BasicBlock * BB,Function * F)977 SPIRVToLLVM::transCmpInst(SPIRVValue* BV, BasicBlock* BB, Function* F) {
978 SPIRVCompare* BC = static_cast<SPIRVCompare*>(BV);
979 assert(BB && "Invalid BB");
980 SPIRVType* BT = BC->getOperand(0)->getType();
981 Instruction* Inst = nullptr;
982 auto OP = BC->getOpCode();
983 if (isLogicalOpCode(OP))
984 OP = IntBoolOpMap::rmap(OP);
985 if (BT->isTypeVectorOrScalarInt() || BT->isTypeVectorOrScalarBool() ||
986 BT->isTypePointer())
987 Inst = new ICmpInst(*BB, CmpMap::rmap(OP),
988 transValue(BC->getOperand(0), F, BB),
989 transValue(BC->getOperand(1), F, BB));
990 else if (BT->isTypeVectorOrScalarFloat())
991 Inst = new FCmpInst(*BB, CmpMap::rmap(OP),
992 transValue(BC->getOperand(0), F, BB),
993 transValue(BC->getOperand(1), F, BB));
994 assert(Inst && "not implemented");
995 return Inst;
996 }
997
998 bool
postProcessOCL()999 SPIRVToLLVM::postProcessOCL() {
1000 std::string DemangledName;
1001 SPIRVWord SrcLangVer = 0;
1002 BM->getSourceLanguage(&SrcLangVer);
1003 bool isCPP = SrcLangVer == kOCLVer::CL21;
1004 for (auto I = M->begin(), E = M->end(); I != E;) {
1005 auto F = I++;
1006 if (F->hasName() && F->isDeclaration()) {
1007 DEBUG(dbgs() << "[postProcessOCL sret] " << *F << '\n');
1008 if (F->getReturnType()->isStructTy() &&
1009 oclIsBuiltin(F->getName(), &DemangledName, isCPP)) {
1010 if (!postProcessOCLBuiltinReturnStruct(static_cast<Function*>(F)))
1011 return false;
1012 }
1013 }
1014 }
1015 for (auto I = M->begin(), E = M->end(); I != E;) {
1016 auto F = static_cast<Function*>(I++);
1017 if (F->hasName() && F->isDeclaration()) {
1018 DEBUG(dbgs() << "[postProcessOCL func ptr] " << *F << '\n');
1019 auto AI = F->arg_begin();
1020 if (hasFunctionPointerArg(F, AI) && isDecoratedSPIRVFunc(F))
1021 if (!postProcessOCLBuiltinWithFuncPointer(F, AI))
1022 return false;
1023 }
1024 }
1025 for (auto I = M->begin(), E = M->end(); I != E;) {
1026 auto F = static_cast<Function*>(I++);
1027 if (F->hasName() && F->isDeclaration()) {
1028 DEBUG(dbgs() << "[postProcessOCL array arg] " << *F << '\n');
1029 if (hasArrayArg(F) && oclIsBuiltin(F->getName(), &DemangledName, isCPP))
1030 if (!postProcessOCLBuiltinWithArrayArguments(F, DemangledName))
1031 return false;
1032 }
1033 }
1034 return true;
1035 }
1036
1037 bool
postProcessOCLBuiltinReturnStruct(Function * F)1038 SPIRVToLLVM::postProcessOCLBuiltinReturnStruct(Function *F) {
1039 std::string Name = F->getName();
1040 F->setName(Name + ".old");
1041 for (auto I = F->user_begin(), E = F->user_end(); I != E;) {
1042 if (auto CI = dyn_cast<CallInst>(*I++)) {
1043 auto ST = dyn_cast<StoreInst>(*(CI->user_begin()));
1044 assert(ST);
1045 std::vector<Type *> ArgTys;
1046 getFunctionTypeParameterTypes(F->getFunctionType(), ArgTys);
1047 ArgTys.insert(ArgTys.begin(), PointerType::get(F->getReturnType(),
1048 SPIRAS_Private));
1049 auto newF = getOrCreateFunction(M, Type::getVoidTy(*Context),
1050 ArgTys, Name);
1051 newF->setCallingConv(F->getCallingConv());
1052 auto Args = getArguments(CI);
1053 Args.insert(Args.begin(), ST->getPointerOperand());
1054 auto NewCI = CallInst::Create(newF, Args, CI->getName(), CI);
1055 NewCI->setCallingConv(CI->getCallingConv());
1056 ST->dropAllReferences();
1057 ST->removeFromParent();
1058 CI->dropAllReferences();
1059 CI->removeFromParent();
1060 }
1061 }
1062 F->dropAllReferences();
1063 F->removeFromParent();
1064 return true;
1065 }
1066
1067 bool
postProcessOCLBuiltinWithFuncPointer(Function * F,Function::arg_iterator I)1068 SPIRVToLLVM::postProcessOCLBuiltinWithFuncPointer(Function* F,
1069 Function::arg_iterator I) {
1070 auto Name = undecorateSPIRVFunction(F->getName());
1071 std::set<Value *> InvokeFuncPtrs;
1072 mutateFunctionOCL (F, [=, &InvokeFuncPtrs](
1073 CallInst *CI, std::vector<Value *> &Args) {
1074 auto ALoc = std::find_if(Args.begin(), Args.end(), [](Value * elem) {
1075 return isFunctionPointerType(elem->getType());
1076 });
1077 assert(ALoc != Args.end() && "Buit-in must accept a pointer to function");
1078 assert(isa<Function>(*ALoc) && "Invalid function pointer usage");
1079 Value *Ctx = ALoc[1];
1080 Value *CtxLen = ALoc[2];
1081 Value *CtxAlign = ALoc[3];
1082 if (Name == kOCLBuiltinName::EnqueueKernel)
1083 assert(Args.end() - ALoc > 3);
1084 else
1085 assert(Args.end() - ALoc > 0);
1086 // Erase arguments what are hanled by "spir_block_bind" according to SPIR 2.0
1087 Args.erase(ALoc + 1, ALoc + 4);
1088
1089 InvokeFuncPtrs.insert(*ALoc);
1090 // There will be as many calls to spir_block_bind as how much device execution
1091 // bult-ins using this block. This doesn't contradict SPIR 2.0 specification.
1092 *ALoc = addBlockBind(M, cast<Function>(removeCast(*ALoc)),
1093 Ctx, CtxLen, CtxAlign, CI);
1094 return Name;
1095 });
1096 for (auto &I:InvokeFuncPtrs)
1097 eraseIfNoUse(I);
1098 return true;
1099 }
1100
1101 bool
postProcessOCLBuiltinWithArrayArguments(Function * F,const std::string & DemangledName)1102 SPIRVToLLVM::postProcessOCLBuiltinWithArrayArguments(Function* F,
1103 const std::string &DemangledName) {
1104 DEBUG(dbgs() << "[postProcessOCLBuiltinWithArrayArguments] " << *F << '\n');
1105 auto Attrs = F->getAttributes();
1106 auto Name = F->getName();
1107 mutateFunction(F, [=](CallInst *CI, std::vector<Value *> &Args) {
1108 auto FBegin = CI->getParent()->getParent()->begin()->getFirstInsertionPt();
1109 for (auto &I:Args) {
1110 auto T = I->getType();
1111 if (!T->isArrayTy())
1112 continue;
1113 auto Alloca = new AllocaInst(T, "", static_cast<Instruction*>(FBegin));
1114 new StoreInst(I, Alloca, false, CI);
1115 auto Zero = ConstantInt::getNullValue(Type::getInt32Ty(T->getContext()));
1116 Value *Index[] = {Zero, Zero};
1117 I = GetElementPtrInst::CreateInBounds(Alloca, Index, "", CI);
1118 }
1119 return Name;
1120 }, nullptr, &Attrs);
1121 return true;
1122 }
1123
1124 // ToDo: Handle unsigned integer return type. May need spec change.
1125 Instruction *
postProcessOCLReadImage(SPIRVInstruction * BI,CallInst * CI,const std::string & FuncName)1126 SPIRVToLLVM::postProcessOCLReadImage(SPIRVInstruction *BI, CallInst* CI,
1127 const std::string &FuncName) {
1128 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
1129 StringRef ImageTypeName;
1130 bool isDepthImage = false;
1131 if (isOCLImageType(
1132 (cast<CallInst>(CI->getOperand(0)))->getArgOperand(0)->getType(),
1133 &ImageTypeName))
1134 isDepthImage = ImageTypeName.endswith("depth_t");
1135 return mutateCallInstOCL(
1136 M, CI,
1137 [=](CallInst *, std::vector<Value *> &Args, llvm::Type *&RetTy) {
1138 CallInst *CallSampledImg = cast<CallInst>(Args[0]);
1139 auto Img = CallSampledImg->getArgOperand(0);
1140 assert(isOCLImageType(Img->getType()));
1141 auto Sampler = CallSampledImg->getArgOperand(1);
1142 Args[0] = Img;
1143 Args.insert(Args.begin() + 1, Sampler);
1144 if(Args.size() > 4 ) {
1145 ConstantInt* ImOp = dyn_cast<ConstantInt>(Args[3]);
1146 ConstantFP* LodVal = dyn_cast<ConstantFP>(Args[4]);
1147 // Drop "Image Operands" argument.
1148 Args.erase(Args.begin() + 3, Args.begin() + 4);
1149 // If the image operand is LOD and its value is zero, drop it too.
1150 if (ImOp && LodVal && LodVal->isNullValue() &&
1151 ImOp->getZExtValue() == ImageOperandsMask::ImageOperandsLodMask )
1152 Args.erase(Args.begin() + 3, Args.end());
1153 }
1154 if (CallSampledImg->hasOneUse()) {
1155 CallSampledImg->replaceAllUsesWith(
1156 UndefValue::get(CallSampledImg->getType()));
1157 CallSampledImg->dropAllReferences();
1158 CallSampledImg->eraseFromParent();
1159 }
1160 Type *T = CI->getType();
1161 if (auto VT = dyn_cast<VectorType>(T))
1162 T = VT->getElementType();
1163 RetTy = isDepthImage ? T : CI->getType();
1164 return std::string(kOCLBuiltinName::SampledReadImage) +
1165 (T->isFloatingPointTy() ? 'f' : 'i');
1166 },
1167 [=](CallInst *NewCI) -> Instruction * {
1168 if (isDepthImage)
1169 return InsertElementInst::Create(
1170 UndefValue::get(VectorType::get(NewCI->getType(), 4)), NewCI,
1171 getSizet(M, 0), "", NewCI->getParent());
1172 return NewCI;
1173 },
1174 &Attrs);
1175 }
1176
1177 CallInst*
postProcessOCLWriteImage(SPIRVInstruction * BI,CallInst * CI,const std::string & DemangledName)1178 SPIRVToLLVM::postProcessOCLWriteImage(SPIRVInstruction *BI, CallInst *CI,
1179 const std::string &DemangledName) {
1180 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
1181 return mutateCallInstOCL(M, CI, [=](CallInst *, std::vector<Value *> &Args) {
1182 llvm::Type *T = Args[2]->getType();
1183 if (Args.size() > 4) {
1184 ConstantInt* ImOp = dyn_cast<ConstantInt>(Args[3]);
1185 ConstantFP* LodVal = dyn_cast<ConstantFP>(Args[4]);
1186 // Drop "Image Operands" argument.
1187 Args.erase(Args.begin() + 3, Args.begin() + 4);
1188 // If the image operand is LOD and its value is zero, drop it too.
1189 if (ImOp && LodVal && LodVal->isNullValue() &&
1190 ImOp->getZExtValue() == ImageOperandsMask::ImageOperandsLodMask )
1191 Args.erase(Args.begin() + 3, Args.end());
1192 else
1193 std::swap(Args[2], Args[3]);
1194 }
1195 return std::string(kOCLBuiltinName::WriteImage) +
1196 (T->isFPOrFPVectorTy() ? 'f' : 'i');
1197 }, &Attrs);
1198 }
1199
1200 CallInst *
postProcessOCLBuildNDRange(SPIRVInstruction * BI,CallInst * CI,const std::string & FuncName)1201 SPIRVToLLVM::postProcessOCLBuildNDRange(SPIRVInstruction *BI, CallInst *CI,
1202 const std::string &FuncName) {
1203 assert(CI->getNumArgOperands() == 3);
1204 auto GWS = CI->getArgOperand(0);
1205 auto LWS = CI->getArgOperand(1);
1206 auto GWO = CI->getArgOperand(2);
1207 CI->setArgOperand(0, GWO);
1208 CI->setArgOperand(1, GWS);
1209 CI->setArgOperand(2, LWS);
1210 return CI;
1211 }
1212
1213 Instruction *
postProcessGroupAllAny(CallInst * CI,const std::string & DemangledName)1214 SPIRVToLLVM::postProcessGroupAllAny(CallInst *CI,
1215 const std::string &DemangledName) {
1216 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
1217 return mutateCallInstSPIRV(
1218 M, CI,
1219 [=](CallInst *, std::vector<Value *> &Args, llvm::Type *&RetTy) {
1220 Type *Int32Ty = Type::getInt32Ty(*Context);
1221 RetTy = Int32Ty;
1222 Args[1] = CastInst::CreateZExtOrBitCast(Args[1], Int32Ty, "", CI);
1223 return DemangledName;
1224 },
1225 [=](CallInst *NewCI) -> Instruction * {
1226 Type *RetTy = Type::getInt1Ty(*Context);
1227 return CastInst::CreateTruncOrBitCast(NewCI, RetTy, "",
1228 NewCI->getNextNode());
1229 },
1230 &Attrs);
1231 }
1232
1233 CallInst *
expandOCLBuiltinWithScalarArg(CallInst * CI,const std::string & FuncName)1234 SPIRVToLLVM::expandOCLBuiltinWithScalarArg(CallInst* CI,
1235 const std::string &FuncName) {
1236 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
1237 if (!CI->getOperand(0)->getType()->isVectorTy() &&
1238 CI->getOperand(1)->getType()->isVectorTy()) {
1239 return mutateCallInstOCL(M, CI, [=](CallInst *, std::vector<Value *> &Args){
1240 unsigned vecSize = CI->getOperand(1)->getType()->getVectorNumElements();
1241 Value *NewVec = nullptr;
1242 if (auto CA = dyn_cast<Constant>(Args[0]))
1243 NewVec = ConstantVector::getSplat(vecSize, CA);
1244 else {
1245 NewVec = ConstantVector::getSplat(vecSize,
1246 Constant::getNullValue(Args[0]->getType()));
1247 NewVec = InsertElementInst::Create(NewVec, Args[0], getInt32(M, 0), "",
1248 CI);
1249 NewVec = new ShuffleVectorInst(NewVec, NewVec,
1250 ConstantVector::getSplat(vecSize, getInt32(M, 0)), "", CI);
1251 }
1252 NewVec->takeName(Args[0]);
1253 Args[0] = NewVec;
1254 return FuncName;
1255 }, &Attrs);
1256 }
1257 return CI;
1258 }
1259
1260 std::string
transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe * ST)1261 SPIRVToLLVM::transOCLPipeTypeAccessQualifier(SPIRV::SPIRVTypePipe* ST) {
1262 return SPIRSPIRVAccessQualifierMap::rmap(ST->getAccessQualifier());
1263 }
1264
1265 void
transGeneratorMD()1266 SPIRVToLLVM::transGeneratorMD() {
1267 SPIRVMDBuilder B(*M);
1268 B.addNamedMD(kSPIRVMD::Generator)
1269 .addOp()
1270 .addU16(BM->getGeneratorId())
1271 .addU16(BM->getGeneratorVer())
1272 .done();
1273 }
1274
1275 Value *
oclTransConstantSampler(SPIRV::SPIRVConstantSampler * BCS)1276 SPIRVToLLVM::oclTransConstantSampler(SPIRV::SPIRVConstantSampler* BCS) {
1277 auto Lit = (BCS->getAddrMode() << 1) |
1278 BCS->getNormalized() |
1279 ((BCS->getFilterMode() + 1) << 4);
1280 auto Ty = IntegerType::getInt32Ty(*Context);
1281 return ConstantInt::get(Ty, Lit);
1282 }
1283
1284 Value *
oclTransConstantPipeStorage(SPIRV::SPIRVConstantPipeStorage * BCPS)1285 SPIRVToLLVM::oclTransConstantPipeStorage(
1286 SPIRV::SPIRVConstantPipeStorage* BCPS) {
1287
1288 string CPSName = string(kSPIRVTypeName::PrefixAndDelim)
1289 + kSPIRVTypeName::ConstantPipeStorage;
1290
1291 auto Int32Ty = IntegerType::getInt32Ty(*Context);
1292 auto CPSTy = M->getTypeByName(CPSName);
1293 if (!CPSTy) {
1294 Type* CPSElemsTy[] = { Int32Ty, Int32Ty, Int32Ty };
1295 CPSTy = StructType::create(*Context, CPSElemsTy, CPSName);
1296 }
1297
1298 assert(CPSTy != nullptr && "Could not create spirv.ConstantPipeStorage");
1299
1300 Constant* CPSElems[] = {
1301 ConstantInt::get(Int32Ty, BCPS->getPacketSize()),
1302 ConstantInt::get(Int32Ty, BCPS->getPacketAlign()),
1303 ConstantInt::get(Int32Ty, BCPS->getCapacity())
1304 };
1305
1306 return new GlobalVariable(*M, CPSTy, false, GlobalValue::LinkOnceODRLinkage,
1307 ConstantStruct::get(CPSTy, CPSElems), BCPS->getName(),
1308 nullptr, GlobalValue::NotThreadLocal, SPIRAS_Global);
1309 }
1310
1311 /// For instructions, this function assumes they are created in order
1312 /// and appended to the given basic block. An instruction may use a
1313 /// instruction from another BB which has not been translated. Such
1314 /// instructions should be translated to place holders at the point
1315 /// of first use, then replaced by real instructions when they are
1316 /// created.
1317 ///
1318 /// When CreatePlaceHolder is true, create a load instruction of a
1319 /// global variable as placeholder for SPIRV instruction. Otherwise,
1320 /// create instruction and replace placeholder if there is one.
1321 Value *
transValueWithoutDecoration(SPIRVValue * BV,Function * F,BasicBlock * BB,bool CreatePlaceHolder)1322 SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
1323 BasicBlock *BB, bool CreatePlaceHolder){
1324
1325 auto OC = BV->getOpCode();
1326 IntBoolOpMap::rfind(OC, &OC);
1327
1328 // Translation of non-instruction values
1329 switch(OC) {
1330 case OpConstant: {
1331 SPIRVConstant *BConst = static_cast<SPIRVConstant *>(BV);
1332 SPIRVType *BT = BV->getType();
1333 Type *LT = transType(BT);
1334 switch(BT->getOpCode()) {
1335 case OpTypeBool:
1336 case OpTypeInt:
1337 return mapValue(BV, ConstantInt::get(LT, BConst->getZExtIntValue(),
1338 static_cast<SPIRVTypeInt*>(BT)->isSigned()));
1339 case OpTypeFloat: {
1340 const llvm::fltSemantics *FS = nullptr;
1341 switch (BT->getFloatBitWidth()) {
1342 case 16:
1343 FS = &APFloat::IEEEhalf;
1344 break;
1345 case 32:
1346 FS = &APFloat::IEEEsingle;
1347 break;
1348 case 64:
1349 FS = &APFloat::IEEEdouble;
1350 break;
1351 default:
1352 llvm_unreachable("invalid float type");
1353 }
1354 return mapValue(BV, ConstantFP::get(*Context, APFloat(*FS,
1355 APInt(BT->getFloatBitWidth(), BConst->getZExtIntValue()))));
1356 }
1357 default:
1358 llvm_unreachable("Not implemented");
1359 return nullptr;
1360 }
1361 }
1362
1363 case OpConstantTrue:
1364 return mapValue(BV, ConstantInt::getTrue(*Context));
1365
1366 case OpConstantFalse:
1367 return mapValue(BV, ConstantInt::getFalse(*Context));
1368
1369 case OpConstantNull: {
1370 auto LT = transType(BV->getType());
1371 return mapValue(BV, Constant::getNullValue(LT));
1372 }
1373
1374 case OpConstantComposite: {
1375 auto BCC = static_cast<SPIRVConstantComposite*>(BV);
1376 std::vector<Constant *> CV;
1377 for (auto &I:BCC->getElements())
1378 CV.push_back(dyn_cast<Constant>(transValue(I, F, BB)));
1379 switch(BV->getType()->getOpCode()) {
1380 case OpTypeVector:
1381 return mapValue(BV, ConstantVector::get(CV));
1382 case OpTypeArray:
1383 return mapValue(BV, ConstantArray::get(
1384 dyn_cast<ArrayType>(transType(BCC->getType())), CV));
1385 case OpTypeStruct: {
1386 auto BCCTy = dyn_cast<StructType>(transType(BCC->getType()));
1387 auto Members = BCCTy->getNumElements();
1388 auto Constants = CV.size();
1389 //if we try to initialize constant TypeStruct, add bitcasts
1390 //if src and dst types are both pointers but to different types
1391 if (Members == Constants) {
1392 for (unsigned i = 0; i < Members; ++i) {
1393 if (CV[i]->getType() == BCCTy->getElementType(i))
1394 continue;
1395 if (!CV[i]->getType()->isPointerTy() ||
1396 !BCCTy->getElementType(i)->isPointerTy())
1397 continue;
1398
1399 CV[i] = ConstantExpr::getBitCast(CV[i], BCCTy->getElementType(i));
1400 }
1401 }
1402
1403 return mapValue(BV, ConstantStruct::get(
1404 dyn_cast<StructType>(transType(BCC->getType())), CV));
1405 }
1406 default:
1407 llvm_unreachable("not implemented");
1408 return nullptr;
1409 }
1410 }
1411
1412 case OpConstantSampler: {
1413 auto BCS = static_cast<SPIRVConstantSampler*>(BV);
1414 return mapValue(BV, oclTransConstantSampler(BCS));
1415 }
1416
1417 case OpConstantPipeStorage: {
1418 auto BCPS = static_cast<SPIRVConstantPipeStorage*>(BV);
1419 return mapValue(BV, oclTransConstantPipeStorage(BCPS));
1420 }
1421
1422 case OpSpecConstantOp: {
1423 auto BI = createInstFromSpecConstantOp(
1424 static_cast<SPIRVSpecConstantOp*>(BV));
1425 return mapValue(BV, transValue(BI, nullptr, nullptr, false));
1426 }
1427
1428 case OpUndef:
1429 return mapValue(BV, UndefValue::get(transType(BV->getType())));
1430
1431 case OpVariable: {
1432 auto BVar = static_cast<SPIRVVariable *>(BV);
1433 auto Ty = transType(BVar->getType()->getPointerElementType());
1434 bool IsConst = BVar->isConstant();
1435 llvm::GlobalValue::LinkageTypes LinkageTy = transLinkageType(BVar);
1436 Constant *Initializer = nullptr;
1437 SPIRVValue *Init = BVar->getInitializer();
1438 if (Init)
1439 Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false));
1440 else if (LinkageTy == GlobalValue::CommonLinkage)
1441 // In LLVM variables with common linkage type must be initilized by 0
1442 Initializer = Constant::getNullValue(Ty);
1443
1444 SPIRVStorageClassKind BS = BVar->getStorageClass();
1445 if (BS == StorageClassFunction && !Init) {
1446 assert (BB && "Invalid BB");
1447 return mapValue(BV, new AllocaInst(Ty, BV->getName(), BB));
1448 }
1449 auto AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS);
1450 auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy, Initializer,
1451 BV->getName(), 0, GlobalVariable::NotThreadLocal, AddrSpace);
1452 LVar->setUnnamedAddr((IsConst && Ty->isArrayTy() &&
1453 Ty->getArrayElementType()->isIntegerTy(8)) ?
1454 GlobalValue::UnnamedAddr::Global :
1455 GlobalValue::UnnamedAddr::None);
1456 SPIRVBuiltinVariableKind BVKind;
1457 if (BVar->isBuiltin(&BVKind))
1458 BuiltinGVMap[LVar] = BVKind;
1459 return mapValue(BV, LVar);
1460 }
1461
1462 case OpFunctionParameter: {
1463 auto BA = static_cast<SPIRVFunctionParameter*>(BV);
1464 assert (F && "Invalid function");
1465 unsigned ArgNo = 0;
1466 for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
1467 ++I, ++ArgNo) {
1468 if (ArgNo == BA->getArgNo())
1469 return mapValue(BV, static_cast<Argument*>(I));
1470 }
1471 llvm_unreachable("Invalid argument");
1472 return nullptr;
1473 }
1474
1475 case OpFunction:
1476 return mapValue(BV, transFunction(static_cast<SPIRVFunction *>(BV)));
1477
1478 case OpLabel:
1479 return mapValue(BV, BasicBlock::Create(*Context, BV->getName(), F));
1480
1481 case OpBitcast: // Can be translated without BB pointer
1482 if(!CreatePlaceHolder) // May be a placeholder
1483 return mapValue(BV, transConvertInst(BV, F, BB));
1484
1485 default:
1486 // do nothing
1487 break;
1488 }
1489
1490 // All other values require valid BB pointer.
1491 assert(BB && "Invalid BB");
1492
1493 // Creation of place holder
1494 if (CreatePlaceHolder) {
1495 auto GV = new GlobalVariable(*M,
1496 transType(BV->getType()),
1497 false,
1498 GlobalValue::PrivateLinkage,
1499 nullptr,
1500 std::string(kPlaceholderPrefix) + BV->getName(),
1501 0, GlobalVariable::NotThreadLocal, 0);
1502 auto LD = new LoadInst(GV, BV->getName(), BB);
1503 PlaceholderMap[BV] = LD;
1504 return mapValue(BV, LD);
1505 }
1506
1507 // Translation of instructions
1508 switch (BV->getOpCode()) {
1509 case OpBranch: {
1510 auto BR = static_cast<SPIRVBranch *>(BV);
1511 return mapValue(BV, BranchInst::Create(
1512 dyn_cast<BasicBlock>(transValue(BR->getTargetLabel(), F, BB)), BB));
1513 }
1514
1515 case OpBranchConditional: {
1516 auto BR = static_cast<SPIRVBranchConditional *>(BV);
1517 return mapValue(
1518 BV, BranchInst::Create(
1519 dyn_cast<BasicBlock>(transValue(BR->getTrueLabel(), F, BB)),
1520 dyn_cast<BasicBlock>(transValue(BR->getFalseLabel(), F, BB)),
1521 transValue(BR->getCondition(), F, BB), BB));
1522 }
1523
1524 case OpPhi: {
1525 auto Phi = static_cast<SPIRVPhi *>(BV);
1526 auto LPhi = dyn_cast<PHINode>(mapValue(
1527 BV, PHINode::Create(transType(Phi->getType()),
1528 Phi->getPairs().size() / 2, Phi->getName(), BB)));
1529 Phi->foreachPair([&](SPIRVValue *IncomingV, SPIRVBasicBlock *IncomingBB,
1530 size_t Index) {
1531 auto Translated = transValue(IncomingV, F, BB);
1532 LPhi->addIncoming(Translated,
1533 dyn_cast<BasicBlock>(transValue(IncomingBB, F, BB)));
1534 });
1535 return LPhi;
1536 }
1537
1538 case OpReturn:
1539 return mapValue(BV, ReturnInst::Create(*Context, BB));
1540
1541 case OpReturnValue: {
1542 auto RV = static_cast<SPIRVReturnValue *>(BV);
1543 return mapValue(
1544 BV, ReturnInst::Create(*Context,
1545 transValue(RV->getReturnValue(), F, BB), BB));
1546 }
1547
1548 case OpStore: {
1549 SPIRVStore *BS = static_cast<SPIRVStore*>(BV);
1550 StoreInst *SI = new StoreInst(transValue(BS->getSrc(), F, BB),
1551 transValue(BS->getDst(), F, BB),
1552 BS->SPIRVMemoryAccess::isVolatile(),
1553 BS->SPIRVMemoryAccess::getAlignment(), BB);
1554 if (BS->SPIRVMemoryAccess::isNonTemporal())
1555 transNonTemporalMetadata(SI);
1556 return mapValue(BV, SI);
1557 }
1558
1559 case OpLoad: {
1560 SPIRVLoad *BL = static_cast<SPIRVLoad*>(BV);
1561 LoadInst *LI = new LoadInst(transValue(BL->getSrc(), F, BB), BV->getName(),
1562 BL->SPIRVMemoryAccess::isVolatile(),
1563 BL->SPIRVMemoryAccess::getAlignment(), BB);
1564 if (BL->SPIRVMemoryAccess::isNonTemporal())
1565 transNonTemporalMetadata(LI);
1566 return mapValue(BV, LI);
1567 }
1568
1569 case OpCopyMemorySized: {
1570 SPIRVCopyMemorySized *BC = static_cast<SPIRVCopyMemorySized *>(BV);
1571 std::string FuncName = "llvm.memcpy";
1572 SPIRVType* BS = BC->getSource()->getType();
1573 SPIRVType* BT = BC->getTarget()->getType();
1574 Type *Int1Ty = Type::getInt1Ty(*Context);
1575 Type* Int32Ty = Type::getInt32Ty(*Context);
1576 Type* VoidTy = Type::getVoidTy(*Context);
1577 Type* SrcTy = transType(BS);
1578 Type* TrgTy = transType(BT);
1579 Type* SizeTy = transType(BC->getSize()->getType());
1580 Type* ArgTy[] = { TrgTy, SrcTy, SizeTy, Int32Ty, Int1Ty };
1581
1582 ostringstream TempName;
1583 TempName << ".p" << SPIRSPIRVAddrSpaceMap::rmap(BT->getPointerStorageClass()) << "i8";
1584 TempName << ".p" << SPIRSPIRVAddrSpaceMap::rmap(BS->getPointerStorageClass()) << "i8";
1585 FuncName += TempName.str();
1586 if (BC->getSize()->getType()->getBitWidth() == 32)
1587 FuncName += ".i32";
1588 else
1589 FuncName += ".i64";
1590
1591 FunctionType *FT = FunctionType::get(VoidTy, ArgTy, false);
1592 Function *Func = dyn_cast<Function>(M->getOrInsertFunction(FuncName, FT));
1593 assert(Func && Func->getFunctionType() == FT && "Function type mismatch");
1594 Func->setLinkage(GlobalValue::ExternalLinkage);
1595
1596 if (isFuncNoUnwind())
1597 Func->addFnAttr(Attribute::NoUnwind);
1598
1599 Value *Arg[] = { transValue(BC->getTarget(), Func, BB),
1600 transValue(BC->getSource(), Func, BB),
1601 dyn_cast<llvm::ConstantInt>(transValue(BC->getSize(),
1602 Func, BB)),
1603 ConstantInt::get(Int32Ty,
1604 BC->SPIRVMemoryAccess::getAlignment()),
1605 ConstantInt::get(Int1Ty,
1606 BC->SPIRVMemoryAccess::isVolatile())};
1607 return mapValue( BV, CallInst::Create(Func, Arg, "", BB));
1608 }
1609
1610 case OpSelect: {
1611 SPIRVSelect *BS = static_cast<SPIRVSelect*>(BV);
1612 return mapValue(BV,
1613 SelectInst::Create(transValue(BS->getCondition(), F, BB),
1614 transValue(BS->getTrueValue(), F, BB),
1615 transValue(BS->getFalseValue(), F, BB),
1616 BV->getName(), BB));
1617 }
1618
1619 case OpSwitch: {
1620 auto BS = static_cast<SPIRVSwitch *>(BV);
1621 auto Select = transValue(BS->getSelect(), F, BB);
1622 auto LS = SwitchInst::Create(
1623 Select, dyn_cast<BasicBlock>(transValue(BS->getDefault(), F, BB)),
1624 BS->getNumPairs(), BB);
1625 BS->foreachPair(
1626 [&](SPIRVWord Literal, SPIRVBasicBlock *Label, size_t Index) {
1627 LS->addCase(ConstantInt::get(dyn_cast<IntegerType>(Select->getType()),
1628 Literal),
1629 dyn_cast<BasicBlock>(transValue(Label, F, BB)));
1630 });
1631 return mapValue(BV, LS);
1632 }
1633
1634 case OpAccessChain:
1635 case OpInBoundsAccessChain:
1636 case OpPtrAccessChain:
1637 case OpInBoundsPtrAccessChain: {
1638 auto AC = static_cast<SPIRVAccessChainBase *>(BV);
1639 auto Base = transValue(AC->getBase(), F, BB);
1640 auto Index = transValue(AC->getIndices(), F, BB);
1641 if (!AC->hasPtrIndex())
1642 Index.insert(Index.begin(), getInt32(M, 0));
1643 auto IsInbound = AC->isInBounds();
1644 Value *V = nullptr;
1645 if (BB) {
1646 auto GEP = GetElementPtrInst::Create(nullptr, Base, Index,
1647 BV->getName(), BB);
1648 GEP->setIsInBounds(IsInbound);
1649 V = GEP;
1650 } else {
1651 V = ConstantExpr::getGetElementPtr(Base->getType(),
1652 dyn_cast<Constant>(Base),
1653 Index,
1654 IsInbound);
1655 }
1656 return mapValue(BV, V);
1657 }
1658
1659 case OpCompositeExtract: {
1660 SPIRVCompositeExtract *CE = static_cast<SPIRVCompositeExtract *>(BV);
1661 if (CE->getComposite()->getType()->isTypeVector()) {
1662 assert(CE->getIndices().size() == 1 && "Invalid index");
1663 return mapValue(
1664 BV, ExtractElementInst::Create(
1665 transValue(CE->getComposite(), F, BB),
1666 ConstantInt::get(*Context, APInt(32, CE->getIndices()[0])),
1667 BV->getName(), BB));
1668 }
1669 return mapValue(
1670 BV, ExtractValueInst::Create(
1671 transValue(CE->getComposite(), F, BB),
1672 CE->getIndices(), BV->getName(), BB));
1673 }
1674
1675 case OpVectorExtractDynamic: {
1676 auto CE = static_cast<SPIRVVectorExtractDynamic *>(BV);
1677 return mapValue(
1678 BV, ExtractElementInst::Create(transValue(CE->getVector(), F, BB),
1679 transValue(CE->getIndex(), F, BB),
1680 BV->getName(), BB));
1681 }
1682
1683 case OpCompositeInsert: {
1684 auto CI = static_cast<SPIRVCompositeInsert *>(BV);
1685 if (CI->getComposite()->getType()->isTypeVector()) {
1686 assert(CI->getIndices().size() == 1 && "Invalid index");
1687 return mapValue(
1688 BV, InsertElementInst::Create(
1689 transValue(CI->getComposite(), F, BB),
1690 transValue(CI->getObject(), F, BB),
1691 ConstantInt::get(*Context, APInt(32, CI->getIndices()[0])),
1692 BV->getName(), BB));
1693 }
1694 return mapValue(
1695 BV, InsertValueInst::Create(
1696 transValue(CI->getComposite(), F, BB),
1697 transValue(CI->getObject(), F, BB),
1698 CI->getIndices(), BV->getName(), BB));
1699 }
1700
1701 case OpVectorInsertDynamic: {
1702 auto CI = static_cast<SPIRVVectorInsertDynamic *>(BV);
1703 return mapValue(
1704 BV, InsertElementInst::Create(transValue(CI->getVector(), F, BB),
1705 transValue(CI->getComponent(), F, BB),
1706 transValue(CI->getIndex(), F, BB),
1707 BV->getName(), BB));
1708 }
1709
1710 case OpVectorShuffle: {
1711 auto VS = static_cast<SPIRVVectorShuffle *>(BV);
1712 std::vector<Constant *> Components;
1713 IntegerType *Int32Ty = IntegerType::get(*Context, 32);
1714 for (auto I : VS->getComponents()) {
1715 if (I == static_cast<SPIRVWord>(-1))
1716 Components.push_back(UndefValue::get(Int32Ty));
1717 else
1718 Components.push_back(ConstantInt::get(Int32Ty, I));
1719 }
1720 return mapValue(BV,
1721 new ShuffleVectorInst(transValue(VS->getVector1(), F, BB),
1722 transValue(VS->getVector2(), F, BB),
1723 ConstantVector::get(Components),
1724 BV->getName(), BB));
1725 }
1726
1727 case OpFunctionCall: {
1728 SPIRVFunctionCall *BC = static_cast<SPIRVFunctionCall *>(BV);
1729 auto Call = CallInst::Create(transFunction(BC->getFunction()),
1730 transValue(BC->getArgumentValues(), F, BB),
1731 BC->getName(), BB);
1732 setCallingConv(Call);
1733 setAttrByCalledFunc(Call);
1734 return mapValue(BV, Call);
1735 }
1736
1737 case OpExtInst:
1738 return mapValue(
1739 BV, transOCLBuiltinFromExtInst(static_cast<SPIRVExtInst *>(BV), BB));
1740
1741 case OpControlBarrier:
1742 case OpMemoryBarrier:
1743 return mapValue(
1744 BV, transOCLBarrierFence(static_cast<SPIRVInstruction *>(BV), BB));
1745
1746 case OpSNegate: {
1747 SPIRVUnary *BC = static_cast<SPIRVUnary *>(BV);
1748 return mapValue(
1749 BV, BinaryOperator::CreateNSWNeg(transValue(BC->getOperand(0), F, BB),
1750 BV->getName(), BB));
1751 }
1752
1753 case OpFNegate: {
1754 SPIRVUnary *BC = static_cast<SPIRVUnary *>(BV);
1755 return mapValue(
1756 BV, BinaryOperator::CreateFNeg(transValue(BC->getOperand(0), F, BB),
1757 BV->getName(), BB));
1758 }
1759
1760 case OpNot: {
1761 SPIRVUnary *BC = static_cast<SPIRVUnary *>(BV);
1762 return mapValue(
1763 BV, BinaryOperator::CreateNot(transValue(BC->getOperand(0), F, BB),
1764 BV->getName(), BB));
1765 }
1766
1767 case OpAll :
1768 case OpAny :
1769 return mapValue(BV,
1770 transOCLAllAny(static_cast<SPIRVInstruction *>(BV), BB));
1771
1772 case OpIsFinite :
1773 case OpIsInf :
1774 case OpIsNan :
1775 case OpIsNormal :
1776 case OpSignBitSet :
1777 return mapValue(BV,
1778 transOCLRelational(static_cast<SPIRVInstruction *>(BV), BB));
1779
1780 default: {
1781 auto OC = BV->getOpCode();
1782 if (isSPIRVCmpInstTransToLLVMInst(static_cast<SPIRVInstruction*>(BV))) {
1783 return mapValue(BV, transCmpInst(BV, BB, F));
1784 } else if (OCLSPIRVBuiltinMap::rfind(OC, nullptr) &&
1785 !isAtomicOpCode(OC) &&
1786 !isGroupOpCode(OC) &&
1787 !isPipeOpCode(OC)) {
1788 return mapValue(BV, transOCLBuiltinFromInst(
1789 static_cast<SPIRVInstruction *>(BV), BB));
1790 } else if (isBinaryShiftLogicalBitwiseOpCode(OC) ||
1791 isLogicalOpCode(OC)) {
1792 return mapValue(BV, transShiftLogicalBitwiseInst(BV, BB, F));
1793 } else if (isCvtOpCode(OC)) {
1794 auto BI = static_cast<SPIRVInstruction *>(BV);
1795 Value *Inst = nullptr;
1796 if (BI->hasFPRoundingMode() || BI->isSaturatedConversion())
1797 Inst = transOCLBuiltinFromInst(BI, BB);
1798 else
1799 Inst = transConvertInst(BV, F, BB);
1800 return mapValue(BV, Inst);
1801 }
1802 return mapValue(BV, transSPIRVBuiltinFromInst(
1803 static_cast<SPIRVInstruction *>(BV), BB));
1804 }
1805
1806 SPIRVDBG(spvdbgs() << "Cannot translate " << *BV << '\n';)
1807 llvm_unreachable("Translation of SPIRV instruction not implemented");
1808 return NULL;
1809 }
1810 }
1811
1812 template<class SourceTy, class FuncTy>
1813 bool
foreachFuncCtlMask(SourceTy Source,FuncTy Func)1814 SPIRVToLLVM::foreachFuncCtlMask(SourceTy Source, FuncTy Func) {
1815 SPIRVWord FCM = Source->getFuncCtlMask();
1816 SPIRSPIRVFuncCtlMaskMap::foreach([&](Attribute::AttrKind Attr,
1817 SPIRVFunctionControlMaskKind Mask){
1818 if (FCM & Mask)
1819 Func(Attr);
1820 });
1821 return true;
1822 }
1823
1824 Function *
transFunction(SPIRVFunction * BF)1825 SPIRVToLLVM::transFunction(SPIRVFunction *BF) {
1826 auto Loc = FuncMap.find(BF);
1827 if (Loc != FuncMap.end())
1828 return Loc->second;
1829
1830 auto IsKernel = BM->isEntryPoint(ExecutionModelKernel, BF->getId());
1831 auto Linkage = IsKernel ? GlobalValue::ExternalLinkage : transLinkageType(BF);
1832 FunctionType *FT = dyn_cast<FunctionType>(transType(BF->getFunctionType()));
1833 Function *F = dyn_cast<Function>(mapValue(BF, Function::Create(FT, Linkage,
1834 BF->getName(), M)));
1835 assert(F);
1836 mapFunction(BF, F);
1837 if (!F->isIntrinsic()) {
1838 F->setCallingConv(IsKernel ? CallingConv::SPIR_KERNEL :
1839 CallingConv::SPIR_FUNC);
1840 if (isFuncNoUnwind())
1841 F->addFnAttr(Attribute::NoUnwind);
1842 foreachFuncCtlMask(BF, [&](Attribute::AttrKind Attr){
1843 F->addFnAttr(Attr);
1844 });
1845 }
1846
1847 for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E;
1848 ++I) {
1849 auto BA = BF->getArgument(I->getArgNo());
1850 mapValue(BA, static_cast<Argument*>(I));
1851 setName(static_cast<Argument*>(I), BA);
1852 BA->foreachAttr([&](SPIRVFuncParamAttrKind Kind){
1853 if (Kind == FunctionParameterAttributeNoWrite)
1854 return;
1855 F->addAttribute(I->getArgNo() + 1, SPIRSPIRVFuncParamAttrMap::rmap(Kind));
1856 });
1857
1858 SPIRVWord MaxOffset = 0;
1859 if (BA->hasDecorate(DecorationMaxByteOffset, 0, &MaxOffset)) {
1860 AttrBuilder Builder;
1861 Builder.addDereferenceableAttr(MaxOffset);
1862 I->addAttr(AttributeSet::get(*Context, I->getArgNo() + 1, Builder));
1863 }
1864 }
1865 BF->foreachReturnValueAttr([&](SPIRVFuncParamAttrKind Kind){
1866 if (Kind == FunctionParameterAttributeNoWrite)
1867 return;
1868 F->addAttribute(AttributeSet::ReturnIndex,
1869 SPIRSPIRVFuncParamAttrMap::rmap(Kind));
1870 });
1871
1872 // Creating all basic blocks before creating instructions.
1873 for (size_t I = 0, E = BF->getNumBasicBlock(); I != E; ++I) {
1874 transValue(BF->getBasicBlock(I), F, nullptr);
1875 }
1876
1877 for (size_t I = 0, E = BF->getNumBasicBlock(); I != E; ++I) {
1878 SPIRVBasicBlock *BBB = BF->getBasicBlock(I);
1879 BasicBlock *BB = dyn_cast<BasicBlock>(transValue(BBB, F, nullptr));
1880 for (size_t BI = 0, BE = BBB->getNumInst(); BI != BE; ++BI) {
1881 SPIRVInstruction *BInst = BBB->getInst(BI);
1882 transValue(BInst, F, BB, false);
1883 }
1884 }
1885 return F;
1886 }
1887
1888 /// LLVM convert builtin functions is translated to two instructions:
1889 /// y = i32 islessgreater(float x, float z) ->
1890 /// y = i32 ZExt(bool LessGreater(float x, float z))
1891 /// When translating back, for simplicity, a trunc instruction is inserted
1892 /// w = bool LessGreater(float x, float z) ->
1893 /// w = bool Trunc(i32 islessgreater(float x, float z))
1894 /// Optimizer should be able to remove the redundant trunc/zext
1895 void
transOCLBuiltinFromInstPreproc(SPIRVInstruction * BI,Type * & RetTy,std::vector<SPIRVValue * > & Args)1896 SPIRVToLLVM::transOCLBuiltinFromInstPreproc(SPIRVInstruction* BI, Type *&RetTy,
1897 std::vector<SPIRVValue *> &Args) {
1898 if (!BI->hasType())
1899 return;
1900 auto BT = BI->getType();
1901 auto OC = BI->getOpCode();
1902 if (isCmpOpCode(BI->getOpCode())) {
1903 if (BT->isTypeBool())
1904 RetTy = IntegerType::getInt32Ty(*Context);
1905 else if (BT->isTypeVectorBool())
1906 RetTy = VectorType::get(IntegerType::get(*Context,
1907 Args[0]->getType()->getVectorComponentType()->isTypeFloat(64)?64:32),
1908 BT->getVectorComponentCount());
1909 else
1910 llvm_unreachable("invalid compare instruction");
1911 } else if (OC == OpGenericCastToPtrExplicit)
1912 Args.pop_back();
1913 else if (OC == OpImageRead && Args.size() > 2) {
1914 // Drop "Image operands" argument
1915 Args.erase(Args.begin() + 2);
1916 }
1917 }
1918
1919 Instruction*
transOCLBuiltinPostproc(SPIRVInstruction * BI,CallInst * CI,BasicBlock * BB,const std::string & DemangledName)1920 SPIRVToLLVM::transOCLBuiltinPostproc(SPIRVInstruction* BI,
1921 CallInst* CI, BasicBlock* BB, const std::string &DemangledName) {
1922 auto OC = BI->getOpCode();
1923 if (isCmpOpCode(OC) &&
1924 BI->getType()->isTypeVectorOrScalarBool()) {
1925 return CastInst::Create(Instruction::Trunc, CI, transType(BI->getType()),
1926 "cvt", BB);
1927 }
1928 if (OC == OpImageSampleExplicitLod)
1929 return postProcessOCLReadImage(BI, CI, DemangledName);
1930 if (OC == OpImageWrite) {
1931 return postProcessOCLWriteImage(BI, CI, DemangledName);
1932 }
1933 if (OC == OpGenericPtrMemSemantics)
1934 return BinaryOperator::CreateShl(CI, getInt32(M, 8), "", BB);
1935 if (OC == OpImageQueryFormat)
1936 return BinaryOperator::CreateSub(
1937 CI, getInt32(M, OCLImageChannelDataTypeOffset), "", BB);
1938 if (OC == OpImageQueryOrder)
1939 return BinaryOperator::CreateSub(
1940 CI, getInt32(M, OCLImageChannelOrderOffset), "", BB);
1941 if (OC == OpBuildNDRange)
1942 return postProcessOCLBuildNDRange(BI, CI, DemangledName);
1943 if (OC == OpGroupAll || OC == OpGroupAny)
1944 return postProcessGroupAllAny(CI, DemangledName);
1945 if (SPIRVEnableStepExpansion &&
1946 (DemangledName == "smoothstep" ||
1947 DemangledName == "step"))
1948 return expandOCLBuiltinWithScalarArg(CI, DemangledName);
1949 return CI;
1950 }
1951
1952 Instruction *
transBuiltinFromInst(const std::string & FuncName,SPIRVInstruction * BI,BasicBlock * BB)1953 SPIRVToLLVM::transBuiltinFromInst(const std::string& FuncName,
1954 SPIRVInstruction* BI, BasicBlock* BB) {
1955 std::string MangledName;
1956 auto Ops = BI->getOperands();
1957 Type* RetTy = BI->hasType() ? transType(BI->getType()) :
1958 Type::getVoidTy(*Context);
1959 transOCLBuiltinFromInstPreproc(BI, RetTy, Ops);
1960 std::vector<Type*> ArgTys = transTypeVector(
1961 SPIRVInstruction::getOperandTypes(Ops));
1962 bool HasFuncPtrArg = false;
1963 for (auto& I:ArgTys) {
1964 if (isa<FunctionType>(I)) {
1965 I = PointerType::get(I, SPIRAS_Private);
1966 HasFuncPtrArg = true;
1967 }
1968 }
1969 if (!HasFuncPtrArg)
1970 MangleOpenCLBuiltin(FuncName, ArgTys, MangledName);
1971 else
1972 MangledName = decorateSPIRVFunction(FuncName);
1973 Function* Func = M->getFunction(MangledName);
1974 FunctionType* FT = FunctionType::get(RetTy, ArgTys, false);
1975 // ToDo: Some intermediate functions have duplicate names with
1976 // different function types. This is OK if the function name
1977 // is used internally and finally translated to unique function
1978 // names. However it is better to have a way to differentiate
1979 // between intermidiate functions and final functions and make
1980 // sure final functions have unique names.
1981 SPIRVDBG(
1982 if (!HasFuncPtrArg && Func && Func->getFunctionType() != FT) {
1983 dbgs() << "Warning: Function name conflict:\n"
1984 << *Func << '\n'
1985 << " => " << *FT << '\n';
1986 }
1987 )
1988 if (!Func || Func->getFunctionType() != FT) {
1989 DEBUG(for (auto& I:ArgTys) {
1990 dbgs() << *I << '\n';
1991 });
1992 Func = Function::Create(FT, GlobalValue::ExternalLinkage, MangledName, M);
1993 Func->setCallingConv(CallingConv::SPIR_FUNC);
1994 if (isFuncNoUnwind())
1995 Func->addFnAttr(Attribute::NoUnwind);
1996 }
1997 auto Call = CallInst::Create(Func,
1998 transValue(Ops, BB->getParent(), BB), "", BB);
1999 setName(Call, BI);
2000 setAttrByCalledFunc(Call);
2001 SPIRVDBG(spvdbgs() << "[transInstToBuiltinCall] " << *BI << " -> "; dbgs() <<
2002 *Call << '\n';)
2003 Instruction *Inst = Call;
2004 Inst = transOCLBuiltinPostproc(BI, Call, BB, FuncName);
2005 return Inst;
2006 }
2007
2008 std::string
getOCLBuiltinName(SPIRVInstruction * BI)2009 SPIRVToLLVM::getOCLBuiltinName(SPIRVInstruction* BI) {
2010 auto OC = BI->getOpCode();
2011 if (OC == OpGenericCastToPtrExplicit)
2012 return getOCLGenericCastToPtrName(BI);
2013 if (isCvtOpCode(OC))
2014 return getOCLConvertBuiltinName(BI);
2015 if (OC == OpBuildNDRange) {
2016 auto NDRangeInst = static_cast<SPIRVBuildNDRange *>(BI);
2017 auto EleTy = ((NDRangeInst->getOperands())[0])->getType();
2018 int Dim = EleTy->isTypeArray() ? EleTy->getArrayLength() : 1;
2019 // cygwin does not have std::to_string
2020 ostringstream OS;
2021 OS << Dim;
2022 assert((EleTy->isTypeInt() && Dim == 1) ||
2023 (EleTy->isTypeArray() && Dim >= 2 && Dim <= 3));
2024 return std::string(kOCLBuiltinName::NDRangePrefix) + OS.str() + "D";
2025 }
2026 auto Name = OCLSPIRVBuiltinMap::rmap(OC);
2027
2028 SPIRVType *T = nullptr;
2029 switch(OC) {
2030 case OpImageRead:
2031 T = BI->getType();
2032 break;
2033 case OpImageWrite:
2034 T = BI->getOperands()[2]->getType();
2035 break;
2036 default:
2037 // do nothing
2038 break;
2039 }
2040 if (T && T->isTypeVector())
2041 T = T->getVectorComponentType();
2042 if (T)
2043 Name += T->isTypeFloat()?'f':'i';
2044
2045 return Name;
2046 }
2047
2048 Instruction *
transOCLBuiltinFromInst(SPIRVInstruction * BI,BasicBlock * BB)2049 SPIRVToLLVM::transOCLBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB) {
2050 assert(BB && "Invalid BB");
2051 auto FuncName = getOCLBuiltinName(BI);
2052 return transBuiltinFromInst(FuncName, BI, BB);
2053 }
2054
2055 Instruction *
transSPIRVBuiltinFromInst(SPIRVInstruction * BI,BasicBlock * BB)2056 SPIRVToLLVM::transSPIRVBuiltinFromInst(SPIRVInstruction *BI, BasicBlock *BB) {
2057 assert(BB && "Invalid BB");
2058 string Suffix = "";
2059 if (BI->getOpCode() == OpCreatePipeFromPipeStorage) {
2060 auto CPFPS = static_cast<SPIRVCreatePipeFromPipeStorage*>(BI);
2061 assert(CPFPS->getType()->isTypePipe() &&
2062 "Invalid type of CreatePipeFromStorage");
2063 auto PipeType = static_cast<SPIRVTypePipe*>(CPFPS->getType());
2064 switch (PipeType->getAccessQualifier()) {
2065 case AccessQualifierReadOnly: Suffix = "_read"; break;
2066 case AccessQualifierWriteOnly: Suffix = "_write"; break;
2067 case AccessQualifierReadWrite: Suffix = "_read_write"; break;
2068 }
2069 }
2070
2071 return transBuiltinFromInst(getSPIRVFuncName(BI->getOpCode(), Suffix), BI, BB);
2072 }
2073
2074 bool
translate()2075 SPIRVToLLVM::translate() {
2076 if (!transAddressingModel())
2077 return false;
2078
2079 DbgTran.createCompileUnit();
2080 DbgTran.addDbgInfoVersion();
2081
2082 for (unsigned I = 0, E = BM->getNumVariables(); I != E; ++I) {
2083 auto BV = BM->getVariable(I);
2084 if (BV->getStorageClass() != StorageClassFunction)
2085 transValue(BV, nullptr, nullptr);
2086 }
2087
2088 for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
2089 transFunction(BM->getFunction(I));
2090 }
2091 if (!transKernelMetadata())
2092 return false;
2093 if (!transFPContractMetadata())
2094 return false;
2095 if (!transSourceLanguage())
2096 return false;
2097 if (!transSourceExtension())
2098 return false;
2099 transGeneratorMD();
2100 if (!transOCLBuiltinsFromVariables())
2101 return false;
2102 if (!postProcessOCL())
2103 return false;
2104 eraseUselessFunctions(M);
2105 DbgTran.finalize();
2106 return true;
2107 }
2108
2109 bool
transAddressingModel()2110 SPIRVToLLVM::transAddressingModel() {
2111 switch (BM->getAddressingModel()) {
2112 case AddressingModelPhysical64:
2113 M->setTargetTriple(SPIR_TARGETTRIPLE64);
2114 M->setDataLayout(SPIR_DATALAYOUT64);
2115 break;
2116 case AddressingModelPhysical32:
2117 M->setTargetTriple(SPIR_TARGETTRIPLE32);
2118 M->setDataLayout(SPIR_DATALAYOUT32);
2119 break;
2120 case AddressingModelLogical:
2121 // Do not set target triple and data layout
2122 break;
2123 default:
2124 SPIRVCKRT(0, InvalidAddressingModel, "Actual addressing mode is " +
2125 (unsigned)BM->getAddressingModel());
2126 }
2127 return true;
2128 }
2129
2130 bool
transDecoration(SPIRVValue * BV,Value * V)2131 SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
2132 if (!transAlign(BV, V))
2133 return false;
2134 DbgTran.transDbgInfo(BV, V);
2135 return true;
2136 }
2137
2138 bool
transFPContractMetadata()2139 SPIRVToLLVM::transFPContractMetadata() {
2140 bool ContractOff = false;
2141 for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
2142 SPIRVFunction *BF = BM->getFunction(I);
2143 if (!isOpenCLKernel(BF))
2144 continue;
2145 if (BF->getExecutionMode(ExecutionModeContractionOff)) {
2146 ContractOff = true;
2147 break;
2148 }
2149 }
2150 if (!ContractOff)
2151 M->getOrInsertNamedMetadata(kSPIR2MD::FPContract);
2152 return true;
2153 }
2154
transOCLImageTypeAccessQualifier(SPIRV::SPIRVTypeImage * ST)2155 std::string SPIRVToLLVM::transOCLImageTypeAccessQualifier(
2156 SPIRV::SPIRVTypeImage* ST) {
2157 return SPIRSPIRVAccessQualifierMap::rmap(ST->getAccessQualifier());
2158 }
2159
2160 bool
transNonTemporalMetadata(Instruction * I)2161 SPIRVToLLVM::transNonTemporalMetadata(Instruction *I) {
2162 Constant* One = ConstantInt::get(Type::getInt32Ty(*Context), 1);
2163 MDNode *Node = MDNode::get(*Context, ConstantAsMetadata::get(One));
2164 I->setMetadata(M->getMDKindID("nontemporal"), Node);
2165 return true;
2166 }
2167
2168 bool
transKernelMetadata()2169 SPIRVToLLVM::transKernelMetadata() {
2170 NamedMDNode *KernelMDs = M->getOrInsertNamedMetadata(SPIR_MD_KERNELS);
2171 for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
2172 SPIRVFunction *BF = BM->getFunction(I);
2173 Function *F = static_cast<Function *>(getTranslatedValue(BF));
2174 assert(F && "Invalid translated function");
2175 if (F->getCallingConv() != CallingConv::SPIR_KERNEL)
2176 continue;
2177 std::vector<llvm::Metadata*> KernelMD;
2178 KernelMD.push_back(ValueAsMetadata::get(F));
2179
2180 // Generate metadata for kernel_arg_address_spaces
2181 addOCLKernelArgumentMetadata(Context, KernelMD,
2182 SPIR_MD_KERNEL_ARG_ADDR_SPACE, BF,
2183 [=](SPIRVFunctionParameter *Arg){
2184 SPIRVType *ArgTy = Arg->getType();
2185 SPIRAddressSpace AS = SPIRAS_Private;
2186 if (ArgTy->isTypePointer())
2187 AS = SPIRSPIRVAddrSpaceMap::rmap(ArgTy->getPointerStorageClass());
2188 else if (ArgTy->isTypeOCLImage() || ArgTy->isTypePipe())
2189 AS = SPIRAS_Global;
2190 return ConstantAsMetadata::get(
2191 ConstantInt::get(Type::getInt32Ty(*Context), AS));
2192 });
2193 // Generate metadata for kernel_arg_access_qual
2194 addOCLKernelArgumentMetadata(Context, KernelMD,
2195 SPIR_MD_KERNEL_ARG_ACCESS_QUAL, BF,
2196 [=](SPIRVFunctionParameter *Arg){
2197 std::string Qual;
2198 auto T = Arg->getType();
2199 if (T->isTypeOCLImage()) {
2200 auto ST = static_cast<SPIRVTypeImage *>(T);
2201 Qual = transOCLImageTypeAccessQualifier(ST);
2202 } else if (T->isTypePipe()){
2203 auto PT = static_cast<SPIRVTypePipe *>(T);
2204 Qual = transOCLPipeTypeAccessQualifier(PT);
2205 } else
2206 Qual = "none";
2207 return MDString::get(*Context, Qual);
2208 });
2209 // Generate metadata for kernel_arg_type
2210 addOCLKernelArgumentMetadata(Context, KernelMD,
2211 SPIR_MD_KERNEL_ARG_TYPE, BF,
2212 [=](SPIRVFunctionParameter *Arg){
2213 return transOCLKernelArgTypeName(Arg);
2214 });
2215 // Generate metadata for kernel_arg_type_qual
2216 addOCLKernelArgumentMetadata(Context, KernelMD,
2217 SPIR_MD_KERNEL_ARG_TYPE_QUAL, BF,
2218 [=](SPIRVFunctionParameter *Arg){
2219 std::string Qual;
2220 if (Arg->hasDecorate(DecorationVolatile))
2221 Qual = kOCLTypeQualifierName::Volatile;
2222 Arg->foreachAttr([&](SPIRVFuncParamAttrKind Kind){
2223 Qual += Qual.empty() ? "" : " ";
2224 switch(Kind){
2225 case FunctionParameterAttributeNoAlias:
2226 Qual += kOCLTypeQualifierName::Restrict;
2227 break;
2228 case FunctionParameterAttributeNoWrite:
2229 Qual += kOCLTypeQualifierName::Const;
2230 break;
2231 default:
2232 // do nothing.
2233 break;
2234 }
2235 });
2236 if (Arg->getType()->isTypePipe()) {
2237 Qual += Qual.empty() ? "" : " ";
2238 Qual += kOCLTypeQualifierName::Pipe;
2239 }
2240 return MDString::get(*Context, Qual);
2241 });
2242 // Generate metadata for kernel_arg_base_type
2243 addOCLKernelArgumentMetadata(Context, KernelMD,
2244 SPIR_MD_KERNEL_ARG_BASE_TYPE, BF,
2245 [=](SPIRVFunctionParameter *Arg){
2246 return transOCLKernelArgTypeName(Arg);
2247 });
2248 // Generate metadata for kernel_arg_name
2249 if (SPIRVGenKernelArgNameMD) {
2250 bool ArgHasName = true;
2251 BF->foreachArgument([&](SPIRVFunctionParameter *Arg){
2252 ArgHasName &= !Arg->getName().empty();
2253 });
2254 if (ArgHasName)
2255 addOCLKernelArgumentMetadata(Context, KernelMD,
2256 SPIR_MD_KERNEL_ARG_NAME, BF,
2257 [=](SPIRVFunctionParameter *Arg){
2258 return MDString::get(*Context, Arg->getName());
2259 });
2260 }
2261 // Generate metadata for reqd_work_group_size
2262 if (auto EM = BF->getExecutionMode(ExecutionModeLocalSize)) {
2263 KernelMD.push_back(getMDNodeStringIntVec(Context,
2264 kSPIR2MD::WGSize, EM->getLiterals()));
2265 }
2266 // Generate metadata for work_group_size_hint
2267 if (auto EM = BF->getExecutionMode(ExecutionModeLocalSizeHint)) {
2268 KernelMD.push_back(getMDNodeStringIntVec(Context,
2269 kSPIR2MD::WGSizeHint, EM->getLiterals()));
2270 }
2271 // Generate metadata for vec_type_hint
2272 if (auto EM = BF->getExecutionMode(ExecutionModeVecTypeHint)) {
2273 std::vector<Metadata*> MetadataVec;
2274 MetadataVec.push_back(MDString::get(*Context, kSPIR2MD::VecTyHint));
2275 Type *VecHintTy = decodeVecTypeHint(*Context, EM->getLiterals()[0]);
2276 assert(VecHintTy);
2277 MetadataVec.push_back(ValueAsMetadata::get(UndefValue::get(VecHintTy)));
2278 MetadataVec.push_back(
2279 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(*Context),
2280 1)));
2281 KernelMD.push_back(MDNode::get(*Context, MetadataVec));
2282 }
2283
2284 llvm::MDNode *Node = MDNode::get(*Context, KernelMD);
2285 KernelMDs->addOperand(Node);
2286 }
2287 return true;
2288 }
2289
2290 bool
transAlign(SPIRVValue * BV,Value * V)2291 SPIRVToLLVM::transAlign(SPIRVValue *BV, Value *V) {
2292 if (auto AL = dyn_cast<AllocaInst>(V)) {
2293 SPIRVWord Align = 0;
2294 if (BV->hasAlignment(&Align))
2295 AL->setAlignment(Align);
2296 return true;
2297 }
2298 if (auto GV = dyn_cast<GlobalVariable>(V)) {
2299 SPIRVWord Align = 0;
2300 if (BV->hasAlignment(&Align))
2301 GV->setAlignment(Align);
2302 return true;
2303 }
2304 return true;
2305 }
2306
2307 void
transOCLVectorLoadStore(std::string & UnmangledName,std::vector<SPIRVWord> & BArgs)2308 SPIRVToLLVM::transOCLVectorLoadStore(std::string& UnmangledName,
2309 std::vector<SPIRVWord> &BArgs) {
2310 if (UnmangledName.find("vload") == 0 &&
2311 UnmangledName.find("n") != std::string::npos) {
2312 if (BArgs.back() != 1) {
2313 std::stringstream SS;
2314 SS << BArgs.back();
2315 UnmangledName.replace(UnmangledName.find("n"), 1, SS.str());
2316 } else {
2317 UnmangledName.erase(UnmangledName.find("n"), 1);
2318 }
2319 BArgs.pop_back();
2320 } else if (UnmangledName.find("vstore") == 0) {
2321 if (UnmangledName.find("n") != std::string::npos) {
2322 auto T = BM->getValueType(BArgs[0]);
2323 if (T->isTypeVector()) {
2324 auto W = T->getVectorComponentCount();
2325 std::stringstream SS;
2326 SS << W;
2327 UnmangledName.replace(UnmangledName.find("n"), 1, SS.str());
2328 } else {
2329 UnmangledName.erase(UnmangledName.find("n"), 1);
2330 }
2331 }
2332 if (UnmangledName.find("_r") != std::string::npos) {
2333 UnmangledName.replace(UnmangledName.find("_r"), 2, std::string("_") +
2334 SPIRSPIRVFPRoundingModeMap::rmap(static_cast<SPIRVFPRoundingModeKind>(
2335 BArgs.back())));
2336 BArgs.pop_back();
2337 }
2338 }
2339 }
2340
2341 // printf is not mangled. The function type should have just one argument.
2342 // read_image*: the second argument should be mangled as sampler.
2343 Instruction *
transOCLBuiltinFromExtInst(SPIRVExtInst * BC,BasicBlock * BB)2344 SPIRVToLLVM::transOCLBuiltinFromExtInst(SPIRVExtInst *BC, BasicBlock *BB) {
2345 assert(BB && "Invalid BB");
2346 std::string MangledName;
2347 SPIRVWord EntryPoint = BC->getExtOp();
2348 SPIRVExtInstSetKind Set = BM->getBuiltinSet(BC->getExtSetId());
2349 bool IsVarArg = false;
2350 bool IsPrintf = false;
2351 std::string UnmangledName;
2352 auto BArgs = BC->getArguments();
2353
2354 (void) Set;
2355 assert (Set == SPIRVEIS_OpenCL && "Not OpenCL extended instruction");
2356 if (EntryPoint == OpenCLLIB::Printf)
2357 IsPrintf = true;
2358 else {
2359 UnmangledName = OCLExtOpMap::map(static_cast<OCLExtOpKind>(
2360 EntryPoint));
2361 }
2362
2363 SPIRVDBG(spvdbgs() << "[transOCLBuiltinFromExtInst] OrigUnmangledName: " <<
2364 UnmangledName << '\n');
2365 transOCLVectorLoadStore(UnmangledName, BArgs);
2366
2367 std::vector<Type *> ArgTypes = transTypeVector(BC->getValueTypes(BArgs));
2368
2369 if (IsPrintf) {
2370 MangledName = "printf";
2371 IsVarArg = true;
2372 ArgTypes.resize(1);
2373 } else if (UnmangledName.find("read_image") == 0) {
2374 auto ModifiedArgTypes = ArgTypes;
2375 ModifiedArgTypes[1] = getOrCreateOpaquePtrType(M, "opencl.sampler_t");
2376 MangleOpenCLBuiltin(UnmangledName, ModifiedArgTypes, MangledName);
2377 } else {
2378 MangleOpenCLBuiltin(UnmangledName, ArgTypes, MangledName);
2379 }
2380 SPIRVDBG(spvdbgs() << "[transOCLBuiltinFromExtInst] ModifiedUnmangledName: " <<
2381 UnmangledName << " MangledName: " << MangledName << '\n');
2382
2383 FunctionType *FT = FunctionType::get(
2384 transType(BC->getType()),
2385 ArgTypes,
2386 IsVarArg);
2387 Function *F = M->getFunction(MangledName);
2388 if (!F) {
2389 F = Function::Create(FT,
2390 GlobalValue::ExternalLinkage,
2391 MangledName,
2392 M);
2393 F->setCallingConv(CallingConv::SPIR_FUNC);
2394 if (isFuncNoUnwind())
2395 F->addFnAttr(Attribute::NoUnwind);
2396 }
2397 auto Args = transValue(BC->getValues(BArgs), F, BB);
2398 SPIRVDBG(dbgs() << "[transOCLBuiltinFromExtInst] Function: " << *F <<
2399 ", Args: ";
2400 for (auto &I:Args) dbgs() << *I << ", "; dbgs() << '\n');
2401 CallInst *Call = CallInst::Create(F,
2402 Args,
2403 BC->getName(),
2404 BB);
2405 setCallingConv(Call);
2406 addFnAttr(Context, Call, Attribute::NoUnwind);
2407 return transOCLBuiltinPostproc(BC, Call, BB, UnmangledName);
2408 }
2409
2410 CallInst *
transOCLBarrier(BasicBlock * BB,SPIRVWord ExecScope,SPIRVWord MemSema,SPIRVWord MemScope)2411 SPIRVToLLVM::transOCLBarrier(BasicBlock *BB, SPIRVWord ExecScope,
2412 SPIRVWord MemSema, SPIRVWord MemScope) {
2413 SPIRVWord Ver = 0;
2414 BM->getSourceLanguage(&Ver);
2415
2416 Type* Int32Ty = Type::getInt32Ty(*Context);
2417 Type* VoidTy = Type::getVoidTy(*Context);
2418
2419 std::string FuncName;
2420 SmallVector<Type *, 2> ArgTy;
2421 SmallVector<Value *, 2> Arg;
2422
2423 Constant *MemFenceFlags =
2424 ConstantInt::get(Int32Ty, rmapBitMask<OCLMemFenceMap>(MemSema));
2425
2426 FuncName = (ExecScope == ScopeWorkgroup) ? kOCLBuiltinName::WorkGroupBarrier
2427 : kOCLBuiltinName::SubGroupBarrier;
2428
2429 if (ExecScope == ScopeWorkgroup && Ver > 0 && Ver <= kOCLVer::CL12) {
2430 FuncName = kOCLBuiltinName::Barrier;
2431 ArgTy.push_back(Int32Ty);
2432 Arg.push_back(MemFenceFlags);
2433 } else {
2434 Constant *Scope = ConstantInt::get(Int32Ty, OCLMemScopeMap::rmap(
2435 static_cast<spv::Scope>(MemScope)));
2436
2437 ArgTy.append(2, Int32Ty);
2438 Arg.push_back(MemFenceFlags);
2439 Arg.push_back(Scope);
2440 }
2441
2442 std::string MangledName;
2443
2444 MangleOpenCLBuiltin(FuncName, ArgTy, MangledName);
2445 Function *Func = M->getFunction(MangledName);
2446 if (!Func) {
2447 FunctionType *FT = FunctionType::get(VoidTy, ArgTy, false);
2448 Func = Function::Create(FT, GlobalValue::ExternalLinkage, MangledName, M);
2449 Func->setCallingConv(CallingConv::SPIR_FUNC);
2450 if (isFuncNoUnwind())
2451 Func->addFnAttr(Attribute::NoUnwind);
2452 }
2453
2454 return CallInst::Create(Func, Arg, "", BB);
2455 }
2456
2457 CallInst *
transOCLMemFence(BasicBlock * BB,SPIRVWord MemSema,SPIRVWord MemScope)2458 SPIRVToLLVM::transOCLMemFence(BasicBlock *BB,
2459 SPIRVWord MemSema, SPIRVWord MemScope) {
2460 SPIRVWord Ver = 0;
2461 BM->getSourceLanguage(&Ver);
2462
2463 Type* Int32Ty = Type::getInt32Ty(*Context);
2464 Type* VoidTy = Type::getVoidTy(*Context);
2465
2466 std::string FuncName;
2467 SmallVector<Type *, 3> ArgTy;
2468 SmallVector<Value *, 3> Arg;
2469
2470 Constant *MemFenceFlags =
2471 ConstantInt::get(Int32Ty, rmapBitMask<OCLMemFenceMap>(MemSema));
2472
2473 if (Ver > 0 && Ver <= kOCLVer::CL12) {
2474 FuncName = kOCLBuiltinName::MemFence;
2475 ArgTy.push_back(Int32Ty);
2476 Arg.push_back(MemFenceFlags);
2477 } else {
2478 Constant *Order =
2479 ConstantInt::get(Int32Ty, mapSPIRVMemOrderToOCL(MemSema));
2480
2481 Constant *Scope = ConstantInt::get(Int32Ty, OCLMemScopeMap::rmap(
2482 static_cast<spv::Scope>(MemScope)));
2483
2484 FuncName = kOCLBuiltinName::AtomicWorkItemFence;
2485 ArgTy.append(3, Int32Ty);
2486 Arg.push_back(MemFenceFlags);
2487 Arg.push_back(Order);
2488 Arg.push_back(Scope);
2489 }
2490
2491 std::string MangledName;
2492
2493 MangleOpenCLBuiltin(FuncName, ArgTy, MangledName);
2494 Function *Func = M->getFunction(MangledName);
2495 if (!Func) {
2496 FunctionType *FT = FunctionType::get(VoidTy, ArgTy, false);
2497 Func = Function::Create(FT, GlobalValue::ExternalLinkage, MangledName, M);
2498 Func->setCallingConv(CallingConv::SPIR_FUNC);
2499 if (isFuncNoUnwind())
2500 Func->addFnAttr(Attribute::NoUnwind);
2501 }
2502
2503 return CallInst::Create(Func, Arg, "", BB);
2504 }
2505
2506 Instruction *
transOCLBarrierFence(SPIRVInstruction * MB,BasicBlock * BB)2507 SPIRVToLLVM::transOCLBarrierFence(SPIRVInstruction *MB, BasicBlock *BB) {
2508 assert(BB && "Invalid BB");
2509 std::string FuncName;
2510 auto getIntVal = [](SPIRVValue *value){
2511 return static_cast<SPIRVConstant*>(value)->getZExtIntValue();
2512 };
2513
2514 CallInst* Call = nullptr;
2515
2516 if (MB->getOpCode() == OpMemoryBarrier) {
2517 auto MemB = static_cast<SPIRVMemoryBarrier*>(MB);
2518
2519 SPIRVWord MemScope = getIntVal(MemB->getOpValue(0));
2520 SPIRVWord MemSema = getIntVal(MemB->getOpValue(1));
2521
2522 Call = transOCLMemFence(BB, MemSema, MemScope);
2523 } else if (MB->getOpCode() == OpControlBarrier) {
2524 auto CtlB = static_cast<SPIRVControlBarrier*>(MB);
2525
2526 SPIRVWord ExecScope = getIntVal(CtlB->getExecScope());
2527 SPIRVWord MemSema = getIntVal(CtlB->getMemSemantic());
2528 SPIRVWord MemScope = getIntVal(CtlB->getMemScope());
2529
2530 Call = transOCLBarrier(BB, ExecScope, MemSema, MemScope);
2531 } else {
2532 llvm_unreachable("Invalid instruction");
2533 }
2534
2535 setName(Call, MB);
2536 setAttrByCalledFunc(Call);
2537 SPIRVDBG(spvdbgs() << "[transBarrier] " << *MB << " -> ";
2538 dbgs() << *Call << '\n';)
2539
2540 return Call;
2541 }
2542
2543 // SPIR-V only contains language version. Use OpenCL language version as
2544 // SPIR version.
2545 bool
transSourceLanguage()2546 SPIRVToLLVM::transSourceLanguage() {
2547 SPIRVWord Ver = 0;
2548 SourceLanguage Lang = BM->getSourceLanguage(&Ver);
2549 assert((Lang == SourceLanguageOpenCL_C ||
2550 Lang == SourceLanguageOpenCL_CPP) && "Unsupported source language");
2551 unsigned short Major = 0;
2552 unsigned char Minor = 0;
2553 unsigned char Rev = 0;
2554 std::tie(Major, Minor, Rev) = decodeOCLVer(Ver);
2555 SPIRVMDBuilder Builder(*M);
2556 Builder.addNamedMD(kSPIRVMD::Source)
2557 .addOp()
2558 .add(Lang)
2559 .add(Ver)
2560 .done();
2561 // ToDo: Phasing out usage of old SPIR metadata
2562 if (Ver <= kOCLVer::CL12)
2563 addOCLVersionMetadata(Context, M, kSPIR2MD::SPIRVer, 1, 2);
2564 else
2565 addOCLVersionMetadata(Context, M, kSPIR2MD::SPIRVer, 2, 0);
2566
2567 addOCLVersionMetadata(Context, M, kSPIR2MD::OCLVer, Major, Minor);
2568 return true;
2569 }
2570
2571 bool
transSourceExtension()2572 SPIRVToLLVM::transSourceExtension() {
2573 auto ExtSet = rmap<OclExt::Kind>(BM->getExtension());
2574 auto CapSet = rmap<OclExt::Kind>(BM->getCapability());
2575 ExtSet.insert(CapSet.begin(), CapSet.end());
2576 auto OCLExtensions = map<std::string>(ExtSet);
2577 std::set<std::string> OCLOptionalCoreFeatures;
2578 static const char *OCLOptCoreFeatureNames[] = {
2579 "cl_images", "cl_doubles",
2580 };
2581 for (auto &I : OCLOptCoreFeatureNames) {
2582 auto Loc = OCLExtensions.find(I);
2583 if (Loc != OCLExtensions.end()) {
2584 OCLExtensions.erase(Loc);
2585 OCLOptionalCoreFeatures.insert(I);
2586 }
2587 }
2588 addNamedMetadataStringSet(Context, M, kSPIR2MD::Extensions, OCLExtensions);
2589 addNamedMetadataStringSet(Context, M, kSPIR2MD::OptFeatures,
2590 OCLOptionalCoreFeatures);
2591 return true;
2592 }
2593
2594 // If the argument is unsigned return uconvert*, otherwise return convert*.
2595 std::string
getOCLConvertBuiltinName(SPIRVInstruction * BI)2596 SPIRVToLLVM::getOCLConvertBuiltinName(SPIRVInstruction* BI) {
2597 auto OC = BI->getOpCode();
2598 assert(isCvtOpCode(OC) && "Not convert instruction");
2599 auto U = static_cast<SPIRVUnary *>(BI);
2600 std::string Name;
2601 if (isCvtFromUnsignedOpCode(OC))
2602 Name = "u";
2603 Name += "convert_";
2604 Name += mapSPIRVTypeToOCLType(U->getType(),
2605 !isCvtToUnsignedOpCode(OC));
2606 SPIRVFPRoundingModeKind Rounding;
2607 if (U->isSaturatedConversion())
2608 Name += "_sat";
2609 if (U->hasFPRoundingMode(&Rounding)) {
2610 Name += "_";
2611 Name += SPIRSPIRVFPRoundingModeMap::rmap(Rounding);
2612 }
2613 return Name;
2614 }
2615
2616 //Check Address Space of the Pointer Type
2617 std::string
getOCLGenericCastToPtrName(SPIRVInstruction * BI)2618 SPIRVToLLVM::getOCLGenericCastToPtrName(SPIRVInstruction* BI) {
2619 auto GenericCastToPtrInst = BI->getType()->getPointerStorageClass();
2620 switch (GenericCastToPtrInst) {
2621 case StorageClassCrossWorkgroup:
2622 return std::string(kOCLBuiltinName::ToGlobal);
2623 case StorageClassWorkgroup:
2624 return std::string(kOCLBuiltinName::ToLocal);
2625 case StorageClassFunction:
2626 return std::string(kOCLBuiltinName::ToPrivate);
2627 default:
2628 llvm_unreachable("Invalid address space");
2629 return "";
2630 }
2631 }
2632
2633 llvm::GlobalValue::LinkageTypes
transLinkageType(const SPIRVValue * V)2634 SPIRVToLLVM::transLinkageType(const SPIRVValue* V) {
2635 if (V->getLinkageType() == LinkageTypeInternal) {
2636 return GlobalValue::InternalLinkage;
2637 }
2638 else if (V->getLinkageType() == LinkageTypeImport) {
2639 // Function declaration
2640 if (V->getOpCode() == OpFunction) {
2641 if (static_cast<const SPIRVFunction*>(V)->getNumBasicBlock() == 0)
2642 return GlobalValue::ExternalLinkage;
2643 }
2644 // Variable declaration
2645 if (V->getOpCode() == OpVariable) {
2646 if (static_cast<const SPIRVVariable*>(V)->getInitializer() == 0)
2647 return GlobalValue::ExternalLinkage;
2648 }
2649 // Definition
2650 return GlobalValue::AvailableExternallyLinkage;
2651 }
2652 else {// LinkageTypeExport
2653 if (V->getOpCode() == OpVariable) {
2654 if (static_cast<const SPIRVVariable*>(V)->getInitializer() == 0 )
2655 // Tentative definition
2656 return GlobalValue::CommonLinkage;
2657 }
2658 return GlobalValue::ExternalLinkage;
2659 }
2660 }
2661
transOCLAllAny(SPIRVInstruction * I,BasicBlock * BB)2662 Instruction *SPIRVToLLVM::transOCLAllAny(SPIRVInstruction *I, BasicBlock *BB) {
2663 CallInst *CI = cast<CallInst>(transSPIRVBuiltinFromInst(I, BB));
2664 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
2665 return cast<Instruction>(mapValue(
2666 I, mutateCallInstOCL(
2667 M, CI,
2668 [=](CallInst *, std::vector<Value *> &Args, llvm::Type *&RetTy) {
2669 Type *Int32Ty = Type::getInt32Ty(*Context);
2670 auto OldArg = CI->getOperand(0);
2671 auto NewArgTy = VectorType::get(
2672 Int32Ty, OldArg->getType()->getVectorNumElements());
2673 auto NewArg =
2674 CastInst::CreateSExtOrBitCast(OldArg, NewArgTy, "", CI);
2675 Args[0] = NewArg;
2676 RetTy = Int32Ty;
2677 return CI->getCalledFunction()->getName();
2678 },
2679 [=](CallInst *NewCI) -> Instruction * {
2680 return CastInst::CreateTruncOrBitCast(
2681 NewCI, Type::getInt1Ty(*Context), "", NewCI->getNextNode());
2682 },
2683 &Attrs)));
2684 }
2685
transOCLRelational(SPIRVInstruction * I,BasicBlock * BB)2686 Instruction *SPIRVToLLVM::transOCLRelational(SPIRVInstruction *I, BasicBlock *BB) {
2687 CallInst *CI = cast<CallInst>(transSPIRVBuiltinFromInst(I, BB));
2688 AttributeSet Attrs = CI->getCalledFunction()->getAttributes();
2689 return cast<Instruction>(mapValue(
2690 I, mutateCallInstOCL(
2691 M, CI,
2692 [=](CallInst *, std::vector<Value *> &Args, llvm::Type *&RetTy) {
2693 Type *IntTy = Type::getInt32Ty(*Context);
2694 RetTy = IntTy;
2695 if (CI->getType()->isVectorTy()) {
2696 if (cast<VectorType>(CI->getOperand(0)->getType())
2697 ->getElementType()
2698 ->isDoubleTy())
2699 IntTy = Type::getInt64Ty(*Context);
2700 if (cast<VectorType>(CI->getOperand(0)->getType())
2701 ->getElementType()
2702 ->isHalfTy())
2703 IntTy = Type::getInt16Ty(*Context);
2704 RetTy = VectorType::get(IntTy,
2705 CI->getType()->getVectorNumElements());
2706 }
2707 return CI->getCalledFunction()->getName();
2708 },
2709 [=](CallInst *NewCI) -> Instruction * {
2710 Type *RetTy = Type::getInt1Ty(*Context);
2711 if (NewCI->getType()->isVectorTy())
2712 RetTy =
2713 VectorType::get(Type::getInt1Ty(*Context),
2714 NewCI->getType()->getVectorNumElements());
2715 return CastInst::CreateTruncOrBitCast(NewCI, RetTy, "",
2716 NewCI->getNextNode());
2717 },
2718 &Attrs)));
2719 }
2720 }
2721
2722 bool
ReadSPIRV(LLVMContext & C,std::istream & IS,Module * & M,std::string & ErrMsg)2723 llvm::ReadSPIRV(LLVMContext &C, std::istream &IS, Module *&M,
2724 std::string &ErrMsg) {
2725 M = new Module("", C);
2726 std::unique_ptr<SPIRVModule> BM(SPIRVModule::createSPIRVModule());
2727
2728 IS >> *BM;
2729
2730 SPIRVToLLVM BTL(M, BM.get());
2731 bool Succeed = true;
2732 if (!BTL.translate()) {
2733 BM->getError(ErrMsg);
2734 Succeed = false;
2735 }
2736 legacy::PassManager PassMgr;
2737 PassMgr.add(createSPIRVToOCL20());
2738 PassMgr.add(createOCL20To12());
2739 PassMgr.run(*M);
2740
2741 if (DbgSaveTmpLLVM)
2742 dumpLLVM(M, DbgTmpLLVMFileName);
2743 if (!Succeed) {
2744 delete M;
2745 M = nullptr;
2746 }
2747 return Succeed;
2748 }
2749