Go to the documentation of this file.
40 VRegToTypeMap[&MF][VReg] = SpirvType;
57 return MIRBuilder.
buildInstr(SPIRV::OpTypeBool)
64 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeInt)
73 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFloat)
80 return MIRBuilder.
buildInstr(SPIRV::OpTypeVoid)
88 assert((EleOpc == SPIRV::OpTypeInt || EleOpc == SPIRV::OpTypeFloat ||
89 EleOpc == SPIRV::OpTypeBool) &&
90 "Invalid vector element type");
92 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeVector)
103 auto &MF = MIRBuilder.
getMF();
111 const auto ConstInt =
121 .
addImm(ConstInt->getSExtValue());
128 auto &MF = MIRBuilder.
getMF();
130 const Type *LLVMFPTy;
151 bool IsInstSelector) {
154 GVar = cast<const GlobalVariable>(GV);
159 GVar =
M->getGlobalVariable(
Name);
160 if (GVar ==
nullptr) {
169 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpVariable)
180 if (IsInstSelector) {
183 *Subtarget.getRegisterInfo(),
184 *Subtarget.getRegBankInfo());
186 Reg = MIB->getOperand(0).getReg();
191 if (
Reg != ResVReg) {
222 "Invalid array element type");
225 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeArray)
235 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypePointer)
242 SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
245 auto MIB = MIRBuilder.
buildInstr(SPIRV::OpTypeFunction)
248 for (
const SPIRVType *ArgType : ArgTypes)
253 SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
const Type *Ty,
257 if (
auto IType = dyn_cast<IntegerType>(Ty)) {
258 const unsigned Width = IType->getBitWidth();
259 return Width == 1 ? getOpTypeBool(MIRBuilder)
265 return getOpTypeVoid(MIRBuilder);
269 return getOpTypeVector(cast<FixedVectorType>(Ty)->getNumElements(), El,
276 assert(!isa<StructType>(Ty) &&
"Unsupported StructType");
277 if (
auto FType = dyn_cast<FunctionType>(Ty)) {
280 for (
const auto &
t : FType->params()) {
283 return getOpTypeFunction(RetTy, ParamTypes, MIRBuilder);
285 if (
auto PType = dyn_cast<PointerType>(Ty)) {
290 if (PType->isOpaque()) {
293 Type *ElemType = PType->getNonOpaquePointerElementType();
296 assert(!isa<StructType>(ElemType) &&
"Unsupported StructType pointer");
303 return getOpTypePointer(
SC, SpvElementType, MIRBuilder);
309 auto t = VRegToTypeMap.find(
CurMF);
310 if (
t != VRegToTypeMap.end()) {
311 auto tt =
t->second.find(VReg);
312 if (tt !=
t->second.end())
321 SPIRVType *SpirvType = createSPIRVType(
Type, MIRBuilder, AccessQual, EmitIR);
323 SPIRVToLLVMType[SpirvType] =
Type;
328 unsigned TypeOpcode)
const {
330 assert(
Type &&
"isScalarOfType VReg has no type assigned");
331 return Type->getOpcode() == TypeOpcode;
335 unsigned TypeOpcode)
const {
337 assert(
Type &&
"isScalarOrVectorOfType VReg has no type assigned");
338 if (
Type->getOpcode() == TypeOpcode)
340 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
343 return ScalarType->
getOpcode() == TypeOpcode;
351 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
352 auto EleTypeReg =
Type->getOperand(1).getReg();
355 if (
Type->getOpcode() == SPIRV::OpTypeInt ||
356 Type->getOpcode() == SPIRV::OpTypeFloat)
357 return Type->getOperand(1).getImm();
358 if (
Type->getOpcode() == SPIRV::OpTypeBool)
365 if (
Type->getOpcode() == SPIRV::OpTypeVector) {
366 auto EleTypeReg =
Type->getOperand(1).getReg();
369 if (
Type->getOpcode() == SPIRV::OpTypeInt)
370 return Type->getOperand(2).getImm() != 0;
378 Type->getOperand(1).isImm() &&
"Pointer type is expected");
390 SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
Type *LLVMTy,
394 SPIRVToLLVMType[SpirvType] = LLVMTy;
402 auto MIB =
BuildMI(
BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypeInt))
406 return restOfCreateSPIRVType(LLVMTy, MIB);
430 auto MIB =
BuildMI(
BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypeVector))
434 return restOfCreateSPIRVType(LLVMTy, MIB);
454 auto MIB =
BuildMI(
BB,
I,
I.getDebugLoc(),
TII.get(SPIRV::OpTypePointer))
458 return restOfCreateSPIRVType(LLVMTy, MIB);
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
This is an optimization pass for GlobalISel generic memory operations.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
bool isScalarOrVectorOfType(Register VReg, unsigned TypeOpcode) const
bool isScalarOfType(Register VReg, unsigned TypeOpcode) const
SPIRVGlobalRegistry(unsigned PointerSize)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static Register createTypeVReg(MachineIRBuilder &MIRBuilder)
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MachineRegisterInfo * getMRI()
Getter for MRI.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
unsigned getScalarOrVectorBitWidth(const SPIRVType *Type) const
Reg
All possible values of the reg field in the ModR/M byte.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
The instances of the Type class are immutable: once they are created, they are never changed.
void assignSPIRVTypeToVReg(SPIRVType *Type, Register VReg, MachineFunction &MF)
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
bool isFloatingPointTy() const
Return true if this is one of the six floating-point types.
static IntegerType * getInt32Ty(LLVMContext &C)
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
SPIRVType * getSPIRVTypeForVReg(Register VReg) const
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType, StringRef Name, const GlobalValue *GV, SPIRV::StorageClass Storage, const MachineInstr *Init, bool IsConst, bool HasLinkageTy, SPIRV::LinkageType LinkageType, MachineIRBuilder &MIRBuilder, bool IsInstSelector)
const Type * getTypeForSPIRVType(const SPIRVType *Ty) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
bool isArrayTy() const
True if this is an instance of ArrayType.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr)
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
void setType(Register VReg, LLT Ty)
Set the low-level type of VReg to Ty.
constexpr char AccQual[]
Key for Kernel::Arg::Metadata::mAccQual.
bitcast float %x to i32 %s=and i32 %t, 2147483647 %d=bitcast i32 %s to float ret float %d } declare float @fabsf(float %n) define float @bar(float %x) nounwind { %d=call float @fabsf(float %x) ret float %d } This IR(from PR6194):target datalayout="e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple="x86_64-apple-darwin10.0.0" %0=type { double, double } %struct.float3=type { float, float, float } define void @test(%0, %struct.float3 *nocapture %res) nounwind noinline ssp { entry:%tmp18=extractvalue %0 %0, 0 t
bool isVectorTy() const
True if this is an instance of VectorType.
const HexagonInstrInfo * TII
Class to represent integer types.
MachineFunction & getMF()
Getter for the function we currently build.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
unsigned getAddressSpace() const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Type * getArrayElementType() const
SPIRV::StorageClass addressSpaceToStorageClass(unsigned AddrSpace)
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
Helper class to build MachineInstr.
Representation of each machine instruction.
Module * getParent()
Get the module that this global value is contained inside of...
unsigned storageClassToAddressSpace(SPIRV::StorageClass SC)
constexpr uint64_t PointerSize
x86_64 pointer size.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint64_t getArrayNumElements() const
bool isVoidTy() const
Return true if this is 'void'.
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
void buildOpDecorate(Register Reg, MachineIRBuilder &MIRBuilder, llvm::SPIRV::Decoration Dec, const std::vector< uint32_t > &DecArgs, StringRef StrImm)
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
A Module instance is used to store all the information related to an LLVM module.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
constexpr char IsConst[]
Key for Kernel::Arg::Metadata::mIsConst.
StringRef - Represent a constant reference to a string, i.e.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void buildOpName(Register Target, const StringRef &Name, MachineIRBuilder &MIRBuilder)
StringRef getName() const
Return a constant reference to the value's name.
SPIRVType * getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
SPIRVType * getOrCreateSPIRVPointerType(SPIRVType *BaseType, MachineIRBuilder &MIRBuilder, SPIRV::StorageClass SClass=SPIRV::StorageClass::Function)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Function & getFunction()
Return the LLVM function that this machine code represents.
uint64_t value() const
This is a hole in the type system and should not be abused.
SPIRVType * getOrCreateSPIRVIntegerType(unsigned BitWidth, MachineIRBuilder &MIRBuilder)
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
constexpr unsigned BitWidth
Register getSPIRVTypeID(const SPIRVType *SpirvType) const
@ ExternalLinkage
Externally visible function.
SPIRV::StorageClass getPointerStorageClass(Register VReg) const
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Register buildConstantInt(uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType=nullptr, bool EmitIR=true)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
SPIRVType * assignTypeToVReg(const Type *Type, Register VReg, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
SPIRVType * getOrCreateSPIRVType(const Type *Type, MachineIRBuilder &MIRBuilder, SPIRV::AccessQualifier AQ=SPIRV::AccessQualifier::ReadWrite, bool EmitIR=true)
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
bool isScalarOrVectorSigned(const SPIRVType *Type) const
SPIRVType * getOrCreateSPIRVVectorType(SPIRVType *BaseType, unsigned NumElements, MachineIRBuilder &MIRBuilder)
static Type * getFloatTy(LLVMContext &C)
void setRegClass(Register Reg, const TargetRegisterClass *RC)
setRegClass - Set the register class of the specified virtual register.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.