Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
SPIRVISelLowering.cpp
Go to the documentation of this file.
1//===- SPIRVISelLowering.cpp - SPIR-V DAG Lowering Impl ---------*- 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 implements the SPIRVTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SPIRVISelLowering.h"
14#include "SPIRV.h"
15#include "SPIRVInstrInfo.h"
16#include "SPIRVRegisterBankInfo.h"
17#include "SPIRVRegisterInfo.h"
18#include "SPIRVSubtarget.h"
19#include "SPIRVTargetMachine.h"
20#include "llvm/CodeGen/MachineInstrBuilder.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/IR/IntrinsicsSPIRV.h"
23
24#define DEBUG_TYPE "spirv-lower"
25
26using namespacellvm;
27
28unsignedSPIRVTargetLowering::getNumRegistersForCallingConv(
29LLVMContext &Context,CallingConv::IDCC,EVT VT) const{
30// This code avoids CallLowering fail inside getVectorTypeBreakdown
31// on v3i1 arguments. Maybe we need to return 1 for all types.
32// TODO: remove it once this case is supported by the default implementation.
33if (VT.isVector() && VT.getVectorNumElements() == 3 &&
34 (VT.getVectorElementType() == MVT::i1 ||
35 VT.getVectorElementType() == MVT::i8))
36return 1;
37if (!VT.isVector() && VT.isInteger() && VT.getSizeInBits() <= 64)
38return 1;
39returngetNumRegisters(Context, VT);
40}
41
42MVTSPIRVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
43CallingConv::IDCC,
44EVT VT) const{
45// This code avoids CallLowering fail inside getVectorTypeBreakdown
46// on v3i1 arguments. Maybe we need to return i32 for all types.
47// TODO: remove it once this case is supported by the default implementation.
48if (VT.isVector() && VT.getVectorNumElements() == 3) {
49if (VT.getVectorElementType() == MVT::i1)
50return MVT::v4i1;
51elseif (VT.getVectorElementType() == MVT::i8)
52return MVT::v4i8;
53 }
54returngetRegisterType(Context, VT);
55}
56
57boolSPIRVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
58constCallInst &I,
59MachineFunction &MF,
60unsigned Intrinsic) const{
61unsigned AlignIdx = 3;
62switch (Intrinsic) {
63case Intrinsic::spv_load:
64 AlignIdx = 2;
65 [[fallthrough]];
66case Intrinsic::spv_store: {
67if (I.getNumOperands() >= AlignIdx + 1) {
68auto *AlignOp = cast<ConstantInt>(I.getOperand(AlignIdx));
69Info.align =Align(AlignOp->getZExtValue());
70 }
71Info.flags =static_cast<MachineMemOperand::Flags>(
72 cast<ConstantInt>(I.getOperand(AlignIdx - 1))->getZExtValue());
73Info.memVT = MVT::i64;
74// TODO: take into account opaque pointers (don't use getElementType).
75// MVT::getVT(PtrTy->getElementType());
76returntrue;
77break;
78 }
79default:
80break;
81 }
82returnfalse;
83}
84
85std::pair<unsigned, const TargetRegisterClass *>
86SPIRVTargetLowering::getRegForInlineAsmConstraint(constTargetRegisterInfo *TRI,
87StringRef Constraint,
88MVT VT) const{
89constTargetRegisterClass *RC =nullptr;
90if (Constraint.starts_with("{"))
91return std::make_pair(0u, RC);
92
93if (VT.isFloatingPoint())
94 RC = VT.isVector() ? &SPIRV::vfIDRegClass : &SPIRV::fIDRegClass;
95elseif (VT.isInteger())
96 RC = VT.isVector() ? &SPIRV::vIDRegClass : &SPIRV::iIDRegClass;
97else
98 RC = &SPIRV::iIDRegClass;
99
100return std::make_pair(0u, RC);
101}
102
103inlineRegistergetTypeReg(MachineRegisterInfo *MRI,Register OpReg) {
104SPIRVType *TypeInst =MRI->getVRegDef(OpReg);
105return TypeInst && TypeInst->getOpcode() == SPIRV::OpFunctionParameter
106 ? TypeInst->getOperand(1).getReg()
107 : OpReg;
108}
109
110staticvoiddoInsertBitcast(constSPIRVSubtarget &STI,MachineRegisterInfo *MRI,
111SPIRVGlobalRegistry &GR,MachineInstr &I,
112Register OpReg,unsigned OpIdx,
113SPIRVType *NewPtrType) {
114MachineIRBuilder MIB(I);
115Register NewReg =createVirtualRegister(NewPtrType, &GR,MRI, MIB.getMF());
116bool Res = MIB.buildInstr(SPIRV::OpBitcast)
117 .addDef(NewReg)
118 .addUse(GR.getSPIRVTypeID(NewPtrType))
119 .addUse(OpReg)
120 .constrainAllUses(*STI.getInstrInfo(), *STI.getRegisterInfo(),
121 *STI.getRegBankInfo());
122if (!Res)
123report_fatal_error("insert validation bitcast: cannot constrain all uses");
124I.getOperand(OpIdx).setReg(NewReg);
125}
126
127staticSPIRVType *createNewPtrType(SPIRVGlobalRegistry &GR,MachineInstr &I,
128SPIRVType *OpType,bool ReuseType,
129bool EmitIR,SPIRVType *ResType,
130constType *ResTy) {
131 SPIRV::StorageClass::StorageClass SC =
132static_cast<SPIRV::StorageClass::StorageClass>(
133 OpType->getOperand(1).getImm());
134MachineIRBuilder MIB(I);
135SPIRVType *NewBaseType =
136 ReuseType ? ResType
137 : GR.getOrCreateSPIRVType(
138 ResTy, MIB, SPIRV::AccessQualifier::ReadWrite, EmitIR);
139return GR.getOrCreateSPIRVPointerType(NewBaseType, MIB, SC);
140}
141
142// Insert a bitcast before the instruction to keep SPIR-V code valid
143// when there is a type mismatch between results and operand types.
144staticvoidvalidatePtrTypes(constSPIRVSubtarget &STI,
145MachineRegisterInfo *MRI,SPIRVGlobalRegistry &GR,
146MachineInstr &I,unsigned OpIdx,
147SPIRVType *ResType,constType *ResTy =nullptr) {
148// Get operand type
149MachineFunction *MF =I.getParent()->getParent();
150Register OpReg =I.getOperand(OpIdx).getReg();
151Register OpTypeReg =getTypeReg(MRI, OpReg);
152SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpTypeReg, MF);
153if (!ResType || !OpType || OpType->getOpcode() != SPIRV::OpTypePointer)
154return;
155// Get operand's pointee type
156Register ElemTypeReg = OpType->getOperand(2).getReg();
157SPIRVType *ElemType = GR.getSPIRVTypeForVReg(ElemTypeReg, MF);
158if (!ElemType)
159return;
160// Check if we need a bitcast to make a statement valid
161bool IsSameMF = MF == ResType->getParent()->getParent();
162bool IsEqualTypes = IsSameMF ? ElemType == ResType
163 : GR.getTypeForSPIRVType(ElemType) == ResTy;
164if (IsEqualTypes)
165return;
166// There is a type mismatch between results and operand types
167// and we insert a bitcast before the instruction to keep SPIR-V code valid
168SPIRVType *NewPtrType =
169createNewPtrType(GR,I, OpType, IsSameMF,false, ResType, ResTy);
170if (!GR.isBitcastCompatible(NewPtrType, OpType))
171report_fatal_error(
172"insert validation bitcast: incompatible result and operand types");
173doInsertBitcast(STI,MRI, GR,I, OpReg, OpIdx, NewPtrType);
174}
175
176// Insert a bitcast before OpGroupWaitEvents if the last argument is a pointer
177// that doesn't point to OpTypeEvent.
178staticvoidvalidateGroupWaitEventsPtr(constSPIRVSubtarget &STI,
179MachineRegisterInfo *MRI,
180SPIRVGlobalRegistry &GR,
181MachineInstr &I) {
182constexprunsigned OpIdx = 2;
183MachineFunction *MF =I.getParent()->getParent();
184Register OpReg =I.getOperand(OpIdx).getReg();
185Register OpTypeReg =getTypeReg(MRI, OpReg);
186SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpTypeReg, MF);
187if (!OpType || OpType->getOpcode() != SPIRV::OpTypePointer)
188return;
189SPIRVType *ElemType = GR.getSPIRVTypeForVReg(OpType->getOperand(2).getReg());
190if (!ElemType || ElemType->getOpcode() == SPIRV::OpTypeEvent)
191return;
192// Insert a bitcast before the instruction to keep SPIR-V code valid.
193LLVMContext &Context = MF->getFunction().getContext();
194SPIRVType *NewPtrType =
195createNewPtrType(GR,I, OpType,false,true,nullptr,
196TargetExtType::get(Context,"spirv.Event"));
197doInsertBitcast(STI,MRI, GR,I, OpReg, OpIdx, NewPtrType);
198}
199
200staticvoidvalidateLifetimeStart(constSPIRVSubtarget &STI,
201MachineRegisterInfo *MRI,
202SPIRVGlobalRegistry &GR,MachineInstr &I) {
203Register PtrReg =I.getOperand(0).getReg();
204MachineFunction *MF =I.getParent()->getParent();
205Register PtrTypeReg =getTypeReg(MRI, PtrReg);
206SPIRVType *PtrType = GR.getSPIRVTypeForVReg(PtrTypeReg, MF);
207SPIRVType *PonteeElemType = PtrType ? GR.getPointeeType(PtrType) :nullptr;
208if (!PonteeElemType || PonteeElemType->getOpcode() == SPIRV::OpTypeVoid ||
209 (PonteeElemType->getOpcode() == SPIRV::OpTypeInt &&
210 PonteeElemType->getOperand(1).getImm() == 8))
211return;
212// To keep the code valid a bitcast must be inserted
213 SPIRV::StorageClass::StorageClass SC =
214static_cast<SPIRV::StorageClass::StorageClass>(
215 PtrType->getOperand(1).getImm());
216MachineIRBuilder MIB(I);
217LLVMContext &Context = MF->getFunction().getContext();
218SPIRVType *ElemType =
219 GR.getOrCreateSPIRVType(IntegerType::getInt8Ty(Context), MIB);
220SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(ElemType, MIB, SC);
221doInsertBitcast(STI,MRI, GR,I, PtrReg, 0, NewPtrType);
222}
223
224staticvoidvalidatePtrUnwrapStructField(constSPIRVSubtarget &STI,
225MachineRegisterInfo *MRI,
226SPIRVGlobalRegistry &GR,
227MachineInstr &I,unsigned OpIdx) {
228MachineFunction *MF =I.getParent()->getParent();
229Register OpReg =I.getOperand(OpIdx).getReg();
230Register OpTypeReg =getTypeReg(MRI, OpReg);
231SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpTypeReg, MF);
232if (!OpType || OpType->getOpcode() != SPIRV::OpTypePointer)
233return;
234SPIRVType *ElemType = GR.getSPIRVTypeForVReg(OpType->getOperand(2).getReg());
235if (!ElemType || ElemType->getOpcode() != SPIRV::OpTypeStruct ||
236 ElemType->getNumOperands() != 2)
237return;
238// It's a structure-wrapper around another type with a single member field.
239SPIRVType *MemberType =
240 GR.getSPIRVTypeForVReg(ElemType->getOperand(1).getReg());
241if (!MemberType)
242return;
243unsigned MemberTypeOp = MemberType->getOpcode();
244if (MemberTypeOp != SPIRV::OpTypeVector && MemberTypeOp != SPIRV::OpTypeInt &&
245 MemberTypeOp != SPIRV::OpTypeFloat && MemberTypeOp != SPIRV::OpTypeBool)
246return;
247// It's a structure-wrapper around a valid type. Insert a bitcast before the
248// instruction to keep SPIR-V code valid.
249 SPIRV::StorageClass::StorageClass SC =
250static_cast<SPIRV::StorageClass::StorageClass>(
251 OpType->getOperand(1).getImm());
252MachineIRBuilder MIB(I);
253SPIRVType *NewPtrType = GR.getOrCreateSPIRVPointerType(MemberType, MIB, SC);
254doInsertBitcast(STI,MRI, GR,I, OpReg, OpIdx, NewPtrType);
255}
256
257// Insert a bitcast before the function call instruction to keep SPIR-V code
258// valid when there is a type mismatch between actual and expected types of an
259// argument:
260// %formal = OpFunctionParameter %formal_type
261// ...
262// %res = OpFunctionCall %ty %fun %actual ...
263// implies that %actual is of %formal_type, and in case of opaque pointers.
264// We may need to insert a bitcast to ensure this.
265voidvalidateFunCallMachineDef(constSPIRVSubtarget &STI,
266MachineRegisterInfo *DefMRI,
267MachineRegisterInfo *CallMRI,
268SPIRVGlobalRegistry &GR,MachineInstr &FunCall,
269MachineInstr *FunDef) {
270if (FunDef->getOpcode() != SPIRV::OpFunction)
271return;
272unsigned OpIdx = 3;
273for (FunDef = FunDef->getNextNode();
274 FunDef && FunDef->getOpcode() == SPIRV::OpFunctionParameter &&
275 OpIdx < FunCall.getNumOperands();
276 FunDef = FunDef->getNextNode(), OpIdx++) {
277SPIRVType *DefPtrType = DefMRI->getVRegDef(FunDef->getOperand(1).getReg());
278SPIRVType *DefElemType =
279 DefPtrType && DefPtrType->getOpcode() == SPIRV::OpTypePointer
280 ? GR.getSPIRVTypeForVReg(DefPtrType->getOperand(2).getReg(),
281 DefPtrType->getParent()->getParent())
282 :nullptr;
283if (DefElemType) {
284constType *DefElemTy = GR.getTypeForSPIRVType(DefElemType);
285// validatePtrTypes() works in the context if the call site
286// When we process historical records about forward calls
287// we need to switch context to the (forward) call site and
288// then restore it back to the current machine function.
289MachineFunction *CurMF =
290 GR.setCurrentFunc(*FunCall.getParent()->getParent());
291validatePtrTypes(STI, CallMRI, GR, FunCall, OpIdx, DefElemType,
292 DefElemTy);
293 GR.setCurrentFunc(*CurMF);
294 }
295 }
296}
297
298// Ensure there is no mismatch between actual and expected arg types: calls
299// with a processed definition. Return Function pointer if it's a forward
300// call (ahead of definition), and nullptr otherwise.
301constFunction *validateFunCall(constSPIRVSubtarget &STI,
302MachineRegisterInfo *CallMRI,
303SPIRVGlobalRegistry &GR,
304MachineInstr &FunCall) {
305constGlobalValue *GV = FunCall.getOperand(2).getGlobal();
306constFunction *F = dyn_cast<Function>(GV);
307MachineInstr *FunDef =
308const_cast<MachineInstr *>(GR.getFunctionDefinition(F));
309if (!FunDef)
310returnF;
311MachineRegisterInfo *DefMRI = &FunDef->getParent()->getParent()->getRegInfo();
312validateFunCallMachineDef(STI, DefMRI, CallMRI, GR, FunCall, FunDef);
313returnnullptr;
314}
315
316// Ensure there is no mismatch between actual and expected arg types: calls
317// ahead of a processed definition.
318voidvalidateForwardCalls(constSPIRVSubtarget &STI,
319MachineRegisterInfo *DefMRI,SPIRVGlobalRegistry &GR,
320MachineInstr &FunDef) {
321constFunction *F = GR.getFunctionByDefinition(&FunDef);
322if (SmallPtrSet<MachineInstr *, 8> *FwdCalls = GR.getForwardCalls(F))
323for (MachineInstr *FunCall : *FwdCalls) {
324MachineRegisterInfo *CallMRI =
325 &FunCall->getParent()->getParent()->getRegInfo();
326validateFunCallMachineDef(STI, DefMRI, CallMRI, GR, *FunCall, &FunDef);
327 }
328}
329
330// Validation of an access chain.
331voidvalidateAccessChain(constSPIRVSubtarget &STI,MachineRegisterInfo *MRI,
332SPIRVGlobalRegistry &GR,MachineInstr &I) {
333SPIRVType *BaseTypeInst = GR.getSPIRVTypeForVReg(I.getOperand(0).getReg());
334if (BaseTypeInst && BaseTypeInst->getOpcode() == SPIRV::OpTypePointer) {
335SPIRVType *BaseElemType =
336 GR.getSPIRVTypeForVReg(BaseTypeInst->getOperand(2).getReg());
337validatePtrTypes(STI,MRI, GR,I, 2, BaseElemType);
338 }
339}
340
341// TODO: the logic of inserting additional bitcast's is to be moved
342// to pre-IRTranslation passes eventually
343voidSPIRVTargetLowering::finalizeLowering(MachineFunction &MF) const{
344// finalizeLowering() is called twice (see GlobalISel/InstructionSelect.cpp)
345// We'd like to avoid the needless second processing pass.
346if (ProcessedMF.find(&MF) != ProcessedMF.end())
347return;
348
349MachineRegisterInfo *MRI = &MF.getRegInfo();
350SPIRVGlobalRegistry &GR = *STI.getSPIRVGlobalRegistry();
351 GR.setCurrentFunc(MF);
352for (MachineFunction::iteratorI = MF.begin(), E = MF.end();I != E; ++I) {
353MachineBasicBlock *MBB = &*I;
354SmallPtrSet<MachineInstr *, 8> ToMove;
355for (MachineBasicBlock::iteratorMBBI =MBB->begin(), MBBE =MBB->end();
356MBBI != MBBE;) {
357MachineInstr &MI = *MBBI++;
358switch (MI.getOpcode()) {
359case SPIRV::OpAtomicLoad:
360case SPIRV::OpAtomicExchange:
361case SPIRV::OpAtomicCompareExchange:
362case SPIRV::OpAtomicCompareExchangeWeak:
363case SPIRV::OpAtomicIIncrement:
364case SPIRV::OpAtomicIDecrement:
365case SPIRV::OpAtomicIAdd:
366case SPIRV::OpAtomicISub:
367case SPIRV::OpAtomicSMin:
368case SPIRV::OpAtomicUMin:
369case SPIRV::OpAtomicSMax:
370case SPIRV::OpAtomicUMax:
371case SPIRV::OpAtomicAnd:
372case SPIRV::OpAtomicOr:
373case SPIRV::OpAtomicXor:
374// for the above listed instructions
375// OpAtomicXXX <ResType>, ptr %Op, ...
376// implies that %Op is a pointer to <ResType>
377case SPIRV::OpLoad:
378// OpLoad <ResType>, ptr %Op implies that %Op is a pointer to <ResType>
379validatePtrTypes(STI,MRI, GR,MI, 2,
380 GR.getSPIRVTypeForVReg(MI.getOperand(0).getReg()));
381break;
382case SPIRV::OpAtomicStore:
383// OpAtomicStore ptr %Op, <Scope>, <Mem>, <Obj>
384// implies that %Op points to the <Obj>'s type
385validatePtrTypes(STI,MRI, GR,MI, 0,
386 GR.getSPIRVTypeForVReg(MI.getOperand(3).getReg()));
387break;
388case SPIRV::OpStore:
389// OpStore ptr %Op, <Obj> implies that %Op points to the <Obj>'s type
390validatePtrTypes(STI,MRI, GR,MI, 0,
391 GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg()));
392break;
393case SPIRV::OpPtrCastToGeneric:
394case SPIRV::OpGenericCastToPtr:
395validateAccessChain(STI,MRI, GR,MI);
396break;
397case SPIRV::OpPtrAccessChain:
398case SPIRV::OpInBoundsPtrAccessChain:
399if (MI.getNumOperands() == 4)
400validateAccessChain(STI,MRI, GR,MI);
401break;
402
403case SPIRV::OpFunctionCall:
404// ensure there is no mismatch between actual and expected arg types:
405// calls with a processed definition
406if (MI.getNumOperands() > 3)
407if (constFunction *F =validateFunCall(STI,MRI, GR,MI))
408 GR.addForwardCall(F, &MI);
409break;
410case SPIRV::OpFunction:
411// ensure there is no mismatch between actual and expected arg types:
412// calls ahead of a processed definition
413validateForwardCalls(STI,MRI, GR,MI);
414break;
415
416// ensure that LLVM IR add/sub instructions result in logical SPIR-V
417// instructions when applied to bool type
418case SPIRV::OpIAddS:
419case SPIRV::OpIAddV:
420case SPIRV::OpISubS:
421case SPIRV::OpISubV:
422if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
423 SPIRV::OpTypeBool))
424MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual));
425break;
426
427// ensure that LLVM IR bitwise instructions result in logical SPIR-V
428// instructions when applied to bool type
429case SPIRV::OpBitwiseOrS:
430case SPIRV::OpBitwiseOrV:
431if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
432 SPIRV::OpTypeBool))
433MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalOr));
434break;
435case SPIRV::OpBitwiseAndS:
436case SPIRV::OpBitwiseAndV:
437if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
438 SPIRV::OpTypeBool))
439MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalAnd));
440break;
441case SPIRV::OpBitwiseXorS:
442case SPIRV::OpBitwiseXorV:
443if (GR.isScalarOrVectorOfType(MI.getOperand(1).getReg(),
444 SPIRV::OpTypeBool))
445MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpLogicalNotEqual));
446break;
447case SPIRV::OpLifetimeStart:
448case SPIRV::OpLifetimeStop:
449if (MI.getOperand(1).getImm() > 0)
450validateLifetimeStart(STI,MRI, GR,MI);
451break;
452case SPIRV::OpGroupAsyncCopy:
453validatePtrUnwrapStructField(STI,MRI, GR,MI, 3);
454validatePtrUnwrapStructField(STI,MRI, GR,MI, 4);
455break;
456case SPIRV::OpGroupWaitEvents:
457// OpGroupWaitEvents ..., ..., <pointer to OpTypeEvent>
458validateGroupWaitEventsPtr(STI,MRI, GR,MI);
459break;
460case SPIRV::OpConstantI: {
461SPIRVType *Type = GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg());
462if (Type->getOpcode() != SPIRV::OpTypeInt &&MI.getOperand(2).isImm() &&
463MI.getOperand(2).getImm() == 0) {
464// Validate the null constant of a target extension type
465MI.setDesc(STI.getInstrInfo()->get(SPIRV::OpConstantNull));
466for (unsigned i =MI.getNumOperands() - 1; i > 1; --i)
467MI.removeOperand(i);
468 }
469 }break;
470case SPIRV::OpPhi: {
471// Phi refers to a type definition that goes after the Phi
472// instruction, so that the virtual register definition of the type
473// doesn't dominate all uses. Let's place the type definition
474// instruction at the end of the predecessor.
475MachineBasicBlock *Curr =MI.getParent();
476SPIRVType *Type = GR.getSPIRVTypeForVReg(MI.getOperand(1).getReg());
477if (Type->getParent() == Curr && !Curr->pred_empty())
478 ToMove.insert(const_cast<MachineInstr *>(Type));
479 }break;
480case SPIRV::OpExtInst: {
481// prefetch
482if (!MI.getOperand(2).isImm() || !MI.getOperand(3).isImm() ||
483MI.getOperand(2).getImm() != SPIRV::InstructionSet::OpenCL_std)
484continue;
485switch (MI.getOperand(3).getImm()) {
486case SPIRV::OpenCLExtInst::frexp:
487case SPIRV::OpenCLExtInst::lgamma_r:
488case SPIRV::OpenCLExtInst::remquo: {
489// The last operand must be of a pointer to i32 or vector of i32
490// values.
491MachineIRBuilder MIB(MI);
492SPIRVType *Int32Type = GR.getOrCreateSPIRVIntegerType(32, MIB);
493SPIRVType *RetType =MRI->getVRegDef(MI.getOperand(1).getReg());
494assert(RetType &&"Expected return type");
495validatePtrTypes(
496 STI,MRI, GR,MI,MI.getNumOperands() - 1,
497 RetType->getOpcode() != SPIRV::OpTypeVector
498 ? Int32Type
499 : GR.getOrCreateSPIRVVectorType(
500 Int32Type, RetType->getOperand(2).getImm(), MIB));
501 }break;
502case SPIRV::OpenCLExtInst::fract:
503case SPIRV::OpenCLExtInst::modf:
504case SPIRV::OpenCLExtInst::sincos:
505// The last operand must be of a pointer to the base type represented
506// by the previous operand.
507assert(MI.getOperand(MI.getNumOperands() - 2).isReg() &&
508"Expected v-reg");
509validatePtrTypes(
510 STI,MRI, GR,MI,MI.getNumOperands() - 1,
511 GR.getSPIRVTypeForVReg(
512MI.getOperand(MI.getNumOperands() - 2).getReg()));
513break;
514case SPIRV::OpenCLExtInst::prefetch:
515// Expected `ptr` type is a pointer to float, integer or vector, but
516// the pontee value can be wrapped into a struct.
517assert(MI.getOperand(MI.getNumOperands() - 2).isReg() &&
518"Expected v-reg");
519validatePtrUnwrapStructField(STI,MRI, GR,MI,
520MI.getNumOperands() - 2);
521break;
522 }
523 }break;
524 }
525 }
526for (MachineInstr *MI : ToMove) {
527MachineBasicBlock *Curr =MI->getParent();
528MachineBasicBlock *Pred = *Curr->pred_begin();
529 Pred->insert(Pred->getFirstTerminator(), Curr->remove_instr(MI));
530 }
531 }
532 ProcessedMF.insert(&MF);
533TargetLowering::finalizeLowering(MF);
534}
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition:ARMSLSHardening.cpp:72
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachineInstrBuilder.h
MachineRegisterInfo.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition:MachineSink.cpp:2029
CC
auto CC
Definition:RISCVRedundantCopyElimination.cpp:79
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
doInsertBitcast
static void doInsertBitcast(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I, Register OpReg, unsigned OpIdx, SPIRVType *NewPtrType)
Definition:SPIRVISelLowering.cpp:110
validateLifetimeStart
static void validateLifetimeStart(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I)
Definition:SPIRVISelLowering.cpp:200
validateGroupWaitEventsPtr
static void validateGroupWaitEventsPtr(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I)
Definition:SPIRVISelLowering.cpp:178
validatePtrUnwrapStructField
static void validatePtrUnwrapStructField(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I, unsigned OpIdx)
Definition:SPIRVISelLowering.cpp:224
getTypeReg
Register getTypeReg(MachineRegisterInfo *MRI, Register OpReg)
Definition:SPIRVISelLowering.cpp:103
validateAccessChain
void validateAccessChain(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I)
Definition:SPIRVISelLowering.cpp:331
validateFunCallMachineDef
void validateFunCallMachineDef(const SPIRVSubtarget &STI, MachineRegisterInfo *DefMRI, MachineRegisterInfo *CallMRI, SPIRVGlobalRegistry &GR, MachineInstr &FunCall, MachineInstr *FunDef)
Definition:SPIRVISelLowering.cpp:265
validateForwardCalls
void validateForwardCalls(const SPIRVSubtarget &STI, MachineRegisterInfo *DefMRI, SPIRVGlobalRegistry &GR, MachineInstr &FunDef)
Definition:SPIRVISelLowering.cpp:318
validateFunCall
const Function * validateFunCall(const SPIRVSubtarget &STI, MachineRegisterInfo *CallMRI, SPIRVGlobalRegistry &GR, MachineInstr &FunCall)
Definition:SPIRVISelLowering.cpp:301
validatePtrTypes
static void validatePtrTypes(const SPIRVSubtarget &STI, MachineRegisterInfo *MRI, SPIRVGlobalRegistry &GR, MachineInstr &I, unsigned OpIdx, SPIRVType *ResType, const Type *ResTy=nullptr)
Definition:SPIRVISelLowering.cpp:144
createNewPtrType
static SPIRVType * createNewPtrType(SPIRVGlobalRegistry &GR, MachineInstr &I, SPIRVType *OpType, bool ReuseType, bool EmitIR, SPIRVType *ResType, const Type *ResTy)
Definition:SPIRVISelLowering.cpp:127
SPIRVISelLowering.h
SPIRVInstrInfo.h
SPIRVRegisterBankInfo.h
SPIRVRegisterInfo.h
SPIRVSubtarget.h
SPIRVTargetMachine.h
SPIRV.h
T
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition:Instructions.h:1479
llvm::Function
Definition:Function.h:63
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition:Function.cpp:369
llvm::GlobalValue
Definition:GlobalValue.h:48
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition:LLVMContext.h:67
llvm::MVT
Machine Value Type.
Definition:MachineValueType.h:35
llvm::MVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition:MachineValueType.h:106
llvm::MVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition:MachineValueType.h:90
llvm::MVT::isFloatingPoint
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
Definition:MachineValueType.h:80
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::remove_instr
MachineInstr * remove_instr(MachineInstr *I)
Remove the possibly bundled instruction from the instruction list without deleting it.
Definition:MachineBasicBlock.cpp:1448
llvm::MachineBasicBlock::insert
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Definition:MachineBasicBlock.cpp:1456
llvm::MachineBasicBlock::getFirstTerminator
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Definition:MachineBasicBlock.cpp:244
llvm::MachineBasicBlock::pred_empty
bool pred_empty() const
Definition:MachineBasicBlock.h:420
llvm::MachineBasicBlock::begin
iterator begin()
Definition:MachineBasicBlock.h:355
llvm::MachineBasicBlock::pred_begin
pred_iterator pred_begin()
Definition:MachineBasicBlock.h:405
llvm::MachineBasicBlock::end
iterator end()
Definition:MachineBasicBlock.h:357
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition:MachineBasicBlock.h:311
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition:MachineFunction.h:743
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition:MachineFunction.h:704
llvm::MachineFunction::end
iterator end()
Definition:MachineFunction.h:949
llvm::MachineFunction::begin
iterator begin()
Definition:MachineFunction.h:947
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::MachineInstrBuilder::constrainAllUses
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Definition:MachineInstrBuilder.h:339
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::addDef
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Definition:MachineInstrBuilder.h:118
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::getParent
const MachineBasicBlock * getParent() const
Definition:MachineInstr.h:349
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition:MachineInstr.h:580
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition:MachineInstr.h:587
llvm::MachineMemOperand::Flags
Flags
Flags values. These may be or'd together.
Definition:MachineMemOperand.h:132
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition:MachineOperand.h:582
llvm::MachineOperand::getImm
int64_t getImm() const
Definition:MachineOperand.h:556
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::MachineRegisterInfo::getVRegDef
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Definition:MachineRegisterInfo.cpp:406
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::SPIRVGlobalRegistry
Definition:SPIRVGlobalRegistry.h:30
llvm::SPIRVGlobalRegistry::getSPIRVTypeForVReg
SPIRVType * getSPIRVTypeForVReg(Register VReg, const MachineFunction *MF=nullptr) const
Definition:SPIRVGlobalRegistry.cpp:1106
llvm::SPIRVGlobalRegistry::addForwardCall
void addForwardCall(const Function *F, MachineInstr *MI)
Definition:SPIRVGlobalRegistry.h:309
llvm::SPIRVGlobalRegistry::getTypeForSPIRVType
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
Definition:SPIRVGlobalRegistry.h:351
llvm::SPIRVGlobalRegistry::isBitcastCompatible
bool isBitcastCompatible(const SPIRVType *Type1, const SPIRVType *Type2) const
Definition:SPIRVGlobalRegistry.cpp:1269
llvm::SPIRVGlobalRegistry::getFunctionDefinition
const MachineInstr * getFunctionDefinition(const Function *F)
Definition:SPIRVGlobalRegistry.h:277
llvm::SPIRVGlobalRegistry::getPointeeType
SPIRVType * getPointeeType(SPIRVType *PtrType)
Definition:SPIRVGlobalRegistry.cpp:1258
llvm::SPIRVGlobalRegistry::getSPIRVTypeID
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
Definition:SPIRVGlobalRegistry.cpp:969
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::getForwardCalls
SmallPtrSet< MachineInstr *, 8 > * getForwardCalls(const Function *F)
Definition:SPIRVGlobalRegistry.h:315
llvm::SPIRVGlobalRegistry::isScalarOrVectorOfType
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
Definition:SPIRVGlobalRegistry.cpp:1171
llvm::SPIRVGlobalRegistry::setCurrentFunc
MachineFunction * setCurrentFunc(MachineFunction &MF)
Definition:SPIRVGlobalRegistry.h:391
llvm::SPIRVGlobalRegistry::getOrCreateSPIRVPointerType
SPIRVType * getOrCreateSPIRVPointerType(SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass::StorageClass SClass=SPIRV::StorageClass::Function)
Definition:SPIRVGlobalRegistry.cpp:1594
llvm::SPIRVGlobalRegistry::getOrCreateSPIRVVectorType
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder)
Definition:SPIRVGlobalRegistry.cpp:1550
llvm::SPIRVGlobalRegistry::getOrCreateSPIRVIntegerType
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
Definition:SPIRVGlobalRegistry.cpp:1466
llvm::SPIRVGlobalRegistry::getFunctionByDefinition
const Function * getFunctionByDefinition(const MachineInstr *MI)
Definition:SPIRVGlobalRegistry.h:286
llvm::SPIRVSubtarget
Definition:SPIRVSubtarget.h:38
llvm::SPIRVSubtarget::getInstrInfo
const SPIRVInstrInfo * getInstrInfo() const override
Definition:SPIRVSubtarget.h:118
llvm::SPIRVSubtarget::getSPIRVGlobalRegistry
SPIRVGlobalRegistry * getSPIRVGlobalRegistry() const
Definition:SPIRVSubtarget.h:101
llvm::SPIRVSubtarget::getRegisterInfo
const SPIRVRegisterInfo * getRegisterInfo() const override
Definition:SPIRVSubtarget.h:125
llvm::SPIRVSubtarget::getRegBankInfo
const RegisterBankInfo * getRegBankInfo() const override
Definition:SPIRVSubtarget.h:106
llvm::SPIRVTargetLowering::getNumRegisters
unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const override
Return the number of registers that this ValueType will eventually require.
Definition:SPIRVISelLowering.h:62
llvm::SPIRVTargetLowering::getNumRegistersForCallingConv
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
Definition:SPIRVISelLowering.cpp:28
llvm::SPIRVTargetLowering::getRegisterTypeForCallingConv
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
Definition:SPIRVISelLowering.cpp:42
llvm::SPIRVTargetLowering::getTgtMemIntrinsic
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
Definition:SPIRVISelLowering.cpp:57
llvm::SPIRVTargetLowering::finalizeLowering
void finalizeLowering(MachineFunction &MF) const override
Execute target specific actions to finalize target lowering.
Definition:SPIRVISelLowering.cpp:343
llvm::SPIRVTargetLowering::getRegForInlineAsmConstraint
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Definition:SPIRVISelLowering.cpp:86
llvm::SmallPtrSetImpl::insert
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition:SmallPtrSet.h:384
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition:SmallPtrSet.h:519
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::starts_with
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition:StringRef.h:265
llvm::TargetExtType::get
static TargetExtType * get(LLVMContext &Context, StringRef Name, ArrayRef< Type * > Types={}, ArrayRef< unsigned > Ints={})
Return a target extension type having the specified name and optional type and integer parameters.
Definition:Type.cpp:895
llvm::TargetLoweringBase::finalizeLowering
virtual void finalizeLowering(MachineFunction &MF) const
Execute target specific actions to finalize target lowering.
Definition:TargetLoweringBase.cpp:2246
llvm::TargetLoweringBase::getRegisterType
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
Definition:TargetLowering.h:1728
llvm::TargetRegisterClass
Definition:TargetRegisterInfo.h:44
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition:TargetRegisterInfo.h:235
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
llvm::ilist_node_with_parent::getNextNode
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition:ilist_node.h:353
unsigned
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::createVirtualRegister
Register createVirtualRegister(SPIRVType *SpvType, SPIRVGlobalRegistry *GR, MachineRegisterInfo *MRI, const MachineFunction &MF)
Definition:SPIRVUtils.cpp:748
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::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::EVT
Extended Value Type.
Definition:ValueTypes.h:35
llvm::EVT::getSizeInBits
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition:ValueTypes.h:368
llvm::EVT::isVector
bool isVector() const
Return true if this is a vector value type.
Definition:ValueTypes.h:168
llvm::EVT::getVectorElementType
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Definition:ValueTypes.h:323
llvm::EVT::getVectorNumElements
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition:ValueTypes.h:331
llvm::EVT::isInteger
bool isInteger() const
Return true if this is an integer or a vector integer type.
Definition:ValueTypes.h:152
llvm::TargetLoweringBase::IntrinsicInfo
Definition:TargetLowering.h:1202

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

©2009-2025 Movatter.jp