Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
SPIRVUtils.cpp
Go to the documentation of this file.
1//===--- SPIRVUtils.cpp ---- SPIR-V Utility Functions -----------*- 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 file contains miscellaneous utility functions.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SPIRVUtils.h"
14#include "MCTargetDesc/SPIRVBaseInfo.h"
15#include "SPIRV.h"
16#include "SPIRVGlobalRegistry.h"
17#include "SPIRVInstrInfo.h"
18#include "SPIRVSubtarget.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
21#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
22#include "llvm/CodeGen/MachineInstr.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
24#include "llvm/Demangle/Demangle.h"
25#include "llvm/IR/IntrinsicInst.h"
26#include "llvm/IR/IntrinsicsSPIRV.h"
27#include <queue>
28#include <vector>
29
30namespacellvm {
31
32// The following functions are used to add these string literals as a series of
33// 32-bit integer operands with the correct format, and unpack them if necessary
34// when making string comparisons in compiler passes.
35// SPIR-V requires null-terminated UTF-8 strings padded to 32-bit alignment.
36staticuint32_tconvertCharsToWord(constStringRef &Str,unsigned i) {
37uint32_t Word = 0u;// Build up this 32-bit word from 4 8-bit chars.
38for (unsigned WordIndex = 0; WordIndex < 4; ++WordIndex) {
39unsigned StrIndex = i + WordIndex;
40uint8_t CharToAdd = 0;// Initilize char as padding/null.
41if (StrIndex < Str.size()) {// If it's within the string, get a real char.
42 CharToAdd = Str[StrIndex];
43 }
44 Word |= (CharToAdd << (WordIndex * 8));
45 }
46return Word;
47}
48
49// Get length including padding and null terminator.
50staticsize_tgetPaddedLen(constStringRef &Str) {
51return (Str.size() + 4) & ~3;
52}
53
54voidaddStringImm(constStringRef &Str,MCInst &Inst) {
55constsize_t PaddedLen =getPaddedLen(Str);
56for (unsigned i = 0; i < PaddedLen; i += 4) {
57// Add an operand for the 32-bits of chars or padding.
58 Inst.addOperand(MCOperand::createImm(convertCharsToWord(Str, i)));
59 }
60}
61
62voidaddStringImm(constStringRef &Str,MachineInstrBuilder &MIB) {
63constsize_t PaddedLen =getPaddedLen(Str);
64for (unsigned i = 0; i < PaddedLen; i += 4) {
65// Add an operand for the 32-bits of chars or padding.
66 MIB.addImm(convertCharsToWord(Str, i));
67 }
68}
69
70voidaddStringImm(constStringRef &Str,IRBuilder<> &B,
71 std::vector<Value *> &Args) {
72constsize_t PaddedLen =getPaddedLen(Str);
73for (unsigned i = 0; i < PaddedLen; i += 4) {
74// Add a vector element for the 32-bits of chars or padding.
75 Args.push_back(B.getInt32(convertCharsToWord(Str, i)));
76 }
77}
78
79std::stringgetStringImm(constMachineInstr &MI,unsigned StartIndex) {
80returngetSPIRVStringOperand(MI, StartIndex);
81}
82
83voidaddNumImm(constAPInt &Imm,MachineInstrBuilder &MIB) {
84constauto Bitwidth = Imm.getBitWidth();
85if (Bitwidth == 1)
86return;// Already handled
87elseif (Bitwidth <= 32) {
88 MIB.addImm(Imm.getZExtValue());
89// Asm Printer needs this info to print floating-type correctly
90if (Bitwidth == 16)
91 MIB.getInstr()->setAsmPrinterFlag(SPIRV::ASM_PRINTER_WIDTH16);
92return;
93 }elseif (Bitwidth <= 64) {
94uint64_t FullImm = Imm.getZExtValue();
95uint32_t LowBits = FullImm & 0xffffffff;
96uint32_t HighBits = (FullImm >> 32) & 0xffffffff;
97 MIB.addImm(LowBits).addImm(HighBits);
98return;
99 }
100report_fatal_error("Unsupported constant bitwidth");
101}
102
103voidbuildOpName(RegisterTarget,constStringRef &Name,
104MachineIRBuilder &MIRBuilder) {
105if (!Name.empty()) {
106auto MIB = MIRBuilder.buildInstr(SPIRV::OpName).addUse(Target);
107addStringImm(Name, MIB);
108 }
109}
110
111voidbuildOpName(RegisterTarget,constStringRef &Name,MachineInstr &I,
112constSPIRVInstrInfo &TII) {
113if (!Name.empty()) {
114auto MIB =
115BuildMI(*I.getParent(),I,I.getDebugLoc(),TII.get(SPIRV::OpName))
116 .addUse(Target);
117addStringImm(Name, MIB);
118 }
119}
120
121staticvoidfinishBuildOpDecorate(MachineInstrBuilder &MIB,
122const std::vector<uint32_t> &DecArgs,
123StringRef StrImm) {
124if (!StrImm.empty())
125addStringImm(StrImm, MIB);
126for (constauto &DecArg : DecArgs)
127 MIB.addImm(DecArg);
128}
129
130voidbuildOpDecorate(RegisterReg,MachineIRBuilder &MIRBuilder,
131 SPIRV::Decoration::Decoration Dec,
132const std::vector<uint32_t> &DecArgs,StringRef StrImm) {
133auto MIB = MIRBuilder.buildInstr(SPIRV::OpDecorate)
134 .addUse(Reg)
135 .addImm(static_cast<uint32_t>(Dec));
136finishBuildOpDecorate(MIB, DecArgs, StrImm);
137}
138
139voidbuildOpDecorate(RegisterReg,MachineInstr &I,constSPIRVInstrInfo &TII,
140 SPIRV::Decoration::Decoration Dec,
141const std::vector<uint32_t> &DecArgs,StringRef StrImm) {
142MachineBasicBlock &MBB = *I.getParent();
143auto MIB =BuildMI(MBB,I,I.getDebugLoc(),TII.get(SPIRV::OpDecorate))
144 .addUse(Reg)
145 .addImm(static_cast<uint32_t>(Dec));
146finishBuildOpDecorate(MIB, DecArgs, StrImm);
147}
148
149voidbuildOpSpirvDecorations(RegisterReg,MachineIRBuilder &MIRBuilder,
150constMDNode *GVarMD) {
151for (unsignedI = 0,E = GVarMD->getNumOperands();I !=E; ++I) {
152auto *OpMD = dyn_cast<MDNode>(GVarMD->getOperand(I));
153if (!OpMD)
154report_fatal_error("Invalid decoration");
155if (OpMD->getNumOperands() == 0)
156report_fatal_error("Expect operand(s) of the decoration");
157ConstantInt *DecorationId =
158 mdconst::dyn_extract<ConstantInt>(OpMD->getOperand(0));
159if (!DecorationId)
160report_fatal_error("Expect SPIR-V <Decoration> operand to be the first "
161"element of the decoration");
162auto MIB = MIRBuilder.buildInstr(SPIRV::OpDecorate)
163 .addUse(Reg)
164 .addImm(static_cast<uint32_t>(DecorationId->getZExtValue()));
165for (unsigned OpI = 1, OpE = OpMD->getNumOperands(); OpI != OpE; ++OpI) {
166if (ConstantInt *OpV =
167 mdconst::dyn_extract<ConstantInt>(OpMD->getOperand(OpI)))
168 MIB.addImm(static_cast<uint32_t>(OpV->getZExtValue()));
169elseif (MDString *OpV = dyn_cast<MDString>(OpMD->getOperand(OpI)))
170addStringImm(OpV->getString(), MIB);
171else
172report_fatal_error("Unexpected operand of the decoration");
173 }
174 }
175}
176
177MachineBasicBlock::iteratorgetOpVariableMBBIt(MachineInstr &I) {
178MachineFunction *MF =I.getParent()->getParent();
179MachineBasicBlock *MBB = &MF->front();
180MachineBasicBlock::iterator It =MBB->SkipPHIsAndLabels(MBB->begin()),
181E =MBB->end();
182bool IsHeader =false;
183unsigned Opcode;
184for (; It !=E && It !=I; ++It) {
185 Opcode = It->getOpcode();
186if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
187 IsHeader =true;
188 }elseif (IsHeader &&
189 !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
190 ++It;
191break;
192 }
193 }
194return It;
195}
196
197MachineBasicBlock::iteratorgetInsertPtValidEnd(MachineBasicBlock *MBB) {
198MachineBasicBlock::iteratorI =MBB->end();
199if (I ==MBB->begin())
200returnI;
201 --I;
202while (I->isTerminator() ||I->isDebugValue()) {
203if (I ==MBB->begin())
204break;
205 --I;
206 }
207returnI;
208}
209
210SPIRV::StorageClass::StorageClass
211addressSpaceToStorageClass(unsigned AddrSpace,constSPIRVSubtarget &STI) {
212switch (AddrSpace) {
213case 0:
214return SPIRV::StorageClass::Function;
215case 1:
216return SPIRV::StorageClass::CrossWorkgroup;
217case 2:
218return SPIRV::StorageClass::UniformConstant;
219case 3:
220return SPIRV::StorageClass::Workgroup;
221case 4:
222return SPIRV::StorageClass::Generic;
223case 5:
224return STI.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
225 ? SPIRV::StorageClass::DeviceOnlyINTEL
226 : SPIRV::StorageClass::CrossWorkgroup;
227case 6:
228return STI.canUseExtension(SPIRV::Extension::SPV_INTEL_usm_storage_classes)
229 ? SPIRV::StorageClass::HostOnlyINTEL
230 : SPIRV::StorageClass::CrossWorkgroup;
231case 7:
232return SPIRV::StorageClass::Input;
233case 8:
234return SPIRV::StorageClass::Output;
235case 9:
236return SPIRV::StorageClass::CodeSectionINTEL;
237case 10:
238return SPIRV::StorageClass::Private;
239default:
240report_fatal_error("Unknown address space");
241 }
242}
243
244SPIRV::MemorySemantics::MemorySemantics
245getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC) {
246switch (SC) {
247case SPIRV::StorageClass::StorageBuffer:
248case SPIRV::StorageClass::Uniform:
249return SPIRV::MemorySemantics::UniformMemory;
250case SPIRV::StorageClass::Workgroup:
251return SPIRV::MemorySemantics::WorkgroupMemory;
252case SPIRV::StorageClass::CrossWorkgroup:
253return SPIRV::MemorySemantics::CrossWorkgroupMemory;
254case SPIRV::StorageClass::AtomicCounter:
255return SPIRV::MemorySemantics::AtomicCounterMemory;
256case SPIRV::StorageClass::Image:
257return SPIRV::MemorySemantics::ImageMemory;
258default:
259return SPIRV::MemorySemantics::None;
260 }
261}
262
263SPIRV::MemorySemantics::MemorySemanticsgetMemSemantics(AtomicOrdering Ord) {
264switch (Ord) {
265caseAtomicOrdering::Acquire:
266return SPIRV::MemorySemantics::Acquire;
267caseAtomicOrdering::Release:
268return SPIRV::MemorySemantics::Release;
269caseAtomicOrdering::AcquireRelease:
270return SPIRV::MemorySemantics::AcquireRelease;
271caseAtomicOrdering::SequentiallyConsistent:
272return SPIRV::MemorySemantics::SequentiallyConsistent;
273caseAtomicOrdering::Unordered:
274caseAtomicOrdering::Monotonic:
275caseAtomicOrdering::NotAtomic:
276return SPIRV::MemorySemantics::None;
277 }
278llvm_unreachable(nullptr);
279}
280
281SPIRV::Scope::ScopegetMemScope(LLVMContext &Ctx,SyncScope::ID Id) {
282// Named by
283// https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_scope_id.
284// We don't need aliases for Invocation and CrossDevice, as we already have
285// them covered by "singlethread" and "" strings respectively (see
286// implementation of LLVMContext::LLVMContext()).
287staticconstllvm::SyncScope::ID SubGroup =
288 Ctx.getOrInsertSyncScopeID("subgroup");
289staticconstllvm::SyncScope::ID WorkGroup =
290 Ctx.getOrInsertSyncScopeID("workgroup");
291staticconstllvm::SyncScope::ID Device =
292 Ctx.getOrInsertSyncScopeID("device");
293
294if (Id ==llvm::SyncScope::SingleThread)
295return SPIRV::Scope::Invocation;
296elseif (Id ==llvm::SyncScope::System)
297return SPIRV::Scope::CrossDevice;
298elseif (Id == SubGroup)
299return SPIRV::Scope::Subgroup;
300elseif (Id == WorkGroup)
301return SPIRV::Scope::Workgroup;
302elseif (Id == Device)
303return SPIRV::Scope::Device;
304return SPIRV::Scope::CrossDevice;
305}
306
307MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
308constMachineRegisterInfo *MRI) {
309MachineInstr *MI =MRI->getVRegDef(ConstReg);
310MachineInstr *ConstInstr =
311MI->getOpcode() == SPIRV::G_TRUNC ||MI->getOpcode() == SPIRV::G_ZEXT
312 ?MRI->getVRegDef(MI->getOperand(1).getReg())
313 :MI;
314if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
315if (GI->is(Intrinsic::spv_track_constant)) {
316 ConstReg = ConstInstr->getOperand(2).getReg();
317returnMRI->getVRegDef(ConstReg);
318 }
319 }elseif (ConstInstr->getOpcode() == SPIRV::ASSIGN_TYPE) {
320 ConstReg = ConstInstr->getOperand(1).getReg();
321returnMRI->getVRegDef(ConstReg);
322 }
323returnMRI->getVRegDef(ConstReg);
324}
325
326uint64_tgetIConstVal(Register ConstReg,constMachineRegisterInfo *MRI) {
327constMachineInstr *MI =getDefInstrMaybeConstant(ConstReg,MRI);
328assert(MI &&MI->getOpcode() == TargetOpcode::G_CONSTANT);
329returnMI->getOperand(1).getCImm()->getValue().getZExtValue();
330}
331
332boolisSpvIntrinsic(constMachineInstr &MI,Intrinsic::ID IntrinsicID) {
333if (constauto *GI = dyn_cast<GIntrinsic>(&MI))
334return GI->is(IntrinsicID);
335returnfalse;
336}
337
338Type *getMDOperandAsType(constMDNode *N,unsignedI) {
339Type *ElementTy = cast<ValueAsMetadata>(N->getOperand(I))->getType();
340returntoTypedPointer(ElementTy);
341}
342
343// The set of names is borrowed from the SPIR-V translator.
344// TODO: may be implemented in SPIRVBuiltins.td.
345staticboolisPipeOrAddressSpaceCastBI(constStringRef MangledName) {
346return MangledName =="write_pipe_2" || MangledName =="read_pipe_2" ||
347 MangledName =="write_pipe_2_bl" || MangledName =="read_pipe_2_bl" ||
348 MangledName =="write_pipe_4" || MangledName =="read_pipe_4" ||
349 MangledName =="reserve_write_pipe" ||
350 MangledName =="reserve_read_pipe" ||
351 MangledName =="commit_write_pipe" ||
352 MangledName =="commit_read_pipe" ||
353 MangledName =="work_group_reserve_write_pipe" ||
354 MangledName =="work_group_reserve_read_pipe" ||
355 MangledName =="work_group_commit_write_pipe" ||
356 MangledName =="work_group_commit_read_pipe" ||
357 MangledName =="get_pipe_num_packets_ro" ||
358 MangledName =="get_pipe_max_packets_ro" ||
359 MangledName =="get_pipe_num_packets_wo" ||
360 MangledName =="get_pipe_max_packets_wo" ||
361 MangledName =="sub_group_reserve_write_pipe" ||
362 MangledName =="sub_group_reserve_read_pipe" ||
363 MangledName =="sub_group_commit_write_pipe" ||
364 MangledName =="sub_group_commit_read_pipe" ||
365 MangledName =="to_global" || MangledName =="to_local" ||
366 MangledName =="to_private";
367}
368
369staticboolisEnqueueKernelBI(constStringRef MangledName) {
370return MangledName =="__enqueue_kernel_basic" ||
371 MangledName =="__enqueue_kernel_basic_events" ||
372 MangledName =="__enqueue_kernel_varargs" ||
373 MangledName =="__enqueue_kernel_events_varargs";
374}
375
376staticboolisKernelQueryBI(constStringRef MangledName) {
377return MangledName =="__get_kernel_work_group_size_impl" ||
378 MangledName =="__get_kernel_sub_group_count_for_ndrange_impl" ||
379 MangledName =="__get_kernel_max_sub_group_size_for_ndrange_impl" ||
380 MangledName =="__get_kernel_preferred_work_group_size_multiple_impl";
381}
382
383staticboolisNonMangledOCLBuiltin(StringRefName) {
384if (!Name.starts_with("__"))
385returnfalse;
386
387returnisEnqueueKernelBI(Name) ||isKernelQueryBI(Name) ||
388isPipeOrAddressSpaceCastBI(Name.drop_front(2)) ||
389Name =="__translate_sampler_initializer";
390}
391
392std::stringgetOclOrSpirvBuiltinDemangledName(StringRefName) {
393bool IsNonMangledOCL =isNonMangledOCLBuiltin(Name);
394bool IsNonMangledSPIRV =Name.starts_with("__spirv_");
395bool IsNonMangledHLSL =Name.starts_with("__hlsl_");
396bool IsMangled =Name.starts_with("_Z");
397
398// Otherwise use simple demangling to return the function name.
399if (IsNonMangledOCL || IsNonMangledSPIRV || IsNonMangledHLSL || !IsMangled)
400returnName.str();
401
402// Try to use the itanium demangler.
403if (char *DemangledName =itaniumDemangle(Name.data())) {
404 std::string Result = DemangledName;
405 free(DemangledName);
406return Result;
407 }
408
409// Autocheck C++, maybe need to do explicit check of the source language.
410// OpenCL C++ built-ins are declared in cl namespace.
411// TODO: consider using 'St' abbriviation for cl namespace mangling.
412// Similar to ::std:: in C++.
413size_t Start, Len = 0;
414size_t DemangledNameLenStart = 2;
415if (Name.starts_with("_ZN")) {
416// Skip CV and ref qualifiers.
417size_t NameSpaceStart =Name.find_first_not_of("rVKRO", 3);
418// All built-ins are in the ::cl:: namespace.
419if (Name.substr(NameSpaceStart, 11) !="2cl7__spirv")
420return std::string();
421 DemangledNameLenStart = NameSpaceStart + 11;
422 }
423 Start =Name.find_first_not_of("0123456789", DemangledNameLenStart);
424Name.substr(DemangledNameLenStart, Start - DemangledNameLenStart)
425 .getAsInteger(10, Len);
426returnName.substr(Start, Len).str();
427}
428
429boolhasBuiltinTypePrefix(StringRefName) {
430if (Name.starts_with("opencl.") ||Name.starts_with("ocl_") ||
431Name.starts_with("spirv."))
432returntrue;
433returnfalse;
434}
435
436boolisSpecialOpaqueType(constType *Ty) {
437if (constTargetExtType *ExtTy = dyn_cast<TargetExtType>(Ty))
438returnisTypedPointerWrapper(ExtTy)
439 ?false
440 :hasBuiltinTypePrefix(ExtTy->getName());
441
442returnfalse;
443}
444
445boolisEntryPoint(constFunction &F) {
446// OpenCL handling: any function with the SPIR_KERNEL
447// calling convention will be a potential entry point.
448if (F.getCallingConv() ==CallingConv::SPIR_KERNEL)
449returntrue;
450
451// HLSL handling: special attribute are emitted from the
452// front-end.
453if (F.getFnAttribute("hlsl.shader").isValid())
454returntrue;
455
456returnfalse;
457}
458
459Type *parseBasicTypeName(StringRef &TypeName,LLVMContext &Ctx) {
460 TypeName.consume_front("atomic_");
461if (TypeName.consume_front("void"))
462returnType::getVoidTy(Ctx);
463elseif (TypeName.consume_front("bool") || TypeName.consume_front("_Bool"))
464returnType::getIntNTy(Ctx, 1);
465elseif (TypeName.consume_front("char") ||
466 TypeName.consume_front("signed char") ||
467 TypeName.consume_front("unsigned char") ||
468 TypeName.consume_front("uchar"))
469returnType::getInt8Ty(Ctx);
470elseif (TypeName.consume_front("short") ||
471 TypeName.consume_front("signed short") ||
472 TypeName.consume_front("unsigned short") ||
473 TypeName.consume_front("ushort"))
474returnType::getInt16Ty(Ctx);
475elseif (TypeName.consume_front("int") ||
476 TypeName.consume_front("signed int") ||
477 TypeName.consume_front("unsigned int") ||
478 TypeName.consume_front("uint"))
479returnType::getInt32Ty(Ctx);
480elseif (TypeName.consume_front("long") ||
481 TypeName.consume_front("signed long") ||
482 TypeName.consume_front("unsigned long") ||
483 TypeName.consume_front("ulong"))
484returnType::getInt64Ty(Ctx);
485elseif (TypeName.consume_front("half") ||
486 TypeName.consume_front("_Float16") ||
487 TypeName.consume_front("__fp16"))
488returnType::getHalfTy(Ctx);
489elseif (TypeName.consume_front("float"))
490returnType::getFloatTy(Ctx);
491elseif (TypeName.consume_front("double"))
492returnType::getDoubleTy(Ctx);
493
494// Unable to recognize SPIRV type name
495returnnullptr;
496}
497
498std::unordered_set<BasicBlock *>
499PartialOrderingVisitor::getReachableFrom(BasicBlock *Start) {
500 std::queue<BasicBlock *> ToVisit;
501 ToVisit.push(Start);
502
503 std::unordered_set<BasicBlock *> Output;
504while (ToVisit.size() != 0) {
505 BasicBlock *BB = ToVisit.front();
506 ToVisit.pop();
507
508if (Output.count(BB) != 0)
509continue;
510 Output.insert(BB);
511
512for (BasicBlock *Successor :successors(BB)) {
513if (DT.dominates(Successor, BB))
514continue;
515 ToVisit.push(Successor);
516 }
517 }
518
519return Output;
520}
521
522bool PartialOrderingVisitor::CanBeVisited(BasicBlock *BB) const{
523for (BasicBlock *P :predecessors(BB)) {
524// Ignore back-edges.
525if (DT.dominates(BB,P))
526continue;
527
528// One of the predecessor hasn't been visited. Not ready yet.
529if (BlockToOrder.count(P) == 0)
530returnfalse;
531
532// If the block is a loop exit, the loop must be finished before
533// we can continue.
534 Loop *L = LI.getLoopFor(P);
535if (L ==nullptr ||L->contains(BB))
536continue;
537
538// SPIR-V requires a single back-edge. And the backend first
539// step transforms loops into the simplified format. If we have
540// more than 1 back-edge, something is wrong.
541assert(L->getNumBackEdges() <= 1);
542
543// If the loop has no latch, loop's rank won't matter, so we can
544// proceed.
545BasicBlock *Latch =L->getLoopLatch();
546assert(Latch);
547if (Latch ==nullptr)
548continue;
549
550// The latch is not ready yet, let's wait.
551if (BlockToOrder.count(Latch) == 0)
552returnfalse;
553 }
554
555returntrue;
556}
557
558size_tPartialOrderingVisitor::GetNodeRank(BasicBlock *BB) const{
559auto It = BlockToOrder.find(BB);
560if (It != BlockToOrder.end())
561return It->second.Rank;
562
563size_t result = 0;
564for (BasicBlock *P :predecessors(BB)) {
565// Ignore back-edges.
566if (DT.dominates(BB,P))
567continue;
568
569auto Iterator = BlockToOrder.end();
570Loop *L = LI.getLoopFor(P);
571BasicBlock *Latch = L ? L->getLoopLatch() :nullptr;
572
573// If the predecessor is either outside a loop, or part of
574// the same loop, simply take its rank + 1.
575if (L ==nullptr || L->contains(BB) || Latch ==nullptr) {
576 Iterator = BlockToOrder.find(P);
577 }else {
578// Otherwise, take the loop's rank (highest rank in the loop) as base.
579// Since loops have a single latch, highest rank is easy to find.
580// If the loop has no latch, then it doesn't matter.
581 Iterator = BlockToOrder.find(Latch);
582 }
583
584assert(Iterator != BlockToOrder.end());
585 result = std::max(result, Iterator->second.Rank + 1);
586 }
587
588return result;
589}
590
591size_t PartialOrderingVisitor::visit(BasicBlock *BB,size_t Unused) {
592 ToVisit.push(BB);
593 Queued.insert(BB);
594
595size_t QueueIndex = 0;
596while (ToVisit.size() != 0) {
597BasicBlock *BB = ToVisit.front();
598 ToVisit.pop();
599
600if (!CanBeVisited(BB)) {
601 ToVisit.push(BB);
602if (QueueIndex >= ToVisit.size())
603llvm::report_fatal_error(
604"No valid candidate in the queue. Is the graph reducible?");
605 QueueIndex++;
606continue;
607 }
608
609 QueueIndex = 0;
610size_t Rank =GetNodeRank(BB);
611 OrderInfoInfo = {Rank, BlockToOrder.size()};
612 BlockToOrder.emplace(BB,Info);
613
614for (BasicBlock *S :successors(BB)) {
615if (Queued.count(S) != 0)
616continue;
617 ToVisit.push(S);
618 Queued.insert(S);
619 }
620 }
621
622return 0;
623}
624
625PartialOrderingVisitor::PartialOrderingVisitor(Function &F) {
626 DT.recalculate(F);
627 LI =LoopInfo(DT);
628
629 visit(&*F.begin(), 0);
630
631 Order.reserve(F.size());
632for (auto &[BB,Info] : BlockToOrder)
633 Order.emplace_back(BB);
634
635 std::sort(Order.begin(), Order.end(), [&](constauto &LHS,constauto &RHS) {
636 return compare(LHS, RHS);
637 });
638}
639
640boolPartialOrderingVisitor::compare(constBasicBlock *LHS,
641constBasicBlock *RHS) const{
642const OrderInfo &InfoLHS = BlockToOrder.at(const_cast<BasicBlock *>(LHS));
643const OrderInfo &InfoRHS = BlockToOrder.at(const_cast<BasicBlock *>(RHS));
644if (InfoLHS.Rank != InfoRHS.Rank)
645return InfoLHS.Rank < InfoRHS.Rank;
646return InfoLHS.TraversalIndex < InfoRHS.TraversalIndex;
647}
648
649voidPartialOrderingVisitor::partialOrderVisit(
650BasicBlock &Start, std::function<bool(BasicBlock *)>Op) {
651 std::unordered_set<BasicBlock *> Reachable = getReachableFrom(&Start);
652assert(BlockToOrder.count(&Start) != 0);
653
654// Skipping blocks with a rank inferior to |Start|'s rank.
655auto It = Order.begin();
656while (It != Order.end() && *It != &Start)
657 ++It;
658
659// This is unexpected. Worst case |Start| is the last block,
660// so It should point to the last block, not past-end.
661assert(It != Order.end());
662
663// By default, there is no rank limit. Setting it to the maximum value.
664 std::optional<size_t> EndRank = std::nullopt;
665for (; It != Order.end(); ++It) {
666if (EndRank.has_value() && BlockToOrder[*It].Rank > *EndRank)
667break;
668
669if (Reachable.count(*It) == 0) {
670continue;
671 }
672
673if (!Op(*It)) {
674 EndRank = BlockToOrder[*It].Rank;
675 }
676 }
677}
678
679boolsortBlocks(Function &F) {
680if (F.size() == 0)
681returnfalse;
682
683boolModified =false;
684 std::vector<BasicBlock *> Order;
685 Order.reserve(F.size());
686
687ReversePostOrderTraversal<Function *> RPOT(&F);
688for (BasicBlock *BB : RPOT)
689 Order.push_back(BB);
690
691assert(&*F.begin() == Order[0]);
692BasicBlock *LastBlock = &*F.begin();
693for (BasicBlock *BB : Order) {
694if (BB != LastBlock && &*LastBlock->getNextNode() != BB) {
695Modified =true;
696 BB->moveAfter(LastBlock);
697 }
698 LastBlock = BB;
699 }
700
701returnModified;
702}
703
704MachineInstr *getVRegDef(MachineRegisterInfo &MRI,RegisterReg) {
705MachineInstr *MaybeDef =MRI.getVRegDef(Reg);
706if (MaybeDef && MaybeDef->getOpcode() == SPIRV::ASSIGN_TYPE)
707 MaybeDef =MRI.getVRegDef(MaybeDef->getOperand(1).getReg());
708return MaybeDef;
709}
710
711boolgetVacantFunctionName(Module &M, std::string &Name) {
712// It's a bit of paranoia, but still we don't want to have even a chance that
713// the loop will work for too long.
714constexprunsigned MaxIters = 1024;
715for (unsignedI = 0;I < MaxIters; ++I) {
716 std::string OrdName =Name +Twine(I).str();
717if (!M.getFunction(OrdName)) {
718Name = OrdName;
719returntrue;
720 }
721 }
722returnfalse;
723}
724
725// Assign SPIR-V type to the register. If the register has no valid assigned
726// class, set register LLT type and class according to the SPIR-V type.
727voidsetRegClassType(RegisterReg,SPIRVType *SpvType,SPIRVGlobalRegistry *GR,
728MachineRegisterInfo *MRI,constMachineFunction &MF,
729bool Force) {
730 GR->assignSPIRVTypeToVReg(SpvType,Reg, MF);
731if (!MRI->getRegClassOrNull(Reg) || Force) {
732MRI->setRegClass(Reg, GR->getRegClass(SpvType));
733MRI->setType(Reg, GR->getRegType(SpvType));
734 }
735}
736
737// Create a SPIR-V type, assign SPIR-V type to the register. If the register has
738// no valid assigned class, set register LLT type and class according to the
739// SPIR-V type.
740voidsetRegClassType(RegisterReg,constType *Ty,SPIRVGlobalRegistry *GR,
741MachineIRBuilder &MIRBuilder,bool Force) {
742setRegClassType(Reg, GR->getOrCreateSPIRVType(Ty, MIRBuilder), GR,
743 MIRBuilder.getMRI(), MIRBuilder.getMF(), Force);
744}
745
746// Create a virtual register and assign SPIR-V type to the register. Set
747// register LLT type and class according to the SPIR-V type.
748RegistercreateVirtualRegister(SPIRVType *SpvType,SPIRVGlobalRegistry *GR,
749MachineRegisterInfo *MRI,
750constMachineFunction &MF) {
751RegisterReg =MRI->createVirtualRegister(GR->getRegClass(SpvType));
752MRI->setType(Reg, GR->getRegType(SpvType));
753 GR->assignSPIRVTypeToVReg(SpvType,Reg, MF);
754returnReg;
755}
756
757// Create a virtual register and assign SPIR-V type to the register. Set
758// register LLT type and class according to the SPIR-V type.
759RegistercreateVirtualRegister(SPIRVType *SpvType,SPIRVGlobalRegistry *GR,
760MachineIRBuilder &MIRBuilder) {
761returncreateVirtualRegister(SpvType, GR, MIRBuilder.getMRI(),
762 MIRBuilder.getMF());
763}
764
765// Create a SPIR-V type, virtual register and assign SPIR-V type to the
766// register. Set register LLT type and class according to the SPIR-V type.
767RegistercreateVirtualRegister(constType *Ty,SPIRVGlobalRegistry *GR,
768MachineIRBuilder &MIRBuilder) {
769returncreateVirtualRegister(GR->getOrCreateSPIRVType(Ty, MIRBuilder), GR,
770 MIRBuilder);
771}
772
773// Return true if there is an opaque pointer type nested in the argument.
774boolisNestedPointer(constType *Ty) {
775if (Ty->isPtrOrPtrVectorTy())
776returntrue;
777if (constFunctionType *RefTy = dyn_cast<FunctionType>(Ty)) {
778if (isNestedPointer(RefTy->getReturnType()))
779returntrue;
780for (constType *ArgTy : RefTy->params())
781if (isNestedPointer(ArgTy))
782returntrue;
783returnfalse;
784 }
785if (constArrayType *RefTy = dyn_cast<ArrayType>(Ty))
786returnisNestedPointer(RefTy->getElementType());
787returnfalse;
788}
789
790boolisSpvIntrinsic(constValue *Arg) {
791if (constauto *II = dyn_cast<IntrinsicInst>(Arg))
792if (Function *F =II->getCalledFunction())
793if (F->getName().starts_with("llvm.spv."))
794returntrue;
795returnfalse;
796}
797
798}// namespace llvm
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
Demangle.h
Name
std::string Name
Definition:ELFObjHandler.cpp:77
GenericMachineInstrs.h
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
TII
const HexagonInstrInfo * TII
Definition:HexagonCopyToCombine.cpp:125
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
IntrinsicInst.h
LoopDeletionResult::Modified
@ Modified
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachineIRBuilder.h
This file declares the MachineIRBuilder class.
MachineInstrBuilder.h
MachineInstr.h
Reg
unsigned Reg
Definition:MachineSink.cpp:2028
II
uint64_t IntrinsicInst * II
Definition:NVVMIntrRange.cpp:51
P
#define P(N)
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SPIRVBaseInfo.h
SPIRVGlobalRegistry.h
SPIRVInstrInfo.h
SPIRVSubtarget.h
SPIRVUtils.h
SPIRV.h
StringRef.h
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
LHS
Value * LHS
Definition:X86PartialReduction.cpp:73
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::ArrayType
Class to represent array types.
Definition:DerivedTypes.h:395
llvm::BasicBlock
LLVM Basic Block Representation.
Definition:BasicBlock.h:61
llvm::BasicBlock::front
const Instruction & front() const
Definition:BasicBlock.h:474
llvm::BasicBlock::moveAfter
void moveAfter(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it right after MovePos in the function M...
Definition:BasicBlock.cpp:287
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::ConstantInt::getZExtValue
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition:Constants.h:157
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DominatorTreeBase::dominates
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
Definition:GenericDomTree.h:467
llvm::DominatorTreeBase::recalculate
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
Definition:GenericDomTree.h:859
llvm::FunctionType
Class to represent function types.
Definition:DerivedTypes.h:105
llvm::Function
Definition:Function.h:63
llvm::IRBuilder
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition:IRBuilder.h:2705
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::LLVMContext::getOrInsertSyncScopeID
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID.
Definition:LLVMContext.cpp:306
llvm::LoopInfoBase::getLoopFor
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Definition:GenericLoopInfo.h:606
llvm::LoopInfo
Definition:LoopInfo.h:407
llvm::Loop
Represents a single loop in the control flow graph.
Definition:LoopInfo.h:39
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition:MCInst.h:185
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition:MCInst.h:211
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition:MCInst.h:142
llvm::MDNode
Metadata node.
Definition:Metadata.h:1073
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition:Metadata.h:1434
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition:Metadata.h:1440
llvm::MDString
A single uniqued string.
Definition:Metadata.h:724
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::SkipPHIsAndLabels
iterator SkipPHIsAndLabels(iterator I)
Return the first instruction in MBB after I that is not a PHI or a label.
Definition:MachineBasicBlock.cpp:212
llvm::MachineBasicBlock::begin
iterator begin()
Definition:MachineBasicBlock.h:355
llvm::MachineBasicBlock::end
iterator end()
Definition:MachineBasicBlock.h:357
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::front
const MachineBasicBlock & front() const
Definition:MachineFunction.h:959
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition:MachineIRBuilder.h:235
llvm::MachineIRBuilder::buildInstr
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Definition:MachineIRBuilder.h:417
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition:MachineIRBuilder.h:287
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition:MachineIRBuilder.h:309
llvm::MachineInstrBuilder
Definition:MachineInstrBuilder.h:71
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition:MachineInstrBuilder.h:133
llvm::MachineInstrBuilder::addUse
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Definition:MachineInstrBuilder.h:125
llvm::MachineInstrBuilder::getInstr
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Definition:MachineInstrBuilder.h:91
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineInstr::getOpcode
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition:MachineInstr.h:577
llvm::MachineInstr::setAsmPrinterFlag
void setAsmPrinterFlag(uint8_t Flag)
Set a flag for the AsmPrinter.
Definition:MachineInstr.h:380
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition:MachineInstr.h:587
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition:MachineOperand.h:369
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition:MachineRegisterInfo.h:51
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition:Module.h:65
llvm::PartialOrderingVisitor::GetNodeRank
size_t GetNodeRank(BasicBlock *BB) const
Definition:SPIRVUtils.cpp:558
llvm::PartialOrderingVisitor::partialOrderVisit
void partialOrderVisit(BasicBlock &Start, std::function< bool(BasicBlock *)> Op)
Definition:SPIRVUtils.cpp:649
llvm::PartialOrderingVisitor::compare
bool compare(const BasicBlock *LHS, const BasicBlock *RHS) const
Definition:SPIRVUtils.cpp:640
llvm::PartialOrderingVisitor::PartialOrderingVisitor
PartialOrderingVisitor(Function &F)
Definition:SPIRVUtils.cpp:625
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::ReversePostOrderTraversal
Definition:PostOrderIterator.h:299
llvm::SPIRVGlobalRegistry
Definition:SPIRVGlobalRegistry.h:30
llvm::SPIRVGlobalRegistry::assignSPIRVTypeToVReg
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, const MachineFunction &MF)
Definition:SPIRVGlobalRegistry.cpp:82
llvm::SPIRVGlobalRegistry::getOrCreateSPIRVType
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
Definition:SPIRVGlobalRegistry.cpp:1125
llvm::SPIRVGlobalRegistry::getRegClass
const TargetRegisterClass * getRegClass(SPIRVType *SpvType) const
Definition:SPIRVGlobalRegistry.cpp:1654
llvm::SPIRVGlobalRegistry::getRegType
LLT getRegType(SPIRVType *SpvType) const
Definition:SPIRVGlobalRegistry.cpp:1680
llvm::SPIRVInstrInfo
Definition:SPIRVInstrInfo.h:24
llvm::SPIRVSubtarget
Definition:SPIRVSubtarget.h:38
llvm::SPIRVSubtarget::canUseExtension
bool canUseExtension(SPIRV::Extension::Extension E) const
Definition:SPIRVSubtarget.cpp:105
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::TargetExtType
Class to represent target extensions types, which are generally unintrospectable from target-independ...
Definition:DerivedTypes.h:744
llvm::Target
Target - Wrapper for Target specific information.
Definition:TargetRegistry.h:144
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Twine::str
std::string str() const
Return the twine contents as a std::string.
Definition:Twine.cpp:17
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::getHalfTy
static Type * getHalfTy(LLVMContext &C)
llvm::Type::getDoubleTy
static Type * getDoubleTy(LLVMContext &C)
llvm::Type::getIntNTy
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
llvm::Type::getInt16Ty
static IntegerType * getInt16Ty(LLVMContext &C)
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
llvm::Type::isPtrOrPtrVectorTy
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Definition:Type.h:267
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
llvm::Type::getFloatTy
static Type * getFloatTy(LLVMContext &C)
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::ilist_node_with_parent::getNextNode
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition:ilist_node.h:353
uint32_t
uint64_t
uint8_t
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
false
Definition:StackSlotColoring.cpp:193
llvm::CallingConv::SPIR_KERNEL
@ SPIR_KERNEL
Used for SPIR kernel functions.
Definition:CallingConv.h:144
llvm::ISD::BasicBlock
@ BasicBlock
Various leaf nodes.
Definition:ISDOpcodes.h:71
llvm::Intrinsic::ID
unsigned ID
Definition:GenericSSAContext.h:28
llvm::M68k::MemAddrModeKind::L
@ L
llvm::SPIRV::ASM_PRINTER_WIDTH16
@ ASM_PRINTER_WIDTH16
Definition:SPIRVInstrInfo.h:63
llvm::SyncScope::ID
uint8_t ID
Definition:LLVMContext.h:46
llvm::SyncScope::SingleThread
@ SingleThread
Synchronized with respect to signal handlers executing in the same thread.
Definition:LLVMContext.h:54
llvm::SyncScope::System
@ System
Synchronized with respect to all concurrently executing threads.
Definition:LLVMContext.h:57
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::buildOpName
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
Definition:SPIRVUtils.cpp:103
llvm::getVacantFunctionName
bool getVacantFunctionName(Module &M, std::string &Name)
Definition:SPIRVUtils.cpp:711
llvm::getStringImm
std::string getStringImm(const MachineInstr &MI, unsigned StartIndex)
Definition:SPIRVUtils.cpp:79
llvm::isTypedPointerWrapper
bool isTypedPointerWrapper(const TargetExtType *ExtTy)
Definition:SPIRVUtils.h:298
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition:MachineInstrBuilder.h:373
llvm::finishBuildOpDecorate
static void finishBuildOpDecorate(MachineInstrBuilder &MIB, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Definition:SPIRVUtils.cpp:121
llvm::Successor
@ Successor
Definition:SIMachineScheduler.h:35
llvm::convertCharsToWord
static uint32_t convertCharsToWord(const StringRef &Str, unsigned i)
Definition:SPIRVUtils.cpp:36
llvm::addNumImm
void addNumImm(const APInt &Imm, MachineInstrBuilder &MIB)
Definition:SPIRVUtils.cpp:83
llvm::successors
auto successors(const MachineBasicBlock *BB)
Definition:MachineBasicBlock.h:1376
llvm::sortBlocks
bool sortBlocks(Function &F)
Definition:SPIRVUtils.cpp:679
llvm::getIConstVal
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI)
Definition:SPIRVUtils.cpp:326
llvm::getMemSemanticsForStorageClass
SPIRV::MemorySemantics::MemorySemantics getMemSemanticsForStorageClass(SPIRV::StorageClass::StorageClass SC)
Definition:SPIRVUtils.cpp:245
llvm::isNestedPointer
bool isNestedPointer(const Type *Ty)
Definition:SPIRVUtils.cpp:774
llvm::getOclOrSpirvBuiltinDemangledName
std::string getOclOrSpirvBuiltinDemangledName(StringRef Name)
Definition:SPIRVUtils.cpp:392
llvm::buildOpDecorate
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, SPIRV::Decoration::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
Definition:SPIRVUtils.cpp:130
llvm::getOpVariableMBBIt
MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I)
Definition:SPIRVUtils.cpp:177
llvm::createVirtualRegister
Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
Definition:SPIRVUtils.cpp:748
llvm::getSPIRVStringOperand
std::string getSPIRVStringOperand(const InstType &MI, unsigned StartIndex)
Definition:SPIRVBaseInfo.h:260
llvm::toTypedPointer
Type * toTypedPointer(Type *Ty)
Definition:SPIRVUtils.h:353
llvm::itaniumDemangle
char * itaniumDemangle(std::string_view mangled_name, bool ParseParams=true)
Returns a non-NULL pointer to a NUL-terminated C style string that should be explicitly freed,...
Definition:ItaniumDemangle.cpp:369
llvm::isSpecialOpaqueType
bool isSpecialOpaqueType(const Type *Ty)
Definition:SPIRVUtils.cpp:436
llvm::setRegClassType
void setRegClassType(Register Reg, SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF, bool Force)
Definition:SPIRVUtils.cpp:727
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167
llvm::getInsertPtValidEnd
MachineBasicBlock::iterator getInsertPtValidEnd(MachineBasicBlock *MBB)
Definition:SPIRVUtils.cpp:197
llvm::isNonMangledOCLBuiltin
static bool isNonMangledOCLBuiltin(StringRef Name)
Definition:SPIRVUtils.cpp:383
llvm::isEntryPoint
bool isEntryPoint(const Function &F)
Definition:SPIRVUtils.cpp:445
llvm::addressSpaceToStorageClass
SPIRV::StorageClass::StorageClass addressSpaceToStorageClass(unsigned AddrSpace, const SPIRVSubtarget &STI)
Definition:SPIRVUtils.cpp:211
llvm::AtomicOrdering
AtomicOrdering
Atomic ordering for LLVM's memory model.
Definition:AtomicOrdering.h:56
llvm::AtomicOrdering::Monotonic
@ Monotonic
llvm::AtomicOrdering::Unordered
@ Unordered
llvm::AtomicOrdering::NotAtomic
@ NotAtomic
llvm::AtomicOrdering::AcquireRelease
@ AcquireRelease
llvm::AtomicOrdering::Acquire
@ Acquire
llvm::AtomicOrdering::Release
@ Release
llvm::AtomicOrdering::SequentiallyConsistent
@ SequentiallyConsistent
llvm::getMemScope
SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id)
Definition:SPIRVUtils.cpp:281
llvm::isPipeOrAddressSpaceCastBI
static bool isPipeOrAddressSpaceCastBI(const StringRef MangledName)
Definition:SPIRVUtils.cpp:345
llvm::parseBasicTypeName
Type * parseBasicTypeName(StringRef &TypeName, LLVMContext &Ctx)
Definition:SPIRVUtils.cpp:459
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::getDefInstrMaybeConstant
MachineInstr * getDefInstrMaybeConstant(Register &ConstReg, const MachineRegisterInfo *MRI)
Definition:SPIRVUtils.cpp:307
llvm::hasBuiltinTypePrefix
bool hasBuiltinTypePrefix(StringRef Name)
Definition:SPIRVUtils.cpp:429
llvm::getMDOperandAsType
Type * getMDOperandAsType(const MDNode *N, unsigned I)
Definition:SPIRVUtils.cpp:338
llvm::predecessors
auto predecessors(const MachineBasicBlock *BB)
Definition:MachineBasicBlock.h:1377
llvm::getPaddedLen
static size_t getPaddedLen(const StringRef &Str)
Definition:SPIRVUtils.cpp:50
llvm::isSpvIntrinsic
bool isSpvIntrinsic(const MachineInstr &MI, Intrinsic::ID IntrinsicID)
Definition:SPIRVUtils.cpp:332
llvm::addStringImm
void addStringImm(const StringRef &Str, MCInst &Inst)
Definition:SPIRVUtils.cpp:54
llvm::isKernelQueryBI
static bool isKernelQueryBI(const StringRef MangledName)
Definition:SPIRVUtils.cpp:376
llvm::getVRegDef
MachineInstr * getVRegDef(MachineRegisterInfo &MRI, Register Reg)
Definition:SPIRVUtils.cpp:704
llvm::buildOpSpirvDecorations
void buildOpSpirvDecorations(Register Reg, MachineIRBuilder &MIRBuilder, const MDNode *GVarMD)
Definition:SPIRVUtils.cpp:149
llvm::isEnqueueKernelBI
static bool isEnqueueKernelBI(const StringRef MangledName)
Definition:SPIRVUtils.cpp:369
llvm::getMemSemantics
SPIRV::MemorySemantics::MemorySemantics getMemSemantics(AtomicOrdering Ord)
Definition:SPIRVUtils.cpp:263
N
#define N

Generated on Thu Jul 17 2025 15:38:08 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp