Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.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"
25#include "llvm/ADT/StringExtras.h"
26#include "llvm/Analysis/ValueTracking.h"
27#include "llvm/CodeGen/IntrinsicLowering.h"
28#include "llvm/IR/IRBuilder.h"
29#include "llvm/IR/IntrinsicInst.h"
30#include "llvm/IR/Intrinsics.h"
31#include "llvm/IR/IntrinsicsSPIRV.h"
32#include "llvm/Transforms/Utils/Cloning.h"
33#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
34#include <regex>
35
36using namespacellvm;
37
38namespacellvm {
39voidinitializeSPIRVPrepareFunctionsPass(PassRegistry &);
40}
41
42namespace{
43
44classSPIRVPrepareFunctions :publicModulePass {
45constSPIRVTargetMachine &TM;
46bool substituteIntrinsicCalls(Function *F);
47Function *removeAggregateTypesFromSignature(Function *F);
48
49public:
50staticcharID;
51 SPIRVPrepareFunctions(constSPIRVTargetMachine &TM) :ModulePass(ID), TM(TM) {
52initializeSPIRVPrepareFunctionsPass(*PassRegistry::getPassRegistry());
53 }
54
55boolrunOnModule(Module &M)override;
56
57StringRefgetPassName() const override{return"SPIRV prepare functions"; }
58
59voidgetAnalysisUsage(AnalysisUsage &AU) const override{
60ModulePass::getAnalysisUsage(AU);
61 }
62};
63
64}// namespace
65
66char SPIRVPrepareFunctions::ID = 0;
67
68INITIALIZE_PASS(SPIRVPrepareFunctions,"prepare-functions",
69"SPIRV prepare functions",false,false)
70
71std::string lowerLLVMIntrinsicName(IntrinsicInst *II) {
72Function *IntrinsicFunc =II->getCalledFunction();
73assert(IntrinsicFunc &&"Missing function");
74 std::string FuncName = IntrinsicFunc->getName().str();
75 std::replace(FuncName.begin(), FuncName.end(),'.','_');
76 FuncName ="spirv." + FuncName;
77return FuncName;
78}
79
80staticFunction *getOrCreateFunction(Module *M,Type *RetTy,
81ArrayRef<Type *> ArgTypes,
82StringRefName) {
83FunctionType *FT = FunctionType::get(RetTy, ArgTypes,false);
84Function *F = M->getFunction(Name);
85if (F &&F->getFunctionType() == FT)
86returnF;
87Function *NewF =Function::Create(FT,GlobalValue::ExternalLinkage,Name, M);
88if (F)
89 NewF->setDSOLocal(F->isDSOLocal());
90 NewF->setCallingConv(CallingConv::SPIR_FUNC);
91return NewF;
92}
93
94staticboollowerIntrinsicToFunction(IntrinsicInst *Intrinsic) {
95// For @llvm.memset.* intrinsic cases with constant value and length arguments
96// are emulated via "storing" a constant array to the destination. For other
97// cases we wrap the intrinsic in @spirv.llvm_memset_* function and expand the
98// intrinsic to a loop via expandMemSetAsLoop().
99if (auto *MSI = dyn_cast<MemSetInst>(Intrinsic))
100if (isa<Constant>(MSI->getValue()) && isa<ConstantInt>(MSI->getLength()))
101returnfalse;// It is handled later using OpCopyMemorySized.
102
103Module *M = Intrinsic->getModule();
104 std::string FuncName = lowerLLVMIntrinsicName(Intrinsic);
105if (Intrinsic->isVolatile())
106 FuncName +=".volatile";
107// Redirect @llvm.intrinsic.* call to @spirv.llvm_intrinsic_*
108Function *F = M->getFunction(FuncName);
109if (F) {
110 Intrinsic->setCalledFunction(F);
111returntrue;
112 }
113// TODO copy arguments attributes: nocapture writeonly.
114FunctionCallee FC =
115 M->getOrInsertFunction(FuncName, Intrinsic->getFunctionType());
116auto IntrinsicID = Intrinsic->getIntrinsicID();
117 Intrinsic->setCalledFunction(FC);
118
119F = dyn_cast<Function>(FC.getCallee());
120assert(F &&"Callee must be a function");
121
122switch (IntrinsicID) {
123case Intrinsic::memset: {
124auto *MSI =static_cast<MemSetInst *>(Intrinsic);
125Argument *Dest =F->getArg(0);
126Argument *Val =F->getArg(1);
127Argument *Len =F->getArg(2);
128Argument *IsVolatile =F->getArg(3);
129 Dest->setName("dest");
130 Val->setName("val");
131 Len->setName("len");
132 IsVolatile->setName("isvolatile");
133BasicBlock *EntryBB =BasicBlock::Create(M->getContext(),"entry",F);
134IRBuilder<> IRB(EntryBB);
135auto *MemSet = IRB.CreateMemSet(Dest, Val, Len, MSI->getDestAlign(),
136 MSI->isVolatile());
137 IRB.CreateRetVoid();
138expandMemSetAsLoop(cast<MemSetInst>(MemSet));
139 MemSet->eraseFromParent();
140break;
141 }
142case Intrinsic::bswap: {
143BasicBlock *EntryBB =BasicBlock::Create(M->getContext(),"entry",F);
144IRBuilder<> IRB(EntryBB);
145auto *BSwap = IRB.CreateIntrinsic(Intrinsic::bswap, Intrinsic->getType(),
146F->getArg(0));
147 IRB.CreateRet(BSwap);
148IntrinsicLowering IL(M->getDataLayout());
149 IL.LowerIntrinsicCall(BSwap);
150break;
151 }
152default:
153break;
154 }
155returntrue;
156}
157
158static std::stringgetAnnotation(Value *AnnoVal,Value *OptAnnoVal) {
159if (auto *Ref = dyn_cast_or_null<GetElementPtrInst>(AnnoVal))
160 AnnoVal =Ref->getOperand(0);
161if (auto *Ref = dyn_cast_or_null<BitCastInst>(OptAnnoVal))
162 OptAnnoVal =Ref->getOperand(0);
163
164 std::string Anno;
165if (auto *C = dyn_cast_or_null<Constant>(AnnoVal)) {
166StringRef Str;
167if (getConstantStringInfo(C, Str))
168 Anno = Str;
169 }
170// handle optional annotation parameter in a way that Khronos Translator do
171// (collect integers wrapped in a struct)
172if (auto *C = dyn_cast_or_null<Constant>(OptAnnoVal);
173C &&C->getNumOperands()) {
174Value *MaybeStruct =C->getOperand(0);
175if (auto *Struct = dyn_cast<ConstantStruct>(MaybeStruct)) {
176for (unsignedI = 0, E =Struct->getNumOperands();I != E; ++I) {
177if (auto *CInt = dyn_cast<ConstantInt>(Struct->getOperand(I)))
178 Anno += (I == 0 ?": " :", ") +
179 std::to_string(CInt->getType()->getIntegerBitWidth() == 1
180 ? CInt->getZExtValue()
181 : CInt->getSExtValue());
182 }
183 }elseif (auto *Struct = dyn_cast<ConstantAggregateZero>(MaybeStruct)) {
184// { i32 i32 ... } zeroinitializer
185for (unsignedI = 0, E =Struct->getType()->getStructNumElements();
186I != E; ++I)
187 Anno +=I == 0 ?": 0" :", 0";
188 }
189 }
190return Anno;
191}
192
193staticSmallVector<Metadata *>parseAnnotation(Value *I,
194const std::string &Anno,
195LLVMContext &Ctx,
196Type *Int32Ty) {
197// Try to parse the annotation string according to the following rules:
198// annotation := ({kind} | {kind:value,value,...})+
199// kind := number
200// value := number | string
201staticconst std::regex R(
202"\\{(\\d+)(?:[:,](\\d+|\"[^\"]*\")(?:,(\\d+|\"[^\"]*\"))*)?\\}");
203SmallVector<Metadata *> MDs;
204int Pos = 0;
205for (std::sregex_iterator
206 It = std::sregex_iterator(Anno.begin(), Anno.end(), R),
207 ItEnd = std::sregex_iterator();
208 It != ItEnd; ++It) {
209if (It->position() != Pos)
210returnSmallVector<Metadata *>{};
211 Pos = It->position() + It->length();
212 std::smatchMatch = *It;
213SmallVector<Metadata *> MDsItem;
214for (std::size_t i = 1; i <Match.size(); ++i) {
215 std::ssub_match SMatch =Match[i];
216 std::string Item = SMatch.str();
217if (Item.length() == 0)
218break;
219if (Item[0] =='"') {
220 Item = Item.substr(1, Item.length() - 2);
221// Acceptable format of the string snippet is:
222staticconst std::regex RStr("^(\\d+)(?:,(\\d+))*$");
223if (std::smatch MatchStr; std::regex_match(Item, MatchStr, RStr)) {
224for (std::size_t SubIdx = 1; SubIdx < MatchStr.size(); ++SubIdx)
225if (std::string SubStr = MatchStr[SubIdx].str(); SubStr.length())
226 MDsItem.push_back(ConstantAsMetadata::get(
227 ConstantInt::get(Int32Ty, std::stoi(SubStr))));
228 }else {
229 MDsItem.push_back(MDString::get(Ctx, Item));
230 }
231 }elseif (int32_t Num; llvm::to_integer(StringRef(Item), Num, 10)) {
232 MDsItem.push_back(
233ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Num)));
234 }else {
235 MDsItem.push_back(MDString::get(Ctx, Item));
236 }
237 }
238if (MDsItem.size() == 0)
239returnSmallVector<Metadata *>{};
240 MDs.push_back(MDNode::get(Ctx, MDsItem));
241 }
242return Pos ==static_cast<int>(Anno.length()) ? MDs
243 :SmallVector<Metadata *>{};
244}
245
246staticvoidlowerPtrAnnotation(IntrinsicInst *II) {
247LLVMContext &Ctx =II->getContext();
248Type *Int32Ty =Type::getInt32Ty(Ctx);
249
250// Retrieve an annotation string from arguments.
251Value *PtrArg =nullptr;
252if (auto *BI = dyn_cast<BitCastInst>(II->getArgOperand(0)))
253 PtrArg = BI->getOperand(0);
254else
255 PtrArg =II->getOperand(0);
256 std::string Anno =
257getAnnotation(II->getArgOperand(1),
258 4 <II->arg_size() ?II->getArgOperand(4) :nullptr);
259
260// Parse the annotation.
261SmallVector<Metadata *> MDs =parseAnnotation(II, Anno, Ctx, Int32Ty);
262
263// If the annotation string is not parsed successfully we don't know the
264// format used and output it as a general UserSemantic decoration.
265// Otherwise MDs is a Metadata tuple (a decoration list) in the format
266// expected by `spirv.Decorations`.
267if (MDs.size() == 0) {
268auto UserSemantic =ConstantAsMetadata::get(ConstantInt::get(
269 Int32Ty,static_cast<uint32_t>(SPIRV::Decoration::UserSemantic)));
270 MDs.push_back(MDNode::get(Ctx, {UserSemantic,MDString::get(Ctx, Anno)}));
271 }
272
273// Build the internal intrinsic function.
274IRBuilder<> IRB(II->getParent());
275 IRB.SetInsertPoint(II);
276 IRB.CreateIntrinsic(
277 Intrinsic::spv_assign_decoration, {PtrArg->getType()},
278 {PtrArg,MetadataAsValue::get(Ctx,MDNode::get(Ctx, MDs))});
279II->replaceAllUsesWith(II->getOperand(0));
280}
281
282staticvoidlowerFunnelShifts(IntrinsicInst *FSHIntrinsic) {
283// Get a separate function - otherwise, we'd have to rework the CFG of the
284// current one. Then simply replace the intrinsic uses with a call to the new
285// function.
286// Generate LLVM IR for i* @spirv.llvm_fsh?_i* (i* %a, i* %b, i* %c)
287Module *M = FSHIntrinsic->getModule();
288FunctionType *FSHFuncTy = FSHIntrinsic->getFunctionType();
289Type *FSHRetTy = FSHFuncTy->getReturnType();
290const std::string FuncName = lowerLLVMIntrinsicName(FSHIntrinsic);
291Function *FSHFunc =
292getOrCreateFunction(M, FSHRetTy, FSHFuncTy->params(), FuncName);
293
294if (!FSHFunc->empty()) {
295 FSHIntrinsic->setCalledFunction(FSHFunc);
296return;
297 }
298BasicBlock *RotateBB =BasicBlock::Create(M->getContext(),"rotate", FSHFunc);
299IRBuilder<> IRB(RotateBB);
300Type *Ty = FSHFunc->getReturnType();
301// Build the actual funnel shift rotate logic.
302// In the comments, "int" is used interchangeably with "vector of int
303// elements".
304FixedVectorType *VectorTy = dyn_cast<FixedVectorType>(Ty);
305Type *IntTy = VectorTy ? VectorTy->getElementType() : Ty;
306unsignedBitWidth = IntTy->getIntegerBitWidth();
307ConstantInt *BitWidthConstant = IRB.getInt({BitWidth,BitWidth});
308Value *BitWidthForInsts =
309 VectorTy
310 ? IRB.CreateVectorSplat(VectorTy->getNumElements(), BitWidthConstant)
311 : BitWidthConstant;
312Value *RotateModVal =
313 IRB.CreateURem(/*Rotate*/ FSHFunc->getArg(2), BitWidthForInsts);
314Value *FirstShift =nullptr, *SecShift =nullptr;
315if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
316// Shift the less significant number right, the "rotate" number of bits
317// will be 0-filled on the left as a result of this regular shift.
318 FirstShift = IRB.CreateLShr(FSHFunc->getArg(1), RotateModVal);
319 }else {
320// Shift the more significant number left, the "rotate" number of bits
321// will be 0-filled on the right as a result of this regular shift.
322 FirstShift = IRB.CreateShl(FSHFunc->getArg(0), RotateModVal);
323 }
324// We want the "rotate" number of the more significant int's LSBs (MSBs) to
325// occupy the leftmost (rightmost) "0 space" left by the previous operation.
326// Therefore, subtract the "rotate" number from the integer bitsize...
327Value *SubRotateVal = IRB.CreateSub(BitWidthForInsts, RotateModVal);
328if (FSHIntrinsic->getIntrinsicID() == Intrinsic::fshr) {
329// ...and left-shift the more significant int by this number, zero-filling
330// the LSBs.
331 SecShift = IRB.CreateShl(FSHFunc->getArg(0), SubRotateVal);
332 }else {
333// ...and right-shift the less significant int by this number, zero-filling
334// the MSBs.
335 SecShift = IRB.CreateLShr(FSHFunc->getArg(1), SubRotateVal);
336 }
337// A simple binary addition of the shifted ints yields the final result.
338 IRB.CreateRet(IRB.CreateOr(FirstShift, SecShift));
339
340 FSHIntrinsic->setCalledFunction(FSHFunc);
341}
342
343staticvoidlowerExpectAssume(IntrinsicInst *II) {
344// If we cannot use the SPV_KHR_expect_assume extension, then we need to
345// ignore the intrinsic and move on. It should be removed later on by LLVM.
346// Otherwise we should lower the intrinsic to the corresponding SPIR-V
347// instruction.
348// For @llvm.assume we have OpAssumeTrueKHR.
349// For @llvm.expect we have OpExpectKHR.
350//
351// We need to lower this into a builtin and then the builtin into a SPIR-V
352// instruction.
353if (II->getIntrinsicID() == Intrinsic::assume) {
354Function *F =Intrinsic::getOrInsertDeclaration(
355II->getModule(), Intrinsic::SPVIntrinsics::spv_assume);
356II->setCalledFunction(F);
357 }elseif (II->getIntrinsicID() == Intrinsic::expect) {
358Function *F =Intrinsic::getOrInsertDeclaration(
359II->getModule(), Intrinsic::SPVIntrinsics::spv_expect,
360 {II->getOperand(0)->getType()});
361II->setCalledFunction(F);
362 }else {
363llvm_unreachable("Unknown intrinsic");
364 }
365
366return;
367}
368
369staticbooltoSpvOverloadedIntrinsic(IntrinsicInst *II,Intrinsic::ID NewID,
370ArrayRef<unsigned> OpNos) {
371Function *F =nullptr;
372if (OpNos.empty()) {
373F =Intrinsic::getOrInsertDeclaration(II->getModule(), NewID);
374 }else {
375SmallVector<Type *, 4> Tys;
376for (unsigned OpNo : OpNos)
377 Tys.push_back(II->getOperand(OpNo)->getType());
378F =Intrinsic::getOrInsertDeclaration(II->getModule(), NewID, Tys);
379 }
380II->setCalledFunction(F);
381returntrue;
382}
383
384// Substitutes calls to LLVM intrinsics with either calls to SPIR-V intrinsics
385// or calls to proper generated functions. Returns True if F was modified.
386bool SPIRVPrepareFunctions::substituteIntrinsicCalls(Function *F) {
387bool Changed =false;
388for (BasicBlock &BB : *F) {
389for (Instruction &I : BB) {
390autoCall = dyn_cast<CallInst>(&I);
391if (!Call)
392continue;
393Function *CF =Call->getCalledFunction();
394if (!CF || !CF->isIntrinsic())
395continue;
396auto *II = cast<IntrinsicInst>(Call);
397switch (II->getIntrinsicID()) {
398case Intrinsic::memset:
399case Intrinsic::bswap:
400 Changed |=lowerIntrinsicToFunction(II);
401break;
402case Intrinsic::fshl:
403case Intrinsic::fshr:
404lowerFunnelShifts(II);
405 Changed =true;
406break;
407case Intrinsic::assume:
408case Intrinsic::expect: {
409constSPIRVSubtarget &STI =TM.getSubtarget<SPIRVSubtarget>(*F);
410if (STI.canUseExtension(SPIRV::Extension::SPV_KHR_expect_assume))
411lowerExpectAssume(II);
412 Changed =true;
413 }break;
414case Intrinsic::lifetime_start:
415 Changed |=toSpvOverloadedIntrinsic(
416II, Intrinsic::SPVIntrinsics::spv_lifetime_start, {1});
417break;
418case Intrinsic::lifetime_end:
419 Changed |=toSpvOverloadedIntrinsic(
420II, Intrinsic::SPVIntrinsics::spv_lifetime_end, {1});
421break;
422case Intrinsic::ptr_annotation:
423lowerPtrAnnotation(II);
424 Changed =true;
425break;
426 }
427 }
428 }
429return 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) {
437bool IsRetAggr =F->getReturnType()->isAggregateType();
438// Allow intrinsics with aggregate return type to reach GlobalISel
439if (F->isIntrinsic() && IsRetAggr)
440returnF;
441
442IRBuilder<>B(F->getContext());
443
444bool HasAggrArg =
445 std::any_of(F->arg_begin(),F->arg_end(), [](Argument &Arg) {
446 return Arg.getType()->isAggregateType();
447 });
448bool DoClone = IsRetAggr || HasAggrArg;
449if (!DoClone)
450returnF;
451SmallVector<std::pair<int, Type *>, 4> ChangedTypes;
452Type *RetType = IsRetAggr ?B.getInt32Ty() :F->getReturnType();
453if (IsRetAggr)
454 ChangedTypes.push_back(std::pair<int, Type *>(-1,F->getReturnType()));
455SmallVector<Type *, 4> ArgTypes;
456for (constauto &Arg :F->args()) {
457if (Arg.getType()->isAggregateType()) {
458 ArgTypes.push_back(B.getInt32Ty());
459 ChangedTypes.push_back(
460 std::pair<int, Type *>(Arg.getArgNo(), Arg.getType()));
461 }else
462 ArgTypes.push_back(Arg.getType());
463 }
464FunctionType *NewFTy =
465 FunctionType::get(RetType, ArgTypes,F->getFunctionType()->isVarArg());
466Function *NewF =
467Function::Create(NewFTy,F->getLinkage(),F->getName(), *F->getParent());
468
469ValueToValueMapTy VMap;
470auto NewFArgIt = NewF->arg_begin();
471for (auto &Arg :F->args()) {
472StringRef ArgName = Arg.getName();
473 NewFArgIt->setName(ArgName);
474 VMap[&Arg] = &(*NewFArgIt++);
475 }
476SmallVector<ReturnInst *, 8> Returns;
477
478CloneFunctionInto(NewF,F, VMap, CloneFunctionChangeType::LocalChangesOnly,
479 Returns);
480 NewF->takeName(F);
481
482NamedMDNode *FuncMD =
483F->getParent()->getOrInsertNamedMetadata("spv.cloned_funcs");
484SmallVector<Metadata *, 2> MDArgs;
485 MDArgs.push_back(MDString::get(B.getContext(), NewF->getName()));
486for (auto &ChangedTyP : ChangedTypes)
487 MDArgs.push_back(MDNode::get(
488B.getContext(),
489 {ConstantAsMetadata::get(B.getInt32(ChangedTyP.first)),
490 ValueAsMetadata::get(Constant::getNullValue(ChangedTyP.second))}));
491MDNode *ThisFuncMD =MDNode::get(B.getContext(), MDArgs);
492 FuncMD->addOperand(ThisFuncMD);
493
494for (auto *U :make_early_inc_range(F->users())) {
495if (auto *CI = dyn_cast<CallInst>(U))
496 CI->mutateFunctionType(NewF->getFunctionType());
497U->replaceUsesOfWith(F, NewF);
498 }
499
500// register the mutation
501if (RetType !=F->getReturnType())
502TM.getSubtarget<SPIRVSubtarget>(*F).getSPIRVGlobalRegistry()->addMutated(
503 NewF,F->getReturnType());
504return NewF;
505}
506
507bool SPIRVPrepareFunctions::runOnModule(Module &M) {
508bool Changed =false;
509for (Function &F : M) {
510 Changed |= substituteIntrinsicCalls(&F);
511 Changed |=sortBlocks(F);
512 }
513
514 std::vector<Function *> FuncsWorklist;
515for (auto &F : M)
516 FuncsWorklist.push_back(&F);
517
518for (auto *F : FuncsWorklist) {
519Function *NewF = removeAggregateTypesFromSignature(F);
520
521if (NewF !=F) {
522F->eraseFromParent();
523 Changed =true;
524 }
525 }
526return Changed;
527}
528
529ModulePass *
530llvm::createSPIRVPrepareFunctionsPass(constSPIRVTargetMachine &TM) {
531returnnew SPIRVPrepareFunctions(TM);
532}
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Cloning.h
RetTy
return RetTy
Definition:DeadArgumentElimination.cpp:361
Name
std::string Name
Definition:ELFObjHandler.cpp:77
IRBuilder.h
IntrinsicInst.h
IntrinsicLowering.h
Intrinsics.h
LowerMemIntrinsics.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
II
uint64_t IntrinsicInst * II
Definition:NVVMIntrRange.cpp:51
INITIALIZE_PASS
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:38
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
lowerFunnelShifts
static void lowerFunnelShifts(IntrinsicInst *FSHIntrinsic)
Definition:SPIRVPrepareFunctions.cpp:282
getAnnotation
static std::string getAnnotation(Value *AnnoVal, Value *OptAnnoVal)
Definition:SPIRVPrepareFunctions.cpp:158
toSpvOverloadedIntrinsic
static bool toSpvOverloadedIntrinsic(IntrinsicInst *II, Intrinsic::ID NewID, ArrayRef< unsigned > OpNos)
Definition:SPIRVPrepareFunctions.cpp:369
lowerIntrinsicToFunction
static bool lowerIntrinsicToFunction(IntrinsicInst *Intrinsic)
Definition:SPIRVPrepareFunctions.cpp:94
lowerPtrAnnotation
static void lowerPtrAnnotation(IntrinsicInst *II)
Definition:SPIRVPrepareFunctions.cpp:246
parseAnnotation
static SmallVector< Metadata * > parseAnnotation(Value *I, const std::string &Anno, LLVMContext &Ctx, Type *Int32Ty)
Definition:SPIRVPrepareFunctions.cpp:193
lowerExpectAssume
static void lowerExpectAssume(IntrinsicInst *II)
Definition:SPIRVPrepareFunctions.cpp:343
getOrCreateFunction
static Function * getOrCreateFunction(Module *M, Type *RetTy, ArrayRef< Type * > ArgTypes, StringRef Name)
Definition:SPIRVPrepareFunctions.cpp:80
SPIRVSubtarget.h
SPIRVTargetMachine.h
SPIRVUtils.h
SPIRV.h
StringExtras.h
This file contains some functions that are useful when dealing with strings.
Struct
@ Struct
Definition:TargetLibraryInfo.cpp:78
ValueTracking.h
FunctionType
Definition:ItaniumDemangle.h:823
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition:PassAnalysisSupport.h:47
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition:Argument.h:31
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition:ArrayRef.h:163
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition:BasicBlock.h:213
llvm::CallBase::getFunctionType
FunctionType * getFunctionType() const
Definition:InstrTypes.h:1199
llvm::CallBase::setCalledFunction
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Definition:InstrTypes.h:1380
llvm::ConstantAsMetadata::get
static ConstantAsMetadata * get(Constant *C)
Definition:Metadata.h:532
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::FixedVectorType
Class to represent fixed width SIMD vectors.
Definition:DerivedTypes.h:563
llvm::FixedVectorType::getNumElements
unsigned getNumElements() const
Definition:DerivedTypes.h:606
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition:DerivedTypes.h:170
llvm::Function
Definition:Function.h:63
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition:Function.h:173
llvm::Function::empty
bool empty() const
Definition:Function.h:859
llvm::Function::getFunctionType
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition:Function.h:216
llvm::Function::arg_begin
arg_iterator arg_begin()
Definition:Function.h:868
llvm::Function::isIntrinsic
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
Definition:Function.h:256
llvm::Function::getReturnType
Type * getReturnType() const
Returns the type of the ret val.
Definition:Function.h:221
llvm::Function::setCallingConv
void setCallingConv(CallingConv::ID CC)
Definition:Function.h:281
llvm::Function::getArg
Argument * getArg(unsigned i) const
Definition:Function.h:886
llvm::GlobalValue::setDSOLocal
void setDSOLocal(bool Local)
Definition:GlobalValue.h:304
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition:GlobalValue.h:52
llvm::IRBuilderBase::CreateVectorSplat
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Definition:IRBuilder.cpp:1163
llvm::IRBuilderBase::CreateMemSet
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
Definition:IRBuilder.h:614
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition:IRBuilder.h:1480
llvm::IRBuilderBase::CreateRet
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition:IRBuilder.h:1139
llvm::IRBuilderBase::CreateIntrinsic
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:900
llvm::IRBuilderBase::CreateSub
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition:IRBuilder.h:1387
llvm::IRBuilderBase::CreateShl
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition:IRBuilder.h:1459
llvm::IRBuilderBase::CreateRetVoid
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition:IRBuilder.h:1134
llvm::IRBuilderBase::CreateOr
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition:IRBuilder.h:1540
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition:IRBuilder.h:199
llvm::IRBuilderBase::getInt
ConstantInt * getInt(const APInt &AI)
Get a constant integer value.
Definition:IRBuilder.h:521
llvm::IRBuilderBase::CreateURem
Value * CreateURem(Value *LHS, Value *RHS, const Twine &Name="")
Definition:IRBuilder.h:1447
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::Instruction
Definition:Instruction.h:68
llvm::Instruction::getModule
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition:Instruction.cpp:68
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition:IntrinsicInst.h:48
llvm::IntrinsicInst::getIntrinsicID
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
Definition:IntrinsicInst.h:55
llvm::IntrinsicLowering
Definition:IntrinsicLowering.h:22
llvm::IntrinsicLowering::LowerIntrinsicCall
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
Definition:IntrinsicLowering.cpp:224
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::MDNode
Metadata node.
Definition:Metadata.h:1073
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition:Metadata.h:1549
llvm::MDString::get
static MDString * get(LLVMContext &Context, StringRef Str)
Definition:Metadata.cpp:606
llvm::MemSetInst
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
Definition:IntrinsicInst.h:1237
llvm::MetadataAsValue::get
static MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition:Metadata.cpp:103
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition:Pass.h:251
llvm::ModulePass::runOnModule
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition:Module.h:65
llvm::NamedMDNode
A tuple of MDNodes.
Definition:Metadata.h:1737
llvm::NamedMDNode::addOperand
void addOperand(MDNode *M)
Definition:Metadata.cpp:1431
llvm::PassRegistry
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition:PassRegistry.h:37
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition:PassRegistry.cpp:24
llvm::Pass::getAnalysisUsage
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition:Pass.cpp:98
llvm::Pass::getPassName
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition:Pass.cpp:81
llvm::SPIRVGlobalRegistry::addMutated
void addMutated(Value *Val, Type *Ty)
Definition:SPIRVGlobalRegistry.h:201
llvm::SPIRVSubtarget
Definition:SPIRVSubtarget.h:38
llvm::SPIRVSubtarget::getSPIRVGlobalRegistry
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
Definition:SPIRVSubtarget.h:101
llvm::SPIRVSubtarget::canUseExtension
bool canUseExtension(SPIRV::Extension::Extension E) const
Definition:SPIRVSubtarget.cpp:105
llvm::SPIRVTargetMachine
Definition:SPIRVTargetMachine.h:21
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::getIntegerBitWidth
unsigned getIntegerBitWidth() const
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
llvm::ValueMap< const Value *, WeakTrackingVH >
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition:Value.h:255
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition:Value.cpp:377
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition:Value.cpp:309
llvm::Value::takeName
void takeName(Value *V)
Transfer the name from V to this value.
Definition:Value.cpp:383
llvm::VectorType::getElementType
Type * getElementType() const
Definition:DerivedTypes.h:460
uint32_t
unsigned
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::CallingConv::SPIR_FUNC
@ SPIR_FUNC
Used for SPIR non-kernel device functions.
Definition:CallingConv.h:138
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::Intrinsic::getOrInsertDeclaration
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:732
llvm::M68k::MemAddrModeKind::U
@ U
llvm::MCID::Call
@ Call
Definition:MCInstrDesc.h:156
llvm::SystemZISD::TM
@ TM
Definition:SystemZISelLowering.h:66
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::initializeSPIRVPrepareFunctionsPass
void initializeSPIRVPrepareFunctionsPass(PassRegistry &)
llvm::getConstantStringInfo
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.
Definition:ValueTracking.cpp:6576
llvm::DiagnosticPredicateTy::Match
@ Match
llvm::make_early_inc_range
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:657
llvm::sortBlocks
bool sortBlocks(Function &F)
Definition:SPIRVUtils.cpp:679
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
llvm::BitWidth
constexpr unsigned BitWidth
Definition:BitmaskEnum.h:217
llvm::CloneFunctionInto
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.
Definition:CloneFunction.cpp:262
llvm::createSPIRVPrepareFunctionsPass
ModulePass * createSPIRVPrepareFunctionsPass(const SPIRVTargetMachine &TM)
Definition:SPIRVPrepareFunctions.cpp:530
llvm::expandMemSetAsLoop
void expandMemSetAsLoop(MemSetInst *MemSet)
Expand MemSet as a loop. MemSet is not deleted.
Definition:LowerMemIntrinsics.cpp:967
std
Implement std::hash so that hash_code can be used in STL containers.
Definition:BitVector.h:858

Generated on Fri Jul 18 2025 14:35:26 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp