1 //===- SPIRVUtil.cpp - SPIR-V Utilities -------------------------*- C++ -*-===// 2 // 3 // The LLVM/SPIRV 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 defines utility classes and functions shared by SPIR-V 37 /// reader/writer. 38 /// 39 //===----------------------------------------------------------------------===// 40 41 #include "SPIRVInternal.h" 42 #include "libSPIRV/SPIRVDecorate.h" 43 #include "libSPIRV/SPIRVValue.h" 44 #include "SPIRVMDWalker.h" 45 #include "OCLUtil.h" 46 47 #include "llvm/ADT/StringSwitch.h" 48 #include "llvm/Bitcode/ReaderWriter.h" 49 #include "llvm/IR/IRBuilder.h" 50 #include "llvm/Support/CommandLine.h" 51 #include "llvm/Support/Debug.h" 52 #include "llvm/Support/ErrorHandling.h" 53 #include "llvm/Support/FileSystem.h" 54 #include "llvm/Support/ToolOutputFile.h" 55 #include "llvm/Support/raw_ostream.h" 56 57 #include <functional> 58 #include <sstream> 59 60 #define DEBUG_TYPE "spirv" 61 62 namespace SPIRV{ 63 64 #ifdef _SPIRV_SUPPORT_TEXT_FMT 65 cl::opt<bool, true> 66 UseTextFormat("spirv-text", 67 cl::desc("Use text format for SPIR-V for debugging purpose"), 68 cl::location(SPIRVUseTextFormat)); 69 #endif 70 71 #ifdef _SPIRVDBG 72 cl::opt<bool, true> 73 EnableDbgOutput("spirv-debug", 74 cl::desc("Enable SPIR-V debug output"), 75 cl::location(SPIRVDbgEnable)); 76 #endif 77 78 void 79 addFnAttr(LLVMContext *Context, CallInst *Call, Attribute::AttrKind Attr) { 80 Call->addAttribute(AttributeSet::FunctionIndex, Attr); 81 } 82 83 void 84 removeFnAttr(LLVMContext *Context, CallInst *Call, Attribute::AttrKind Attr) { 85 Call->removeAttribute(AttributeSet::FunctionIndex, 86 Attribute::get(*Context, Attr)); 87 } 88 89 Value * 90 removeCast(Value *V) { 91 auto Cast = dyn_cast<ConstantExpr>(V); 92 if (Cast && Cast->isCast()) { 93 return removeCast(Cast->getOperand(0)); 94 } 95 if (auto Cast = dyn_cast<CastInst>(V)) 96 return removeCast(Cast->getOperand(0)); 97 return V; 98 } 99 100 void 101 saveLLVMModule(Module *M, const std::string &OutputFile) { 102 std::error_code EC; 103 tool_output_file Out(OutputFile.c_str(), EC, sys::fs::F_None); 104 if (EC) { 105 SPIRVDBG(errs() << "Fails to open output file: " << EC.message();) 106 return; 107 } 108 109 WriteBitcodeToFile(M, Out.os()); 110 Out.keep(); 111 } 112 113 std::string 114 mapLLVMTypeToOCLType(const Type* Ty, bool Signed) { 115 if (Ty->isHalfTy()) 116 return "half"; 117 if (Ty->isFloatTy()) 118 return "float"; 119 if (Ty->isDoubleTy()) 120 return "double"; 121 if (auto intTy = dyn_cast<IntegerType>(Ty)) { 122 std::string SignPrefix; 123 std::string Stem; 124 if (!Signed) 125 SignPrefix = "u"; 126 switch (intTy->getIntegerBitWidth()) { 127 case 8: 128 Stem = "char"; 129 break; 130 case 16: 131 Stem = "short"; 132 break; 133 case 32: 134 Stem = "int"; 135 break; 136 case 64: 137 Stem = "long"; 138 break; 139 default: 140 Stem = "invalid_type"; 141 break; 142 } 143 return SignPrefix + Stem; 144 } 145 if (auto vecTy = dyn_cast<VectorType>(Ty)) { 146 Type* eleTy = vecTy->getElementType(); 147 unsigned size = vecTy->getVectorNumElements(); 148 std::stringstream ss; 149 ss << mapLLVMTypeToOCLType(eleTy, Signed) << size; 150 return ss.str(); 151 } 152 return "invalid_type"; 153 } 154 155 std::string 156 mapSPIRVTypeToOCLType(SPIRVType* Ty, bool Signed) { 157 if (Ty->isTypeFloat()) { 158 auto W = Ty->getBitWidth(); 159 switch (W) { 160 case 16: 161 return "half"; 162 case 32: 163 return "float"; 164 case 64: 165 return "double"; 166 default: 167 assert (0 && "Invalid floating pointer type"); 168 return std::string("float") + W + "_t"; 169 } 170 } 171 if (Ty->isTypeInt()) { 172 std::string SignPrefix; 173 std::string Stem; 174 if (!Signed) 175 SignPrefix = "u"; 176 auto W = Ty->getBitWidth(); 177 switch (W) { 178 case 8: 179 Stem = "char"; 180 break; 181 case 16: 182 Stem = "short"; 183 break; 184 case 32: 185 Stem = "int"; 186 break; 187 case 64: 188 Stem = "long"; 189 break; 190 default: 191 llvm_unreachable("Invalid integer type"); 192 Stem = std::string("int") + W + "_t"; 193 break; 194 } 195 return SignPrefix + Stem; 196 } 197 if (Ty->isTypeVector()) { 198 auto eleTy = Ty->getVectorComponentType(); 199 auto size = Ty->getVectorComponentCount(); 200 std::stringstream ss; 201 ss << mapSPIRVTypeToOCLType(eleTy, Signed) << size; 202 return ss.str(); 203 } 204 llvm_unreachable("Invalid type"); 205 return "unknown_type"; 206 } 207 208 PointerType* 209 getOrCreateOpaquePtrType(Module *M, const std::string &Name, 210 unsigned AddrSpace) { 211 auto OpaqueType = M->getTypeByName(Name); 212 if (!OpaqueType) 213 OpaqueType = StructType::create(M->getContext(), Name); 214 return PointerType::get(OpaqueType, AddrSpace); 215 } 216 217 PointerType* 218 getSamplerType(Module *M) { 219 return getOrCreateOpaquePtrType(M, getSPIRVTypeName(kSPIRVTypeName::Sampler), 220 SPIRAS_Constant); 221 } 222 223 PointerType* 224 getPipeStorageType(Module* M) { 225 return getOrCreateOpaquePtrType(M, getSPIRVTypeName( 226 kSPIRVTypeName::PipeStorage), 227 SPIRAS_Constant); 228 } 229 230 231 void 232 getFunctionTypeParameterTypes(llvm::FunctionType* FT, 233 std::vector<Type*>& ArgTys) { 234 for (auto I = FT->param_begin(), E = FT->param_end(); I != E; ++I) { 235 ArgTys.push_back(*I); 236 } 237 } 238 239 bool 240 isVoidFuncTy(FunctionType *FT) { 241 return FT->getReturnType()->isVoidTy() && FT->getNumParams() == 0; 242 } 243 244 bool 245 isPointerToOpaqueStructType(llvm::Type* Ty) { 246 if (auto PT = dyn_cast<PointerType>(Ty)) 247 if (auto ST = dyn_cast<StructType>(PT->getElementType())) 248 if (ST->isOpaque()) 249 return true; 250 return false; 251 } 252 253 bool 254 isPointerToOpaqueStructType(llvm::Type* Ty, const std::string &Name) { 255 if (auto PT = dyn_cast<PointerType>(Ty)) 256 if (auto ST = dyn_cast<StructType>(PT->getElementType())) 257 if (ST->isOpaque() && ST->getName() == Name) 258 return true; 259 return false; 260 } 261 262 bool 263 isOCLImageType(llvm::Type* Ty, StringRef *Name) { 264 if (auto PT = dyn_cast<PointerType>(Ty)) 265 if (auto ST = dyn_cast<StructType>(PT->getElementType())) 266 if (ST->isOpaque()) { 267 auto FullName = ST->getName(); 268 if (FullName.find(kSPR2TypeName::ImagePrefix) == 0) { 269 if (Name) 270 *Name = FullName.drop_front(strlen(kSPR2TypeName::OCLPrefix)); 271 return true; 272 } 273 } 274 return false; 275 } 276 277 /// \param BaseTyName is the type name as in spirv.BaseTyName.Postfixes 278 /// \param Postfix contains postfixes extracted from the SPIR-V image 279 /// type name as spirv.BaseTyName.Postfixes. 280 bool 281 isSPIRVType(llvm::Type* Ty, StringRef BaseTyName, StringRef *Postfix) { 282 if (auto PT = dyn_cast<PointerType>(Ty)) 283 if (auto ST = dyn_cast<StructType>(PT->getElementType())) 284 if (ST->isOpaque()) { 285 auto FullName = ST->getName(); 286 std::string N = std::string(kSPIRVTypeName::PrefixAndDelim) + 287 BaseTyName.str(); 288 if (FullName != N) 289 N = N + kSPIRVTypeName::Delimiter; 290 if (FullName.startswith(N)) { 291 if (Postfix) 292 *Postfix = FullName.drop_front(N.size()); 293 return true; 294 } 295 } 296 return false; 297 } 298 299 Function * 300 getOrCreateFunction(Module *M, Type *RetTy, ArrayRef<Type *> ArgTypes, 301 StringRef Name, BuiltinFuncMangleInfo *Mangle, AttributeSet *Attrs, 302 bool takeName) { 303 std::string MangledName = Name; 304 bool isVarArg = false; 305 if (Mangle) { 306 MangledName = mangleBuiltin(Name, ArgTypes, Mangle); 307 isVarArg = 0 <= Mangle->getVarArg(); 308 if(isVarArg) ArgTypes = ArgTypes.slice(0, Mangle->getVarArg()); 309 } 310 FunctionType *FT = FunctionType::get(RetTy, ArgTypes, isVarArg); 311 Function *F = M->getFunction(MangledName); 312 if (!takeName && F && F->getFunctionType() != FT && Mangle != nullptr) { 313 std::string S; 314 raw_string_ostream SS(S); 315 SS << "Error: Attempt to redefine function: " << *F << " => " << 316 *FT << '\n'; 317 report_fatal_error(SS.str(), false); 318 } 319 if (!F || F->getFunctionType() != FT) { 320 auto NewF = Function::Create(FT, 321 GlobalValue::ExternalLinkage, 322 MangledName, 323 M); 324 if (F && takeName) { 325 NewF->takeName(F); 326 DEBUG(dbgs() << "[getOrCreateFunction] Warning: taking function name\n"); 327 } 328 if (NewF->getName() != MangledName) { 329 DEBUG(dbgs() << "[getOrCreateFunction] Warning: function name changed\n"); 330 } 331 DEBUG(dbgs() << "[getOrCreateFunction] "; 332 if (F) 333 dbgs() << *F << " => "; 334 dbgs() << *NewF << '\n'; 335 ); 336 F = NewF; 337 F->setCallingConv(CallingConv::SPIR_FUNC); 338 if (Attrs) 339 F->setAttributes(*Attrs); 340 } 341 return F; 342 } 343 344 std::vector<Value *> 345 getArguments(CallInst* CI, unsigned Start, unsigned End) { 346 std::vector<Value*> Args; 347 if (End == 0) 348 End = CI->getNumArgOperands(); 349 for (; Start != End; ++Start) { 350 Args.push_back(CI->getArgOperand(Start)); 351 } 352 return Args; 353 } 354 355 uint64_t getArgAsInt(CallInst *CI, unsigned I){ 356 return cast<ConstantInt>(CI->getArgOperand(I))->getZExtValue(); 357 } 358 359 Scope getArgAsScope(CallInst *CI, unsigned I){ 360 return static_cast<Scope>(getArgAsInt(CI, I)); 361 } 362 363 Decoration getArgAsDecoration(CallInst *CI, unsigned I) { 364 return static_cast<Decoration>(getArgAsInt(CI, I)); 365 } 366 367 std::string 368 decorateSPIRVFunction(const std::string &S) { 369 return std::string(kSPIRVName::Prefix) + S + kSPIRVName::Postfix; 370 } 371 372 std::string 373 undecorateSPIRVFunction(const std::string& S) { 374 assert (S.find(kSPIRVName::Prefix) == 0); 375 const size_t Start = strlen(kSPIRVName::Prefix); 376 auto End = S.rfind(kSPIRVName::Postfix); 377 return S.substr(Start, End - Start); 378 } 379 380 std::string 381 prefixSPIRVName(const std::string &S) { 382 return std::string(kSPIRVName::Prefix) + S; 383 } 384 385 StringRef 386 dePrefixSPIRVName(StringRef R, 387 SmallVectorImpl<StringRef> &Postfix) { 388 const size_t Start = strlen(kSPIRVName::Prefix); 389 if (!R.startswith(kSPIRVName::Prefix)) 390 return R; 391 R = R.drop_front(Start); 392 R.split(Postfix, "_", -1, false); 393 auto Name = Postfix.front(); 394 Postfix.erase(Postfix.begin()); 395 return Name; 396 } 397 398 std::string 399 getSPIRVFuncName(Op OC, StringRef PostFix) { 400 return prefixSPIRVName(getName(OC) + PostFix.str()); 401 } 402 403 std::string 404 getSPIRVFuncName(Op OC, const Type *pRetTy, bool IsSigned) { 405 return prefixSPIRVName(getName(OC) + kSPIRVPostfix::Divider + 406 getPostfixForReturnType(pRetTy, false)); 407 } 408 409 std::string 410 getSPIRVExtFuncName(SPIRVExtInstSetKind Set, unsigned ExtOp, 411 StringRef PostFix) { 412 std::string ExtOpName; 413 switch(Set) { 414 default: 415 llvm_unreachable("invalid extended instruction set"); 416 ExtOpName = "unknown"; 417 break; 418 case SPIRVEIS_OpenCL: 419 ExtOpName = getName(static_cast<OCLExtOpKind>(ExtOp)); 420 break; 421 } 422 return prefixSPIRVName(SPIRVExtSetShortNameMap::map(Set) 423 + '_' + ExtOpName + PostFix.str()); 424 } 425 426 SPIRVDecorate * 427 mapPostfixToDecorate(StringRef Postfix, SPIRVEntry *Target) { 428 if (Postfix == kSPIRVPostfix::Sat) 429 return new SPIRVDecorate(spv::DecorationSaturatedConversion, Target); 430 431 if (Postfix.startswith(kSPIRVPostfix::Rt)) 432 return new SPIRVDecorate(spv::DecorationFPRoundingMode, Target, 433 map<SPIRVFPRoundingModeKind>(Postfix.str())); 434 435 return nullptr; 436 } 437 438 SPIRVValue * 439 addDecorations(SPIRVValue *Target, const SmallVectorImpl<std::string>& Decs){ 440 for (auto &I:Decs) 441 if (auto Dec = mapPostfixToDecorate(I, Target)) 442 Target->addDecorate(Dec); 443 return Target; 444 } 445 446 std::string 447 getPostfix(Decoration Dec, unsigned Value) { 448 switch(Dec) { 449 default: 450 llvm_unreachable("not implemented"); 451 return "unknown"; 452 case spv::DecorationSaturatedConversion: 453 return kSPIRVPostfix::Sat; 454 case spv::DecorationFPRoundingMode: 455 return rmap<std::string>(static_cast<SPIRVFPRoundingModeKind>(Value)); 456 } 457 } 458 459 std::string 460 getPostfixForReturnType(CallInst *CI, bool IsSigned) { 461 return getPostfixForReturnType(CI->getType(), IsSigned); 462 } 463 464 std::string getPostfixForReturnType(const Type *pRetTy, bool IsSigned) { 465 return std::string(kSPIRVPostfix::Return) + 466 mapLLVMTypeToOCLType(pRetTy, IsSigned); 467 } 468 469 Op 470 getSPIRVFuncOC(const std::string& S, SmallVectorImpl<std::string> *Dec) { 471 Op OC; 472 SmallVector<StringRef, 2> Postfix; 473 std::string Name; 474 if (!oclIsBuiltin(S, &Name)) 475 Name = S; 476 StringRef R(Name); 477 R = dePrefixSPIRVName(R, Postfix); 478 if (!getByName(R.str(), OC)) 479 return OpNop; 480 if (Dec) 481 for (auto &I:Postfix) 482 Dec->push_back(I.str()); 483 return OC; 484 } 485 486 bool 487 getSPIRVBuiltin(const std::string &OrigName, spv::BuiltIn &B) { 488 SmallVector<StringRef, 2> Postfix; 489 StringRef R(OrigName); 490 R = dePrefixSPIRVName(R, Postfix); 491 assert(Postfix.empty() && "Invalid SPIR-V builtin name"); 492 return getByName(R.str(), B); 493 } 494 495 bool oclIsBuiltin(const StringRef &Name, std::string *DemangledName, 496 bool isCPP) { 497 if (Name == "printf") { 498 if (DemangledName) 499 *DemangledName = Name; 500 return true; 501 } 502 if (!Name.startswith("_Z")) 503 return false; 504 if (!DemangledName) 505 return true; 506 // OpenCL C++ built-ins are declared in cl namespace. 507 // TODO: consider using 'St' abbriviation for cl namespace mangling. 508 // Similar to ::std:: in C++. 509 if (isCPP) { 510 if (!Name.startswith("_ZN")) 511 return false; 512 // Skip CV and ref qualifiers. 513 size_t NameSpaceStart = Name.find_first_not_of("rVKRO", 3); 514 // All built-ins are in the ::cl:: namespace. 515 if (Name.substr(NameSpaceStart, 11) != "2cl7__spirv") 516 return false; 517 size_t DemangledNameLenStart = NameSpaceStart + 11; 518 size_t Start = Name.find_first_not_of("0123456789", DemangledNameLenStart); 519 size_t Len = 0; 520 Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart) 521 .getAsInteger(10, Len); 522 *DemangledName = Name.substr(Start, Len); 523 } else { 524 size_t Start = Name.find_first_not_of("0123456789", 2); 525 size_t Len = 0; 526 Name.substr(2, Start - 2).getAsInteger(10, Len); 527 *DemangledName = Name.substr(Start, Len); 528 } 529 return true; 530 } 531 532 // Check if a mangled type name is unsigned 533 bool isMangledTypeUnsigned(char Mangled) { 534 return Mangled == 'h' /* uchar */ 535 || Mangled == 't' /* ushort */ 536 || Mangled == 'j' /* uint */ 537 || Mangled == 'm' /* ulong */; 538 } 539 540 // Check if a mangled type name is signed 541 bool isMangledTypeSigned(char Mangled) { 542 return Mangled == 'c' /* char */ 543 || Mangled == 'a' /* signed char */ 544 || Mangled == 's' /* short */ 545 || Mangled == 'i' /* int */ 546 || Mangled == 'l' /* long */; 547 } 548 549 // Check if a mangled type name is floating point (excludes half) 550 bool isMangledTypeFP(char Mangled) { 551 return Mangled == 'f' /* float */ 552 || Mangled == 'd'; /* double */ 553 } 554 555 // Check if a mangled type name is half 556 bool isMangledTypeHalf(std::string Mangled) { 557 return Mangled == "Dh"; /* half */ 558 } 559 560 void 561 eraseSubstitutionFromMangledName(std::string& MangledName) { 562 auto Len = MangledName.length(); 563 while (Len >= 2 && MangledName.substr(Len - 2, 2) == "S_") { 564 Len -= 2; 565 MangledName.erase(Len, 2); 566 } 567 } 568 569 ParamType LastFuncParamType(const std::string &MangledName) { 570 auto Copy = MangledName; 571 eraseSubstitutionFromMangledName(Copy); 572 char Mangled = Copy.back(); 573 std::string Mangled2 = Copy.substr(Copy.size() - 2); 574 575 if (isMangledTypeFP(Mangled) || isMangledTypeHalf(Mangled2)) { 576 return ParamType::FLOAT; 577 } else if (isMangledTypeUnsigned(Mangled)) { 578 return ParamType::UNSIGNED; 579 } else if (isMangledTypeSigned(Mangled)) { 580 return ParamType::SIGNED; 581 } 582 583 return ParamType::UNKNOWN; 584 } 585 586 // Check if the last argument is signed 587 bool 588 isLastFuncParamSigned(const std::string& MangledName) { 589 return LastFuncParamType(MangledName) == ParamType::SIGNED; 590 } 591 592 593 // Check if a mangled function name contains unsigned atomic type 594 bool 595 containsUnsignedAtomicType(StringRef Name) { 596 auto Loc = Name.find(kMangledName::AtomicPrefixIncoming); 597 if (Loc == StringRef::npos) 598 return false; 599 return isMangledTypeUnsigned(Name[Loc + strlen( 600 kMangledName::AtomicPrefixIncoming)]); 601 } 602 603 bool 604 isFunctionPointerType(Type *T) { 605 if (isa<PointerType>(T) && 606 isa<FunctionType>(T->getPointerElementType())) { 607 return true; 608 } 609 return false; 610 } 611 612 bool 613 hasFunctionPointerArg(Function *F, Function::arg_iterator& AI) { 614 AI = F->arg_begin(); 615 for (auto AE = F->arg_end(); AI != AE; ++AI) { 616 DEBUG(dbgs() << "[hasFuncPointerArg] " << *AI << '\n'); 617 if (isFunctionPointerType(AI->getType())) { 618 return true; 619 } 620 } 621 return false; 622 } 623 624 Constant * 625 castToVoidFuncPtr(Function *F) { 626 auto T = getVoidFuncPtrType(F->getParent()); 627 return ConstantExpr::getBitCast(F, T); 628 } 629 630 bool 631 hasArrayArg(Function *F) { 632 for (auto I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { 633 DEBUG(dbgs() << "[hasArrayArg] " << *I << '\n'); 634 if (I->getType()->isArrayTy()) { 635 return true; 636 } 637 } 638 return false; 639 } 640 641 CallInst * 642 mutateCallInst(Module *M, CallInst *CI, 643 std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate, 644 BuiltinFuncMangleInfo *Mangle, AttributeSet *Attrs, bool TakeFuncName) { 645 DEBUG(dbgs() << "[mutateCallInst] " << *CI); 646 647 auto Args = getArguments(CI); 648 auto NewName = ArgMutate(CI, Args); 649 std::string InstName; 650 if (!CI->getType()->isVoidTy() && CI->hasName()) { 651 InstName = CI->getName(); 652 CI->setName(InstName + ".old"); 653 } 654 auto NewCI = addCallInst(M, NewName, CI->getType(), Args, Attrs, CI, Mangle, 655 InstName, TakeFuncName); 656 DEBUG(dbgs() << " => " << *NewCI << '\n'); 657 CI->replaceAllUsesWith(NewCI); 658 CI->dropAllReferences(); 659 CI->removeFromParent(); 660 return NewCI; 661 } 662 663 Instruction * 664 mutateCallInst(Module *M, CallInst *CI, 665 std::function<std::string (CallInst *, std::vector<Value *> &, 666 Type *&RetTy)>ArgMutate, 667 std::function<Instruction *(CallInst *)> RetMutate, 668 BuiltinFuncMangleInfo *Mangle, AttributeSet *Attrs, bool TakeFuncName) { 669 DEBUG(dbgs() << "[mutateCallInst] " << *CI); 670 671 auto Args = getArguments(CI); 672 Type *RetTy = CI->getType(); 673 auto NewName = ArgMutate(CI, Args, RetTy); 674 std::string InstName; 675 if (CI->hasName()) { 676 InstName = CI->getName(); 677 CI->setName(InstName + ".old"); 678 } 679 auto NewCI = addCallInst(M, NewName, RetTy, Args, Attrs, 680 CI, Mangle, InstName + ".tmp", TakeFuncName); 681 auto NewI = RetMutate(NewCI); 682 NewI->takeName(CI); 683 DEBUG(dbgs() << " => " << *NewI << '\n'); 684 CI->replaceAllUsesWith(NewI); 685 CI->dropAllReferences(); 686 CI->removeFromParent(); 687 return NewI; 688 } 689 690 void 691 mutateFunction(Function *F, 692 std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate, 693 BuiltinFuncMangleInfo *Mangle, AttributeSet *Attrs, 694 bool TakeFuncName) { 695 auto M = F->getParent(); 696 for (auto I = F->user_begin(), E = F->user_end(); I != E;) { 697 if (auto CI = dyn_cast<CallInst>(*I++)) 698 mutateCallInst(M, CI, ArgMutate, Mangle, Attrs, TakeFuncName); 699 } 700 if (F->use_empty()) 701 F->eraseFromParent(); 702 } 703 704 CallInst * 705 mutateCallInstSPIRV(Module *M, CallInst *CI, 706 std::function<std::string (CallInst *, std::vector<Value *> &)>ArgMutate, 707 AttributeSet *Attrs) { 708 BuiltinFuncMangleInfo BtnInfo; 709 return mutateCallInst(M, CI, ArgMutate, &BtnInfo, Attrs); 710 } 711 712 Instruction * 713 mutateCallInstSPIRV(Module *M, CallInst *CI, 714 std::function<std::string (CallInst *, std::vector<Value *> &, 715 Type *&RetTy)> ArgMutate, 716 std::function<Instruction *(CallInst *)> RetMutate, 717 AttributeSet *Attrs) { 718 BuiltinFuncMangleInfo BtnInfo; 719 return mutateCallInst(M, CI, ArgMutate, RetMutate, &BtnInfo, Attrs); 720 } 721 722 CallInst * 723 addCallInst(Module *M, StringRef FuncName, Type *RetTy, ArrayRef<Value *> Args, 724 AttributeSet *Attrs, Instruction *Pos, BuiltinFuncMangleInfo *Mangle, 725 StringRef InstName, bool TakeFuncName) { 726 727 auto F = getOrCreateFunction(M, RetTy, getTypes(Args), 728 FuncName, Mangle, Attrs, TakeFuncName); 729 // Cannot assign a name to void typed values 730 auto CI = CallInst::Create(F, Args, RetTy->isVoidTy() ? "" : InstName, Pos); 731 CI->setCallingConv(F->getCallingConv()); 732 return CI; 733 } 734 735 CallInst * 736 addCallInstSPIRV(Module *M, StringRef FuncName, Type *RetTy, ArrayRef<Value *> Args, 737 AttributeSet *Attrs, Instruction *Pos, StringRef InstName) { 738 BuiltinFuncMangleInfo BtnInfo; 739 return addCallInst(M, FuncName, RetTy, Args, Attrs, Pos, &BtnInfo, 740 InstName); 741 } 742 743 bool 744 isValidVectorSize(unsigned I) { 745 return I == 2 || 746 I == 3 || 747 I == 4 || 748 I == 8 || 749 I == 16; 750 } 751 752 Value * 753 addVector(Instruction *InsPos, ValueVecRange Range) { 754 size_t VecSize = Range.second - Range.first; 755 if (VecSize == 1) 756 return *Range.first; 757 assert(isValidVectorSize(VecSize) && "Invalid vector size"); 758 IRBuilder<> Builder(InsPos); 759 auto Vec = Builder.CreateVectorSplat(VecSize, *Range.first); 760 unsigned Index = 1; 761 for (++Range.first; Range.first != Range.second; ++Range.first, ++Index) 762 Vec = Builder.CreateInsertElement(Vec, *Range.first, 763 ConstantInt::get(Type::getInt32Ty(InsPos->getContext()), Index, false)); 764 return Vec; 765 } 766 767 void 768 makeVector(Instruction *InsPos, std::vector<Value *> &Ops, 769 ValueVecRange Range) { 770 auto Vec = addVector(InsPos, Range); 771 Ops.erase(Range.first, Range.second); 772 Ops.push_back(Vec); 773 } 774 775 void 776 expandVector(Instruction *InsPos, std::vector<Value *> &Ops, 777 size_t VecPos) { 778 auto Vec = Ops[VecPos]; 779 auto VT = Vec->getType(); 780 if (!VT->isVectorTy()) 781 return; 782 size_t N = VT->getVectorNumElements(); 783 IRBuilder<> Builder(InsPos); 784 for (size_t I = 0; I != N; ++I) 785 Ops.insert(Ops.begin() + VecPos + I, Builder.CreateExtractElement(Vec, 786 ConstantInt::get(Type::getInt32Ty(InsPos->getContext()), I, false))); 787 Ops.erase(Ops.begin() + VecPos + N); 788 } 789 790 Constant * 791 castToInt8Ptr(Constant *V, unsigned Addr = 0) { 792 return ConstantExpr::getBitCast(V, Type::getInt8PtrTy(V->getContext(), Addr)); 793 } 794 795 PointerType * 796 getInt8PtrTy(PointerType *T) { 797 return Type::getInt8PtrTy(T->getContext(), T->getAddressSpace()); 798 } 799 800 Value * 801 castToInt8Ptr(Value *V, Instruction *Pos) { 802 return CastInst::CreatePointerCast(V, getInt8PtrTy( 803 cast<PointerType>(V->getType())), "", Pos); 804 } 805 806 CallInst * 807 addBlockBind(Module *M, Function *InvokeFunc, Value *BlkCtx, Value *CtxLen, 808 Value *CtxAlign, Instruction *InsPos, StringRef InstName) { 809 auto BlkTy = getOrCreateOpaquePtrType(M, SPIR_TYPE_NAME_BLOCK_T, 810 SPIRAS_Private); 811 auto &Ctx = M->getContext(); 812 Value *BlkArgs[] = { 813 castToInt8Ptr(InvokeFunc), 814 CtxLen ? CtxLen : UndefValue::get(Type::getInt32Ty(Ctx)), 815 CtxAlign ? CtxAlign : UndefValue::get(Type::getInt32Ty(Ctx)), 816 BlkCtx ? BlkCtx : UndefValue::get(Type::getInt8PtrTy(Ctx)) 817 }; 818 return addCallInst(M, SPIR_INTRINSIC_BLOCK_BIND, BlkTy, BlkArgs, nullptr, 819 InsPos, nullptr, InstName); 820 } 821 822 IntegerType* getSizetType(Module *M) { 823 return IntegerType::getIntNTy(M->getContext(), 824 M->getDataLayout().getPointerSizeInBits(0)); 825 } 826 827 Type * 828 getVoidFuncType(Module *M) { 829 return FunctionType::get(Type::getVoidTy(M->getContext()), false); 830 } 831 832 Type * 833 getVoidFuncPtrType(Module *M, unsigned AddrSpace) { 834 return PointerType::get(getVoidFuncType(M), AddrSpace); 835 } 836 837 ConstantInt * 838 getInt64(Module *M, int64_t value) { 839 return ConstantInt::get(Type::getInt64Ty(M->getContext()), value, true); 840 } 841 842 Constant *getFloat32(Module *M, float value) { 843 return ConstantFP::get(Type::getFloatTy(M->getContext()), value); 844 } 845 846 ConstantInt * 847 getInt32(Module *M, int value) { 848 return ConstantInt::get(Type::getInt32Ty(M->getContext()), value, true); 849 } 850 851 ConstantInt * 852 getUInt32(Module *M, unsigned value) { 853 return ConstantInt::get(Type::getInt32Ty(M->getContext()), value, false); 854 } 855 856 ConstantInt * 857 getUInt16(Module *M, unsigned short value) { 858 return ConstantInt::get(Type::getInt16Ty(M->getContext()), value, false); 859 } 860 861 std::vector<Value *> getInt32(Module *M, const std::vector<int> &value) { 862 std::vector<Value *> V; 863 for (auto &I:value) 864 V.push_back(getInt32(M, I)); 865 return V; 866 } 867 868 ConstantInt * 869 getSizet(Module *M, uint64_t value) { 870 return ConstantInt::get(getSizetType(M), value, false); 871 } 872 873 /////////////////////////////////////////////////////////////////////////////// 874 // 875 // Functions for getting metadata 876 // 877 /////////////////////////////////////////////////////////////////////////////// 878 int 879 getMDOperandAsInt(MDNode* N, unsigned I) { 880 return mdconst::dyn_extract<ConstantInt>(N->getOperand(I))->getZExtValue(); 881 } 882 883 std::string 884 getMDOperandAsString(MDNode* N, unsigned I) { 885 if (!N) 886 return ""; 887 888 Metadata* Op = N->getOperand(I); 889 if (!Op) 890 return ""; 891 892 if (MDString* Str = dyn_cast<MDString>(Op)) { 893 return Str->getString().str(); 894 } 895 return ""; 896 } 897 898 Type* 899 getMDOperandAsType(MDNode* N, unsigned I) { 900 return cast<ValueAsMetadata>(N->getOperand(I))->getType(); 901 } 902 903 std::set<std::string> 904 getNamedMDAsStringSet(Module *M, const std::string &MDName) { 905 NamedMDNode *NamedMD = M->getNamedMetadata(MDName); 906 std::set<std::string> StrSet; 907 if (!NamedMD) 908 return StrSet; 909 910 assert(NamedMD->getNumOperands() > 0 && "Invalid SPIR"); 911 912 for (unsigned I = 0, E = NamedMD->getNumOperands(); I != E; ++I) { 913 MDNode *MD = NamedMD->getOperand(I); 914 if (!MD || MD->getNumOperands() == 0) 915 continue; 916 for (unsigned J = 0, N = MD->getNumOperands(); J != N; ++J) 917 StrSet.insert(getMDOperandAsString(MD, J)); 918 } 919 920 return StrSet; 921 } 922 923 std::tuple<unsigned, unsigned, std::string> 924 getSPIRVSource(Module *M) { 925 std::tuple<unsigned, unsigned, std::string> Tup; 926 if (auto N = SPIRVMDWalker(*M).getNamedMD(kSPIRVMD::Source).nextOp()) 927 N.get(std::get<0>(Tup)) 928 .get(std::get<1>(Tup)) 929 .setQuiet(true) 930 .get(std::get<2>(Tup)); 931 return Tup; 932 } 933 934 ConstantInt *mapUInt(Module *M, ConstantInt *I, 935 std::function<unsigned(unsigned)> F) { 936 return ConstantInt::get(I->getType(), F(I->getZExtValue()), false); 937 } 938 939 ConstantInt *mapSInt(Module *M, ConstantInt *I, 940 std::function<int(int)> F) { 941 return ConstantInt::get(I->getType(), F(I->getSExtValue()), true); 942 } 943 944 bool 945 isDecoratedSPIRVFunc(const Function *F, std::string *UndecoratedName) { 946 if (!F->hasName() || !F->getName().startswith(kSPIRVName::Prefix)) 947 return false; 948 if (UndecoratedName) 949 *UndecoratedName = undecorateSPIRVFunction(F->getName()); 950 return true; 951 } 952 953 /// Get TypePrimitiveEnum for special OpenCL type except opencl.block. 954 SPIR::TypePrimitiveEnum 955 getOCLTypePrimitiveEnum(StringRef TyName) { 956 return StringSwitch<SPIR::TypePrimitiveEnum>(TyName) 957 .Case("opencl.image1d_t", SPIR::PRIMITIVE_IMAGE_1D_T) 958 .Case("opencl.image1d_array_t", SPIR::PRIMITIVE_IMAGE_1D_ARRAY_T) 959 .Case("opencl.image1d_buffer_t", SPIR::PRIMITIVE_IMAGE_1D_BUFFER_T) 960 .Case("opencl.image2d_t", SPIR::PRIMITIVE_IMAGE_2D_T) 961 .Case("opencl.image2d_array_t", SPIR::PRIMITIVE_IMAGE_2D_ARRAY_T) 962 .Case("opencl.image3d_t", SPIR::PRIMITIVE_IMAGE_3D_T) 963 .Case("opencl.image2d_msaa_t", SPIR::PRIMITIVE_IMAGE_2D_MSAA_T) 964 .Case("opencl.image2d_array_msaa_t", SPIR::PRIMITIVE_IMAGE_2D_ARRAY_MSAA_T) 965 .Case("opencl.image2d_msaa_depth_t", SPIR::PRIMITIVE_IMAGE_2D_MSAA_DEPTH_T) 966 .Case("opencl.image2d_array_msaa_depth_t", SPIR::PRIMITIVE_IMAGE_2D_ARRAY_MSAA_DEPTH_T) 967 .Case("opencl.image2d_depth_t", SPIR::PRIMITIVE_IMAGE_2D_DEPTH_T) 968 .Case("opencl.image2d_array_depth_t", SPIR::PRIMITIVE_IMAGE_2D_ARRAY_DEPTH_T) 969 .Case("opencl.event_t", SPIR::PRIMITIVE_EVENT_T) 970 .Case("opencl.pipe_t", SPIR::PRIMITIVE_PIPE_T) 971 .Case("opencl.reserve_id_t", SPIR::PRIMITIVE_RESERVE_ID_T) 972 .Case("opencl.queue_t", SPIR::PRIMITIVE_QUEUE_T) 973 .Case("opencl.clk_event_t", SPIR::PRIMITIVE_CLK_EVENT_T) 974 .Case("opencl.sampler_t", SPIR::PRIMITIVE_SAMPLER_T) 975 .Case("struct.ndrange_t", SPIR::PRIMITIVE_NDRANGE_T) 976 .Default( SPIR::PRIMITIVE_NONE); 977 } 978 /// Translates LLVM type to descriptor for mangler. 979 /// \param Signed indicates integer type should be translated as signed. 980 /// \param VoidPtr indicates i8* should be translated as void*. 981 static SPIR::RefParamType 982 transTypeDesc(Type *Ty, const BuiltinArgTypeMangleInfo &Info) { 983 bool Signed = Info.IsSigned; 984 unsigned Attr = Info.Attr; 985 bool VoidPtr = Info.IsVoidPtr; 986 if (Info.IsEnum) 987 return SPIR::RefParamType(new SPIR::PrimitiveType(Info.Enum)); 988 if (Info.IsSampler) 989 return SPIR::RefParamType(new SPIR::PrimitiveType( 990 SPIR::PRIMITIVE_SAMPLER_T)); 991 if (Info.IsAtomic && !Ty->isPointerTy()) { 992 BuiltinArgTypeMangleInfo DTInfo = Info; 993 DTInfo.IsAtomic = false; 994 return SPIR::RefParamType(new SPIR::AtomicType( 995 transTypeDesc(Ty, DTInfo))); 996 } 997 if(auto *IntTy = dyn_cast<IntegerType>(Ty)) { 998 switch(IntTy->getBitWidth()) { 999 case 1: 1000 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_BOOL)); 1001 case 8: 1002 return SPIR::RefParamType(new SPIR::PrimitiveType(Signed? 1003 SPIR::PRIMITIVE_CHAR:SPIR::PRIMITIVE_UCHAR)); 1004 case 16: 1005 return SPIR::RefParamType(new SPIR::PrimitiveType(Signed? 1006 SPIR::PRIMITIVE_SHORT:SPIR::PRIMITIVE_USHORT)); 1007 case 32: 1008 return SPIR::RefParamType(new SPIR::PrimitiveType(Signed? 1009 SPIR::PRIMITIVE_INT:SPIR::PRIMITIVE_UINT)); 1010 case 64: 1011 return SPIR::RefParamType(new SPIR::PrimitiveType(Signed? 1012 SPIR::PRIMITIVE_LONG:SPIR::PRIMITIVE_ULONG)); 1013 default: 1014 llvm_unreachable("invliad int size"); 1015 } 1016 } 1017 if (Ty->isVoidTy()) 1018 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_VOID)); 1019 if (Ty->isHalfTy()) 1020 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_HALF)); 1021 if (Ty->isFloatTy()) 1022 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_FLOAT)); 1023 if (Ty->isDoubleTy()) 1024 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_DOUBLE)); 1025 if (Ty->isVectorTy()) { 1026 return SPIR::RefParamType(new SPIR::VectorType( 1027 transTypeDesc(Ty->getVectorElementType(), Info), 1028 Ty->getVectorNumElements())); 1029 } 1030 if (Ty->isArrayTy()) { 1031 return transTypeDesc(PointerType::get(Ty->getArrayElementType(), 0), Info); 1032 } 1033 if (Ty->isStructTy()) { 1034 auto Name = Ty->getStructName(); 1035 std::string Tmp; 1036 1037 if (Name.startswith(kLLVMTypeName::StructPrefix)) 1038 Name = Name.drop_front(strlen(kLLVMTypeName::StructPrefix)); 1039 if (Name.startswith(kSPIRVTypeName::PrefixAndDelim)) { 1040 Name = Name.substr(sizeof(kSPIRVTypeName::PrefixAndDelim) - 1); 1041 Tmp = Name.str(); 1042 auto pos = Tmp.find(kSPIRVTypeName::Delimiter); //first dot 1043 while (pos != std::string::npos) { 1044 Tmp[pos] = '_'; 1045 pos = Tmp.find(kSPIRVTypeName::Delimiter, pos); 1046 } 1047 Name = Tmp = kSPIRVName::Prefix + Tmp; 1048 } 1049 // ToDo: Create a better unique name for struct without name 1050 if (Name.empty()) { 1051 std::ostringstream OS; 1052 OS << reinterpret_cast<size_t>(Ty); 1053 Name = Tmp = std::string("struct_") + OS.str(); 1054 } 1055 return SPIR::RefParamType(new SPIR::UserDefinedType(Name)); 1056 } 1057 1058 if (Ty->isPointerTy()) { 1059 auto ET = Ty->getPointerElementType(); 1060 SPIR::ParamType *EPT = nullptr; 1061 if (auto FT = dyn_cast<FunctionType>(ET)) { 1062 (void) FT; 1063 assert(isVoidFuncTy(FT) && "Not supported"); 1064 EPT = new SPIR::BlockType; 1065 } else if (auto StructTy = dyn_cast<StructType>(ET)) { 1066 DEBUG(dbgs() << "ptr to struct: " << *Ty << '\n'); 1067 auto TyName = StructTy->getStructName(); 1068 if (TyName.startswith(kSPR2TypeName::ImagePrefix) || 1069 TyName.startswith(kSPR2TypeName::Pipe)) { 1070 auto DelimPos = TyName.find_first_of(kSPR2TypeName::Delimiter, 1071 strlen(kSPR2TypeName::OCLPrefix)); 1072 if (DelimPos != StringRef::npos) 1073 TyName = TyName.substr(0, DelimPos); 1074 } 1075 DEBUG(dbgs() << " type name: " << TyName << '\n'); 1076 1077 auto Prim = getOCLTypePrimitiveEnum(TyName); 1078 if (StructTy->isOpaque()) { 1079 if (TyName == "opencl.block") { 1080 auto BlockTy = new SPIR::BlockType; 1081 // Handle block with local memory arguments according to OpenCL 2.0 spec. 1082 if(Info.IsLocalArgBlock) { 1083 SPIR::RefParamType VoidTyRef(new SPIR::PrimitiveType(SPIR::PRIMITIVE_VOID)); 1084 auto VoidPtrTy = new SPIR::PointerType(VoidTyRef); 1085 VoidPtrTy->setAddressSpace(SPIR::ATTR_LOCAL); 1086 // "__local void *" 1087 BlockTy->setParam(0, SPIR::RefParamType(VoidPtrTy)); 1088 // "..." 1089 BlockTy->setParam(1, SPIR::RefParamType( 1090 new SPIR::PrimitiveType(SPIR::PRIMITIVE_VAR_ARG))); 1091 } 1092 EPT = BlockTy; 1093 } else if (Prim != SPIR::PRIMITIVE_NONE) { 1094 if (Prim == SPIR::PRIMITIVE_PIPE_T) { 1095 SPIR::RefParamType OpaqueTyRef(new SPIR::PrimitiveType(Prim)); 1096 auto OpaquePtrTy = new SPIR::PointerType(OpaqueTyRef); 1097 OpaquePtrTy->setAddressSpace(getOCLOpaqueTypeAddrSpace(Prim)); 1098 EPT = OpaquePtrTy; 1099 } 1100 else { 1101 EPT = new SPIR::PrimitiveType(Prim); 1102 } 1103 } 1104 } else if (Prim == SPIR::PRIMITIVE_NDRANGE_T) 1105 // ndrange_t is not opaque type 1106 EPT = new SPIR::PrimitiveType(SPIR::PRIMITIVE_NDRANGE_T); 1107 } 1108 if (EPT) 1109 return SPIR::RefParamType(EPT); 1110 1111 if (VoidPtr && ET->isIntegerTy(8)) 1112 ET = Type::getVoidTy(ET->getContext()); 1113 auto PT = new SPIR::PointerType(transTypeDesc(ET, Info)); 1114 PT->setAddressSpace(static_cast<SPIR::TypeAttributeEnum>( 1115 Ty->getPointerAddressSpace() + (unsigned)SPIR::ATTR_ADDR_SPACE_FIRST)); 1116 for (unsigned I = SPIR::ATTR_QUALIFIER_FIRST, 1117 E = SPIR::ATTR_QUALIFIER_LAST; I <= E; ++I) 1118 PT->setQualifier(static_cast<SPIR::TypeAttributeEnum>(I), I & Attr); 1119 return SPIR::RefParamType(PT); 1120 } 1121 DEBUG(dbgs() << "[transTypeDesc] " << *Ty << '\n'); 1122 assert (0 && "not implemented"); 1123 return SPIR::RefParamType(new SPIR::PrimitiveType(SPIR::PRIMITIVE_INT)); 1124 } 1125 1126 Value * 1127 getScalarOrArray(Value *V, unsigned Size, Instruction *Pos) { 1128 if (!V->getType()->isPointerTy()) 1129 return V; 1130 assert((isa<ConstantExpr>(V) || isa<GetElementPtrInst>(V)) && 1131 "unexpected value type"); 1132 auto GEP = cast<User>(V); 1133 assert(GEP->getNumOperands() == 3 && "must be a GEP from an array"); 1134 auto P = GEP->getOperand(0); 1135 assert(P->getType()->getPointerElementType()->getArrayNumElements() == Size); 1136 auto Index0 = GEP->getOperand(1); 1137 (void) Index0; 1138 assert(dyn_cast<ConstantInt>(Index0)->getZExtValue() == 0); 1139 auto Index1 = GEP->getOperand(2); 1140 (void) Index1; 1141 assert(dyn_cast<ConstantInt>(Index1)->getZExtValue() == 0); 1142 return new LoadInst(P, "", Pos); 1143 } 1144 1145 Constant * 1146 getScalarOrVectorConstantInt(Type *T, uint64_t V, bool isSigned) { 1147 if (auto IT = dyn_cast<IntegerType>(T)) 1148 return ConstantInt::get(IT, V); 1149 if (auto VT = dyn_cast<VectorType>(T)) { 1150 std::vector<Constant *> EV(VT->getVectorNumElements(), 1151 getScalarOrVectorConstantInt(VT->getVectorElementType(), V, isSigned)); 1152 return ConstantVector::get(EV); 1153 } 1154 llvm_unreachable("Invalid type"); 1155 return nullptr; 1156 } 1157 1158 Value * 1159 getScalarOrArrayConstantInt(Instruction *Pos, Type *T, unsigned Len, uint64_t V, 1160 bool isSigned) { 1161 if (auto IT = dyn_cast<IntegerType>(T)) { 1162 assert(Len == 1 && "Invalid length"); 1163 return ConstantInt::get(IT, V, isSigned); 1164 } 1165 if (auto PT = dyn_cast<PointerType>(T)) { 1166 auto ET = PT->getPointerElementType(); 1167 auto AT = ArrayType::get(ET, Len); 1168 std::vector<Constant *> EV(Len, ConstantInt::get(ET, V, isSigned)); 1169 auto CA = ConstantArray::get(AT, EV); 1170 auto Alloca = new AllocaInst(AT, "", Pos); 1171 new StoreInst(CA, Alloca, Pos); 1172 auto Zero = ConstantInt::getNullValue(Type::getInt32Ty(T->getContext())); 1173 Value *Index[] = {Zero, Zero}; 1174 auto Ret = GetElementPtrInst::CreateInBounds(Alloca, Index, "", Pos); 1175 DEBUG(dbgs() << "[getScalarOrArrayConstantInt] Alloca: " << 1176 *Alloca << ", Return: " << *Ret << '\n'); 1177 return Ret; 1178 } 1179 if (auto AT = dyn_cast<ArrayType>(T)) { 1180 auto ET = AT->getArrayElementType(); 1181 assert(AT->getArrayNumElements() == Len); 1182 std::vector<Constant *> EV(Len, ConstantInt::get(ET, V, isSigned)); 1183 auto Ret = ConstantArray::get(AT, EV); 1184 DEBUG(dbgs() << "[getScalarOrArrayConstantInt] Array type: " << 1185 *AT << ", Return: " << *Ret << '\n'); 1186 return Ret; 1187 } 1188 llvm_unreachable("Invalid type"); 1189 return nullptr; 1190 } 1191 1192 void 1193 dumpUsers(Value* V, StringRef Prompt) { 1194 if (!V) return; 1195 DEBUG(dbgs() << Prompt << " Users of " << *V << " :\n"); 1196 for (auto UI = V->user_begin(), UE = V->user_end(); UI != UE; ++UI) 1197 DEBUG(dbgs() << " " << **UI << '\n'); 1198 } 1199 1200 std::string 1201 getSPIRVTypeName(StringRef BaseName, StringRef Postfixes) { 1202 assert(!BaseName.empty() && "Invalid SPIR-V type name"); 1203 auto TN = std::string(kSPIRVTypeName::PrefixAndDelim) 1204 + BaseName.str(); 1205 if (Postfixes.empty()) 1206 return TN; 1207 return TN + kSPIRVTypeName::Delimiter + Postfixes.str(); 1208 } 1209 1210 bool 1211 isSPIRVConstantName(StringRef TyName) { 1212 if (TyName == getSPIRVTypeName(kSPIRVTypeName::ConstantSampler) || 1213 TyName == getSPIRVTypeName(kSPIRVTypeName::ConstantPipeStorage)) 1214 return true; 1215 1216 return false; 1217 } 1218 1219 Type * 1220 getSPIRVTypeByChangeBaseTypeName(Module *M, Type *T, StringRef OldName, 1221 StringRef NewName) { 1222 StringRef Postfixes; 1223 if (isSPIRVType(T, OldName, &Postfixes)) 1224 return getOrCreateOpaquePtrType(M, getSPIRVTypeName(NewName, Postfixes)); 1225 DEBUG(dbgs() << " Invalid SPIR-V type " << *T << '\n'); 1226 llvm_unreachable("Invalid SPIRV-V type"); 1227 return nullptr; 1228 } 1229 1230 std::string 1231 getSPIRVImageTypePostfixes(StringRef SampledType, 1232 SPIRVTypeImageDescriptor Desc, 1233 SPIRVAccessQualifierKind Acc) { 1234 std::string S; 1235 raw_string_ostream OS(S); 1236 OS << SampledType << kSPIRVTypeName::PostfixDelim 1237 << Desc.Dim << kSPIRVTypeName::PostfixDelim 1238 << Desc.Depth << kSPIRVTypeName::PostfixDelim 1239 << Desc.Arrayed << kSPIRVTypeName::PostfixDelim 1240 << Desc.MS << kSPIRVTypeName::PostfixDelim 1241 << Desc.Sampled << kSPIRVTypeName::PostfixDelim 1242 << Desc.Format << kSPIRVTypeName::PostfixDelim 1243 << Acc; 1244 return OS.str(); 1245 } 1246 1247 std::string 1248 getSPIRVImageSampledTypeName(SPIRVType *Ty) { 1249 switch(Ty->getOpCode()) { 1250 case OpTypeVoid: 1251 return kSPIRVImageSampledTypeName::Void; 1252 case OpTypeInt: 1253 if (Ty->getIntegerBitWidth() == 32) { 1254 if (static_cast<SPIRVTypeInt *>(Ty)->isSigned()) 1255 return kSPIRVImageSampledTypeName::Int; 1256 else 1257 return kSPIRVImageSampledTypeName::UInt; } 1258 break; 1259 case OpTypeFloat: 1260 switch(Ty->getFloatBitWidth()) { 1261 case 16: 1262 return kSPIRVImageSampledTypeName::Half; 1263 case 32: 1264 return kSPIRVImageSampledTypeName::Float; 1265 default: 1266 break; 1267 } 1268 break; 1269 default: 1270 break; 1271 } 1272 llvm_unreachable("Invalid sampled type for image"); 1273 } 1274 1275 //ToDo: Find a way to represent uint sampled type in LLVM, maybe an 1276 // opaque type. 1277 Type* 1278 getLLVMTypeForSPIRVImageSampledTypePostfix(StringRef Postfix, 1279 LLVMContext &Ctx) { 1280 if (Postfix == kSPIRVImageSampledTypeName::Void) 1281 return Type::getVoidTy(Ctx); 1282 if (Postfix == kSPIRVImageSampledTypeName::Float) 1283 return Type::getFloatTy(Ctx); 1284 if (Postfix == kSPIRVImageSampledTypeName::Half) 1285 return Type::getHalfTy(Ctx); 1286 if (Postfix == kSPIRVImageSampledTypeName::Int || 1287 Postfix == kSPIRVImageSampledTypeName::UInt) 1288 return Type::getInt32Ty(Ctx); 1289 llvm_unreachable("Invalid sampled type postfix"); 1290 } 1291 1292 std::string 1293 mapOCLTypeNameToSPIRV(StringRef Name, StringRef Acc) { 1294 std::string BaseTy; 1295 std::string Postfixes; 1296 raw_string_ostream OS(Postfixes); 1297 if (!Acc.empty()) 1298 OS << kSPIRVTypeName::PostfixDelim; 1299 if (Name.startswith(kSPR2TypeName::Pipe)) { 1300 BaseTy = kSPIRVTypeName::Pipe; 1301 OS << SPIRSPIRVAccessQualifierMap::map(Acc); 1302 } else if (Name.startswith(kSPR2TypeName::ImagePrefix)) { 1303 SmallVector<StringRef, 4> SubStrs; 1304 const char Delims[] = {kSPR2TypeName::Delimiter, 0}; 1305 Name.split(SubStrs, Delims); 1306 std::string ImageTyName = SubStrs[1].str(); 1307 if (hasAccessQualifiedName(Name)) 1308 ImageTyName.erase(ImageTyName.size() - 5, 3); 1309 auto Desc = map<SPIRVTypeImageDescriptor>(ImageTyName); 1310 DEBUG(dbgs() << "[trans image type] " << SubStrs[1] << " => " << 1311 "(" << (unsigned)Desc.Dim << ", " << 1312 Desc.Depth << ", " << 1313 Desc.Arrayed << ", " << 1314 Desc.MS << ", " << 1315 Desc.Sampled << ", " << 1316 Desc.Format << ")\n"); 1317 1318 BaseTy = kSPIRVTypeName::Image; 1319 OS << getSPIRVImageTypePostfixes(kSPIRVImageSampledTypeName::Void, 1320 Desc, 1321 SPIRSPIRVAccessQualifierMap::map(Acc)); 1322 } else { 1323 DEBUG(dbgs() << "Mapping of " << Name << " is not implemented\n"); 1324 llvm_unreachable("Not implemented"); 1325 } 1326 return getSPIRVTypeName(BaseTy, OS.str()); 1327 } 1328 1329 bool 1330 eraseIfNoUse(Function *F) { 1331 bool changed = false; 1332 if (!F) 1333 return changed; 1334 if (!GlobalValue::isInternalLinkage(F->getLinkage()) && 1335 !F->isDeclaration()) 1336 return changed; 1337 1338 dumpUsers(F, "[eraseIfNoUse] "); 1339 for (auto UI = F->user_begin(), UE = F->user_end(); UI != UE;) { 1340 auto U = *UI++; 1341 if (auto CE = dyn_cast<ConstantExpr>(U)){ 1342 if (CE->use_empty()) { 1343 CE->dropAllReferences(); 1344 changed = true; 1345 } 1346 } 1347 } 1348 if (F->use_empty()) { 1349 DEBUG(dbgs() << "Erase "; 1350 F->printAsOperand(dbgs()); 1351 dbgs() << '\n'); 1352 F->eraseFromParent(); 1353 changed = true; 1354 } 1355 return changed; 1356 } 1357 1358 void 1359 eraseIfNoUse(Value *V) { 1360 if (!V->use_empty()) 1361 return; 1362 if (Constant *C = dyn_cast<Constant>(V)) { 1363 C->destroyConstant(); 1364 return; 1365 } 1366 if (Instruction *I = dyn_cast<Instruction>(V)) { 1367 if (!I->mayHaveSideEffects()) 1368 I->eraseFromParent(); 1369 } 1370 eraseIfNoUse(dyn_cast<Function>(V)); 1371 } 1372 1373 bool 1374 eraseUselessFunctions(Module *M) { 1375 bool changed = false; 1376 for (auto I = M->begin(), E = M->end(); I != E;) 1377 changed |= eraseIfNoUse(static_cast<Function*>(I++)); 1378 return changed; 1379 } 1380 1381 std::string 1382 mangleBuiltin(const std::string &UniqName, 1383 ArrayRef<Type*> ArgTypes, BuiltinFuncMangleInfo* BtnInfo) { 1384 if (!BtnInfo) 1385 return UniqName; 1386 BtnInfo->init(UniqName); 1387 std::string MangledName; 1388 DEBUG(dbgs() << "[mangle] " << UniqName << " => "); 1389 SPIR::NameMangler Mangler(SPIR::SPIR20); 1390 SPIR::FunctionDescriptor FD; 1391 FD.name = BtnInfo->getUnmangledName(); 1392 bool BIVarArgNegative = BtnInfo->getVarArg() < 0; 1393 1394 if (ArgTypes.empty()) { 1395 // Function signature cannot be ()(void, ...) so if there is an ellipsis 1396 // it must be ()(...) 1397 if(BIVarArgNegative) { 1398 FD.parameters.emplace_back(SPIR::RefParamType(new SPIR::PrimitiveType( 1399 SPIR::PRIMITIVE_VOID))); 1400 } 1401 } else { 1402 for (unsigned I = 0, 1403 E = BIVarArgNegative ? ArgTypes.size() : (unsigned)BtnInfo->getVarArg(); 1404 I != E; ++I) { 1405 auto T = ArgTypes[I]; 1406 FD.parameters.emplace_back(transTypeDesc(T, BtnInfo->getTypeMangleInfo(I))); 1407 } 1408 } 1409 // Ellipsis must be the last argument of any function 1410 if(!BIVarArgNegative) { 1411 assert((unsigned)BtnInfo->getVarArg() <= ArgTypes.size() 1412 && "invalid index of an ellipsis"); 1413 FD.parameters.emplace_back(SPIR::RefParamType(new SPIR::PrimitiveType( 1414 SPIR::PRIMITIVE_VAR_ARG))); 1415 } 1416 Mangler.mangle(FD, MangledName); 1417 DEBUG(dbgs() << MangledName << '\n'); 1418 return MangledName; 1419 } 1420 1421 /// Check if access qualifier is encoded in the type name. 1422 bool hasAccessQualifiedName(StringRef TyName) { 1423 if (TyName.endswith("_ro_t") || TyName.endswith("_wo_t") || 1424 TyName.endswith("_rw_t")) 1425 return true; 1426 return false; 1427 } 1428 1429 /// Get access qualifier from the type name. 1430 StringRef getAccessQualifier(StringRef TyName) { 1431 assert(hasAccessQualifiedName(TyName) && 1432 "Type is not qualified with access."); 1433 auto Acc = TyName.substr(TyName.size() - 4, 2); 1434 return llvm::StringSwitch<StringRef>(Acc) 1435 .Case("ro", "read_only") 1436 .Case("wo", "write_only") 1437 .Case("rw", "read_write") 1438 .Default(""); 1439 } 1440 1441 /// Translates OpenCL image type names to SPIR-V. 1442 Type *getSPIRVImageTypeFromOCL(Module *M, Type *ImageTy) { 1443 assert(isOCLImageType(ImageTy) && "Unsupported type"); 1444 auto ImageTypeName = ImageTy->getPointerElementType()->getStructName(); 1445 std::string Acc = kAccessQualName::ReadOnly; 1446 if (hasAccessQualifiedName(ImageTypeName)) 1447 Acc = getAccessQualifier(ImageTypeName); 1448 return getOrCreateOpaquePtrType(M, mapOCLTypeNameToSPIRV(ImageTypeName, Acc)); 1449 } 1450 } 1451