LLVM 22.0.0git
SPIRVPrepareFunctions.cpp
Go to the documentation of this file.
1//===-- SPIRVPrepareFunctions.cpp - modify function signatures --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass modifies function signatures containing aggregate arguments
10// and/or return value before IRTranslator. Information about the original
11// signatures is stored in metadata. It is used during call lowering to
12// restore correct SPIR-V types of function arguments and return values.
13// This pass also substitutes some llvm intrinsic calls with calls to newly
14// generated functions (as the Khronos LLVM/SPIR-V Translator does).
15//
16// NOTE: this pass is a module-level one due to the necessity to modify
17// GVs/functions.
18//
19//===----------------------------------------------------------------------===//
20
21#include "SPIRV.h"
22#include "SPIRVSubtarget.h"
23#include "SPIRVTargetMachine.h"
24#include "SPIRVUtils.h"
28#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/Intrinsics.h"
31#include "llvm/IR/IntrinsicsSPIRV.h"
34#include <regex>
35
36using namespace llvm;
37
38namespace {
39
40class SPIRVPrepareFunctions : public ModulePass {
42 bool substituteIntrinsicCalls(Function *F);
43 Function *removeAggregateTypesFromSignature(Function *F);
44
45public:
46 static char ID;
47 SPIRVPrepareFunctions(const SPIRVTargetMachine &TM)
48 : ModulePass(ID), TM(TM) {}
49
50 bool runOnModule(Module &M) override;
51
52 StringRef getPassName() const override { return "SPIRV prepare functions"; }
53
54 void getAnalysisUsage(AnalysisUsage &AU) const override {
56 }
57};
58
59} // namespace
60
61char SPIRVPrepareFunctions::ID = 0;
62
63INITIALIZE_PASS(SPIRVPrepareFunctions, "prepare-functions",
64 "SPIRV prepare functions", false, false)
65
66static std::string lowerLLVMIntrinsicName(IntrinsicInst *II) {
67 Function *IntrinsicFunc = II->getCalledFunction();
68 assert(IntrinsicFunc && "Missing function");
69 std::string FuncName = IntrinsicFunc->getName().str();
70 llvm::replace(FuncName, '.', '_');
71 FuncName = "spirv." + FuncName;
72 return FuncName;
73}
74
76 ArrayRef<Type *> ArgTypes,
78 FunctionType *FT = FunctionType::get(RetTy, ArgTypes, false);
79 Function *F = M->getFunction(Name);
80 if (F && F->getFunctionType() == FT)
81 return F;
83 if (F)
84 NewF->setDSOLocal(F->isDSOLocal());
86 return NewF;
87}
88
89static bool lowerIntrinsicToFunction(IntrinsicInst *Intrinsic) {
90 // For @llvm.memset.* intrinsic cases with constant value and length arguments
91 // are emulated via "storing" a constant array to the destination. For other
92 // cases we wrap the intrinsic in @spirv.llvm_memset_* function and expand the
93 // intrinsic to a loop via expandMemSetAsLoop().
94 if (auto *MSI = dyn_cast<MemSetInst>(Intrinsic))
95 if (isa<Constant>(MSI->getValue()) && isa<ConstantInt>(MSI->getLength()))
96 return false; // It is handled later using OpCopyMemorySized.
97
98 Module *M = Intrinsic->getModule();
99 std::string FuncName = lowerLLVMIntrinsicName(Intrinsic);
100 if (Intrinsic->isVolatile())
101 FuncName += ".volatile";
102 // Redirect @llvm.intrinsic.* call to @spirv.llvm_intrinsic_*
103 Function *F = M->getFunction(FuncName);
104 if (F) {
105 Intrinsic->setCalledFunction(F);
106 return true;
107 }
108 // TODO copy arguments attributes: nocapture writeonly.
109 FunctionCallee FC =
110 M->getOrInsertFunction(FuncName, Intrinsic->getFunctionType());
111 auto IntrinsicID = Intrinsic->getIntrinsicID();
112 Intrinsic->setCalledFunction(FC);
113
114 F = dyn_cast<Function>(FC.getCallee());
115 assert(F && "Callee must be a function");
116
117 switch (IntrinsicID) {
118 case Intrinsic::memset: {
119 auto *MSI = static_cast<MemSetInst *>(Intrinsic);
120 Argument *Dest = F->getArg(0);
121 Argument *Val = F->getArg(1);
122 Argument *Len = F->getArg(2);
123 Argument *IsVolatile = F->getArg(3);
124 Dest->setName("dest");
125 Val->setName("val");
126 Len->setName("len");
127 IsVolatile->setName("isvolatile");
128 BasicBlock *EntryBB = BasicBlock::Create(M->getContext(), "entry", F);
129 IRBuilder<> IRB(EntryBB);
130 auto *MemSet = IRB.CreateMemSet(Dest, Val, Len, MSI->getDestAlign(),
131 MSI->isVolatile());
132 IRB.CreateRetVoid();
133 expandMemSetAsLoop(cast<MemSetInst>(MemSet));
134 MemSet->eraseFromParent();
135 break;
136 }
137 case Intrinsic::bswap: {
138 BasicBlock *EntryBB = BasicBlock::Create(M->getContext(), "entry", F);
139 IRBuilder<> IRB(EntryBB);
140 auto *BSwap = IRB.CreateIntrinsic(Intrinsic::bswap, Intrinsic->getType(),
141 F->getArg(0));
142 IRB.CreateRet(BSwap);
143 IntrinsicLowering IL(M->getDataLayout());
144 IL.LowerIntrinsicCall(BSwap);
145 break;
146 }
147 default:
148 break;
149 }
150 return true;
151}
152
153static std::string getAnnotation(Value *AnnoVal, Value *OptAnnoVal) {
154 if (auto *Ref = dyn_cast_or_null<GetElementPtrInst>(AnnoVal))
155 AnnoVal = Ref->getOperand(0);
156 if (auto *Ref = dyn_cast_or_null<BitCastInst>(OptAnnoVal))
157 OptAnnoVal = Ref->getOperand(0);
158
159 std::string Anno;
160 if (auto *C = dyn_cast_or_null<Constant>(AnnoVal)) {
161 StringRef Str;
162 if (getConstantStringInfo(C, Str))
163 Anno = Str;
164 }
165 // handle optional annotation parameter in a way that Khronos Translator do
166 // (collect integers wrapped in a struct)
167 if (auto *C = dyn_cast_or_null<Constant>(OptAnnoVal);
168 C && C->getNumOperands()) {
169 Value *MaybeStruct = C->getOperand(0);
170 if (auto *Struct = dyn_cast<ConstantStruct>(MaybeStruct)) {
171 for (unsigned I = 0, E = Struct->getNumOperands(); I != E; ++I) {
172 if (auto *CInt = dyn_cast<ConstantInt>(Struct->getOperand(I)))
173 Anno += (I == 0 ? ": " : ", ") +
174 std::to_string(CInt->getType()->getIntegerBitWidth() == 1
175 ? CInt->getZExtValue()
176 : CInt->getSExtValue());
177 }
178 } else if (auto *Struct = dyn_cast<ConstantAggregateZero>(MaybeStruct)) {
179 // { i32 i32 ... } zeroinitializer
180 for (unsigned I = 0, E = Struct->getType()->getStructNumElements();
181 I != E; ++I)
182 Anno += I == 0 ? ": 0" : ", 0";
183 }
184 }
185 return Anno;
186}
187
189 const std::string &Anno,
190 LLVMContext &Ctx,
191 Type *Int32Ty) {
192 // Try to parse the annotation string according to the following rules:
193 // annotation := ({kind} | {kind:value,value,...})+
194 // kind := number
195 // value := number | string
196 static const std::regex R(
197 "\\{(\\d+)(?:[:,](\\d+|\"[^\"]*\")(?:,(\\d+|\"[^\"]*\"))*)?\\}");
199 int Pos = 0;
200 for (std::sregex_iterator
201 It = std::sregex_iterator(Anno.begin(), Anno.end(), R),
202 ItEnd = std::sregex_iterator();
203 It != ItEnd; ++It) {
204 if (It->position() != Pos)
206 Pos = It->position() + It->length();
207 std::smatch Match = *It;
209 for (std::size_t i = 1; i < Match.size(); ++i) {
210 std::ssub_match SMatch = Match[i];
211 std::string Item = SMatch.str();
212 if (Item.length() == 0)
213 break;
214 if (Item[0] == '"') {
215 Item = Item.substr(1, Item.length() - 2);
216 // Acceptable format of the string snippet is:
217 static const std::regex RStr("^(\\d+)(?:,(\\d+))*$");
218 if (std::smatch MatchStr; std::regex_match(Item, MatchStr, RStr)) {
219 for (std::size_t SubIdx = 1; SubIdx < MatchStr.size(); ++SubIdx)
220 if (std::string SubStr = MatchStr[SubIdx].str(); SubStr.length())
222 ConstantInt::get(Int32Ty, std::stoi(SubStr))));
223 } else {
224 MDsItem.push_back(MDString::get(Ctx, Item));
225 }
226 } else if (int32_t Num; llvm::to_integer(StringRef(Item), Num, 10)) {
227 MDsItem.push_back(
228 ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Num)));
229 } else {
230 MDsItem.push_back(MDString::get(Ctx, Item));
231 }
232 }
233 if (MDsItem.size() == 0)
235 MDs.push_back(MDNode::get(Ctx, MDsItem));
236 }
237 return Pos == static_cast<int>(Anno.length()) ? std::move(MDs)
239}
240
242 LLVMContext &Ctx = II->getContext();
243 Type *Int32Ty = Type::getInt32Ty(Ctx);
244
245 // Retrieve an annotation string from arguments.
246 Value *PtrArg = nullptr;
247 if (auto *BI = dyn_cast<BitCastInst>(II->getArgOperand(0)))
248 PtrArg = BI->getOperand(0);
249 else
250 PtrArg = II->getOperand(0);
251 std::string Anno =
252 getAnnotation(II->getArgOperand(1),
253 4 < II->arg_size() ? II->getArgOperand(4) : nullptr);
254
255 // Parse the annotation.
256 SmallVector<Metadata *> MDs = parseAnnotation(II, Anno, Ctx, Int32Ty);
257
258 // If the annotation string is not parsed successfully we don't know the
259 // format used and output it as a general UserSemantic decoration.
260 // Otherwise MDs is a Metadata tuple (a decoration list) in the format
261 // expected by `spirv.Decorations`.
262 if (MDs.size() == 0) {
263 auto UserSemantic = ConstantAsMetadata::get(ConstantInt::get(
264 Int32Ty, static_cast<uint32_t>(SPIRV::Decoration::UserSemantic)));
265 MDs.push_back(MDNode::get(Ctx, {UserSemantic, MDString::get(Ctx, Anno)}));
266 }
267
268 // Build the internal intrinsic function.
269 IRBuilder<> IRB(II->getParent());
270 IRB.SetInsertPoint(II);
271 IRB.CreateIntrinsic(
272 Intrinsic::spv_assign_decoration, {PtrArg->getType()},
273 {PtrArg, MetadataAsValue::get(Ctx, MDNode::get(Ctx, MDs))});
274 II->replaceAllUsesWith(II->getOperand(0));
275}
276
277static void lowerFunnelShifts(IntrinsicInst *FSHIntrinsic) {
278 // Get a separate function - otherwise, we'd have to rework the CFG of the
279 // current one. Then simply replace the intrinsic uses with a call to the new
280 // function.
281 // Generate LLVM IR for i* @spirv.llvm_fsh?_i* (i* %a, i* %b, i* %c)
282 Module *M = FSHIntrinsic->getModule();
283 FunctionType *FSHFuncTy = FSHIntrinsic->getFunctionType();
284 Type *FSHRetTy = FSHFuncTy->getReturnType();
285 const std::string FuncName = lowerLLVMIntrinsicName(FSHIntrinsic);
286 Function *FSHFunc =
287 getOrCreateFunction(M, FSHRetTy, FSHFuncTy->params(), FuncName);
288
289 if (!FSHFunc->empty()) {
290 FSHIntrinsic->setCalledFunction(FSHFunc);
291 return;
292 }
293 BasicBlock *RotateBB = BasicBlock::Create(M->getContext(), "rotate", FSHFunc);
294 IRBuilder<> IRB(RotateBB);
295 Type *Ty = FSHFunc->getReturnType();
296 // Build the actual funnel shift rotate logic.
297 // In the comments, "int" is used interchangeably with "vector of int
298 // elements".
299 FixedVectorType *VectorTy = dyn_cast<FixedVectorType>(Ty);
300 Type *IntTy = VectorTy ? VectorTy->getElementType() : Ty;
301 unsigned BitWidth = IntTy->getIntegerBitWidth();
302 ConstantInt *BitWidthConstant = IRB.getInt({BitWidth, BitWidth});
303 Value *BitWidthForInsts =
304 VectorTy
305 ? IRB.CreateVectorSplat(VectorTy->getNumElements(), BitWidthConstant)
306 : BitWidthConstant;
307 Value *RotateModVal =
308 IRB.CreateURem(/*Rotate*/ FSHFunc->getArg(2), BitWidthForInsts);
309 Value *FirstShift = nullptr, *SecShift = nullptr;
310 if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
311 // Shift the less significant number right, the "rotate" number of bits
312 // will be 0-filled on the left as a result of this regular shift.
313 FirstShift = IRB.CreateLShr(FSHFunc->getArg(1), RotateModVal);
314 } else {
315 // Shift the more significant number left, the "rotate" number of bits
316 // will be 0-filled on the right as a result of this regular shift.
317 FirstShift = IRB.CreateShl(FSHFunc->getArg(0), RotateModVal);
318 }
319 // We want the "rotate" number of the more significant int's LSBs (MSBs) to
320 // occupy the leftmost (rightmost) "0 space" left by the previous operation.
321 // Therefore, subtract the "rotate" number from the integer bitsize...
322 Value *SubRotateVal = IRB.CreateSub(BitWidthForInsts, RotateModVal);
323 if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
324 // ...and left-shift the more significant int by this number, zero-filling
325 // the LSBs.
326 SecShift = IRB.CreateShl(FSHFunc->getArg(0), SubRotateVal);
327 } else {
328 // ...and right-shift the less significant int by this number, zero-filling
329 // the MSBs.
330 SecShift = IRB.CreateLShr(FSHFunc->getArg(1), SubRotateVal);
331 }
332 // A simple binary addition of the shifted ints yields the final result.
333 IRB.CreateRet(IRB.CreateOr(FirstShift, SecShift));
334
335 FSHIntrinsic->setCalledFunction(FSHFunc);
336}
337
339 // If we cannot use the SPV_KHR_expect_assume extension, then we need to
340 // ignore the intrinsic and move on. It should be removed later on by LLVM.
341 // Otherwise we should lower the intrinsic to the corresponding SPIR-V
342 // instruction.
343 // For @llvm.assume we have OpAssumeTrueKHR.
344 // For @llvm.expect we have OpExpectKHR.
345 //
346 // We need to lower this into a builtin and then the builtin into a SPIR-V
347 // instruction.
348 if (II->getIntrinsicID() == Intrinsic::assume) {
350 II->getModule(), Intrinsic::SPVIntrinsics::spv_assume);
351 II->setCalledFunction(F);
352 } else if (II->getIntrinsicID() == Intrinsic::expect) {
354 II->getModule(), Intrinsic::SPVIntrinsics::spv_expect,
355 {II->getOperand(0)->getType()});
356 II->setCalledFunction(F);
357 } else {
358 llvm_unreachable("Unknown intrinsic");
359 }
360}
361
363 IRBuilder<> Builder(II);
364 auto *Alloca = cast<AllocaInst>(II->getArgOperand(0));
365 std::optional<TypeSize> Size =
366 Alloca->getAllocationSize(Alloca->getDataLayout());
367 Value *SizeVal = Builder.getInt64(Size ? *Size : -1);
368 Builder.CreateIntrinsic(NewID, Alloca->getType(),
369 {SizeVal, II->getArgOperand(0)});
370 II->eraseFromParent();
371 return true;
372}
373
374// Substitutes calls to LLVM intrinsics with either calls to SPIR-V intrinsics
375// or calls to proper generated functions. Returns True if F was modified.
376bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
377 bool Changed = false;
378 const SPIRVSubtarget &STI = TM.getSubtarget<SPIRVSubtarget>(*F);
379 for (BasicBlock &BB : *F) {
380 for (Instruction &I : make_early_inc_range(BB)) {
381 auto Call = dyn_cast<CallInst>(&I);
382 if (!Call)
383 continue;
384 Function *CF = Call->getCalledFunction();
385 if (!CF || !CF->isIntrinsic())
386 continue;
387 auto *II = cast<IntrinsicInst>(Call);
388 switch (II->getIntrinsicID()) {
389 case Intrinsic::memset:
390 case Intrinsic::bswap:
391 Changed |= lowerIntrinsicToFunction(II);
392 break;
393 case Intrinsic::fshl:
394 case Intrinsic::fshr:
396 Changed = true;
397 break;
398 case Intrinsic::assume:
399 case Intrinsic::expect:
400 if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume))
402 Changed = true;
403 break;
404 case Intrinsic::lifetime_start:
405 if (!STI.isShader()) {
406 Changed |= toSpvLifetimeIntrinsic(
407 II, Intrinsic::SPVIntrinsics::spv_lifetime_start);
408 } else {
409 II->eraseFromParent();
410 Changed = true;
411 }
412 break;
413 case Intrinsic::lifetime_end:
414 if (!STI.isShader()) {
415 Changed |= toSpvLifetimeIntrinsic(
416 II, Intrinsic::SPVIntrinsics::spv_lifetime_end);
417 } else {
418 II->eraseFromParent();
419 Changed = true;
420 }
421 break;
422 case Intrinsic::ptr_annotation:
424 Changed = true;
425 break;
426 }
427 }
428 }
429 return Changed;
430}
431
432// Returns F if aggregate argument/return types are not present or cloned F
433// function with the types replaced by i32 types. The change in types is
434// noted in 'spv.cloned_funcs' metadata for later restoration.
435Function *
436SPIRVPrepareFunctions::removeAggregateTypesFromSignature(Function *F) {
437 bool IsRetAggr = F->getReturnType()->isAggregateType();
438 // Allow intrinsics with aggregate return type to reach GlobalISel
439 if (F->isIntrinsic() && IsRetAggr)
440 return F;
441
442 IRBuilder<> B(F->getContext());
443
444 bool HasAggrArg = llvm::any_of(F->args(), [](Argument &Arg) {
445 return Arg.getType()->isAggregateType();
446 });
447 bool DoClone = IsRetAggr || HasAggrArg;
448 if (!DoClone)
449 return F;
450 SmallVector<std::pair<int, Type *>, 4> ChangedTypes;
451 Type *RetType = IsRetAggr ? B.getInt32Ty() : F->getReturnType();
452 if (IsRetAggr)
453 ChangedTypes.push_back(std::pair<int, Type *>(-1, F->getReturnType()));
454 SmallVector<Type *, 4> ArgTypes;
455 for (const auto &Arg : F->args()) {
456 if (Arg.getType()->isAggregateType()) {
457 ArgTypes.push_back(B.getInt32Ty());
458 ChangedTypes.push_back(
459 std::pair<int, Type *>(Arg.getArgNo(), Arg.getType()));
460 } else
461 ArgTypes.push_back(Arg.getType());
462 }
463 FunctionType *NewFTy =
464 FunctionType::get(RetType, ArgTypes, F->getFunctionType()->isVarArg());
465 Function *NewF =
466 Function::Create(NewFTy, F->getLinkage(), F->getName(), *F->getParent());
467
469 auto NewFArgIt = NewF->arg_begin();
470 for (auto &Arg : F->args()) {
471 StringRef ArgName = Arg.getName();
472 NewFArgIt->setName(ArgName);
473 VMap[&Arg] = &(*NewFArgIt++);
474 }
476
477 CloneFunctionInto(NewF, F, VMap, CloneFunctionChangeType::LocalChangesOnly,
478 Returns);
479 NewF->takeName(F);
480
481 NamedMDNode *FuncMD =
482 F->getParent()->getOrInsertNamedMetadata("spv.cloned_funcs");
484 MDArgs.push_back(MDString::get(B.getContext(), NewF->getName()));
485 for (auto &ChangedTyP : ChangedTypes)
486 MDArgs.push_back(MDNode::get(
487 B.getContext(),
488 {ConstantAsMetadata::get(B.getInt32(ChangedTyP.first)),
489 ValueAsMetadata::get(Constant::getNullValue(ChangedTyP.second))}));
490 MDNode *ThisFuncMD = MDNode::get(B.getContext(), MDArgs);
491 FuncMD->addOperand(ThisFuncMD);
492
493 for (auto *U : make_early_inc_range(F->users())) {
494 if (auto *CI = dyn_cast<CallInst>(U))
495 CI->mutateFunctionType(NewF->getFunctionType());
496 U->replaceUsesOfWith(F, NewF);
497 }
498
499 // register the mutation
500 if (RetType != F->getReturnType())
502 NewF, F->getReturnType());
503 return NewF;
504}
505
506bool SPIRVPrepareFunctions::runOnModule(Module &M) {
507 bool Changed = false;
508 for (Function &F : M) {
509 Changed |= substituteIntrinsicCalls(&F);
510 Changed |= sortBlocks(F);
511 }
512
513 std::vector<Function *> FuncsWorklist;
514 for (auto &F : M)
515 FuncsWorklist.push_back(&F);
516
517 for (auto *F : FuncsWorklist) {
518 Function *NewF = removeAggregateTypesFromSignature(F);
519
520 if (NewF != F) {
521 F->eraseFromParent();
522 Changed = true;
523 }
524 }
525 return Changed;
526}
527
530 return new SPIRVPrepareFunctions(TM);
531}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
return RetTy
std::string Name
uint64_t Size
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
static void lowerFunnelShifts(IntrinsicInst *FSHIntrinsic)
static std::string getAnnotation(Value *AnnoVal, Value *OptAnnoVal)
static bool lowerIntrinsicToFunction(IntrinsicInst *Intrinsic)
static void lowerPtrAnnotation(IntrinsicInst *II)
static SmallVector< Metadata * > parseAnnotation(Value *I, const std::string &Anno, LLVMContext &Ctx, Type *Int32Ty)
static bool toSpvLifetimeIntrinsic(IntrinsicInst *II, Intrinsic::ID NewID)
static void lowerExpectAssume(IntrinsicInst *II)
static Function * getOrCreateFunction(Module *M, Type *RetTy, ArrayRef< Type * > ArgTypes, StringRef Name)
This file contains some functions that are useful when dealing with strings.
@ Struct
Represent the analysis usage information of a pass.
This class represents an incoming formal argument to a Function.
Definition: Argument.h:32
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1205
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition: InstrTypes.h:1387
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:592
unsigned getNumElements() const
Definition: DerivedTypes.h:635
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:170
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:166
bool empty() const
Definition: Function.h:857
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:209
arg_iterator arg_begin()
Definition: Function.h:866
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition: Function.h:249
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:214
void setCallingConv(CallingConv::ID CC)
Definition: Function.h:274
Argument * getArg(unsigned i) const
Definition: Function.h:884
void setDSOLocal(bool Local)
Definition: GlobalValue.h:305
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:53
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Definition: IRBuilder.cpp:1115
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1513
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1172
ConstantInt * getInt64(uint64_t C)
Get a constant 64-bit value.
Definition: IRBuilder.h:527
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:834
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1420
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1492
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Definition: IRBuilder.h:630
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1167
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:207
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition: IRBuilder.h:1573
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Definition: IRBuilder.h:538
Value * CreateURem(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1480
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:78
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:49
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition: IntrinsicInst.h:56
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
Metadata node.
Definition: Metadata.h:1077
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:607
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
static LLVM_ABI MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:103
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:255
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
A tuple of MDNodes.
Definition: Metadata.h:1753
LLVM_ABI void addOperand(MDNode *M)
Definition: Metadata.cpp:1471
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:112
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:85
void addMutated(Value *Val, Type *Ty)
bool isShader() const
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
bool canUseExtension(SPIRV::Extension::Extension E) const
size_t size() const
Definition: SmallVector.h:79
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getIntegerBitWidth() const
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:390
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:396
Type * getElementType() const
Definition: DerivedTypes.h:463
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
Definition: CallingConv.h:138
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
Definition: Intrinsics.cpp:751
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI bool getConstantStringInfo(const Value *V, StringRef &Str, bool TrimAtNul=true)
This function computes the length of a null-terminated C string pointed to by V.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:663
bool sortBlocks(Function &F)
Definition: SPIRVUtils.cpp:723
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
@ Ref
The access may reference the value stored in memory.
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1879
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:223
LLVM_ABI void CloneFunctionInto(Function *NewFunc, const Function *OldFunc, ValueToValueMapTy &VMap, CloneFunctionChangeType Changes, SmallVectorImpl< ReturnInst * > &Returns, const char *NameSuffix="", ClonedCodeInfo *CodeInfo=nullptr, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Clone OldFunc into NewFunc, transforming the old arguments into references to VMap values.
ModulePass * createSPIRVPrepareFunctionsPass(const SPIRVTargetMachine &TM)
LLVM_ABI void expandMemSetAsLoop(MemSetInst *MemSet)
Expand MemSet as a loop. MemSet is not deleted.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856