[llvm] [SPIR-V] Rework duplicate tracker and tracking of IR entities and types (PR #130605)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 14 10:41:43 PDT 2025
https://github.com/VyacheslavLevytskyy updated https://github.com/llvm/llvm-project/pull/130605
>From 33221a17e7e0d4a12249a248ccbbff0a7df02ae4 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 10 Mar 2025 06:46:43 -0700
Subject: [PATCH 1/9] remove spv_track_constant() intrnal intrinsics
---
llvm/include/llvm/IR/IntrinsicsSPIRV.td | 2 +-
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 9 +-
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 82 ++++++++++---------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 33 +++-----
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 19 ++---
5 files changed, 65 insertions(+), 80 deletions(-)
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 7012ef3534c68..89fb92be0e1eb 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -13,7 +13,7 @@
let TargetPrefix = "spv" in {
def int_spv_assign_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_assign_ptr_type : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty, llvm_i32_ty], [ImmArg<ArgIndex<2>>]>;
- def int_spv_assign_name : Intrinsic<[], [llvm_any_ty, llvm_vararg_ty]>;
+ def int_spv_assign_name : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_assign_decoration : Intrinsic<[], [llvm_any_ty, llvm_metadata_ty]>;
def int_spv_value_md : Intrinsic<[], [llvm_metadata_ty]>;
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index 579e37f68d5d8..f5c31ea737839 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -391,12 +391,9 @@ static MachineInstr *getBlockStructInstr(Register ParamReg,
// TODO: maybe unify with prelegalizer pass.
static unsigned getConstFromIntrinsic(Register Reg, MachineRegisterInfo *MRI) {
MachineInstr *DefMI = MRI->getUniqueVRegDef(Reg);
- assert(isSpvIntrinsic(*DefMI, Intrinsic::spv_track_constant) &&
- DefMI->getOperand(2).isReg());
- MachineInstr *DefMI2 = MRI->getUniqueVRegDef(DefMI->getOperand(2).getReg());
- assert(DefMI2->getOpcode() == TargetOpcode::G_CONSTANT &&
- DefMI2->getOperand(1).isCImm());
- return DefMI2->getOperand(1).getCImm()->getValue().getZExtValue();
+ assert(DefMI->getOpcode() == TargetOpcode::G_CONSTANT &&
+ DefMI->getOperand(1).isCImm());
+ return DefMI->getOperand(1).getCImm()->getValue().getZExtValue();
}
// Return type of the instruction result from spv_assign_type intrinsic.
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 751ea5ab2dc47..356f4f6dab75c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -63,7 +63,7 @@ class SPIRVEmitIntrinsics
SPIRVTargetMachine *TM = nullptr;
SPIRVGlobalRegistry *GR = nullptr;
Function *CurrF = nullptr;
- bool TrackConstants = true;
+ bool TrackConstants = false;//true;
bool HaveFunPtrs = false;
DenseMap<Instruction *, Constant *> AggrConsts;
DenseMap<Instruction *, Type *> AggrConstTypes;
@@ -316,8 +316,10 @@ static void emitAssignName(Instruction *I, IRBuilder<> &B) {
return;
reportFatalOnTokenType(I);
setInsertPointAfterDef(B, I);
- std::vector<Value *> Args = {I};
- addStringImm(I->getName(), B, Args);
+ LLVMContext &Ctx = I->getContext();
+ std::vector<Value *> Args = {
+ I, MetadataAsValue::get(
+ Ctx, MDNode::get(Ctx, MDString::get(Ctx, I->getName())))};
B.CreateIntrinsic(Intrinsic::spv_assign_name, {I->getType()}, Args);
}
@@ -2023,7 +2025,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
auto *II = dyn_cast<IntrinsicInst>(I);
bool IsConstComposite =
II && II->getIntrinsicID() == Intrinsic::spv_const_composite;
- if (IsConstComposite && TrackConstants) {
+ if (IsConstComposite) {
setInsertPointAfterDef(B, I);
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
@@ -2035,41 +2037,43 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
}
bool IsPhi = isa<PHINode>(I), BPrepared = false;
for (const auto &Op : I->operands()) {
- if (isa<PHINode>(I) || isa<SwitchInst>(I))
- TrackConstants = false;
- if ((isa<ConstantData>(Op) || isa<ConstantExpr>(Op)) && TrackConstants) {
- unsigned OpNo = Op.getOperandNo();
- if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
- (II->paramHasAttr(OpNo, Attribute::ImmArg))))
- continue;
- if (!BPrepared) {
- IsPhi ? B.SetInsertPointPastAllocas(I->getParent()->getParent())
- : B.SetInsertPoint(I);
- BPrepared = true;
- }
- Type *OpTy = Op->getType();
- Value *OpTyVal = Op;
- if (OpTy->isTargetExtTy())
- OpTyVal = getNormalizedPoisonValue(OpTy);
- CallInst *NewOp =
- buildIntrWithMD(Intrinsic::spv_track_constant,
- {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
- Type *OpElemTy = nullptr;
- if (!IsConstComposite && isPointerTy(OpTy) &&
- (OpElemTy = GR->findDeducedElementType(Op)) != nullptr &&
- OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
- GR->buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
- SmallVector<Type *, 2> Types = {OpTy, OpTy};
- SmallVector<Value *, 2> Args = {
- NewOp, buildMD(getNormalizedPoisonValue(OpElemTy)),
- B.getInt32(getPointerAddressSpace(OpTy))};
- CallInst *PtrCasted =
- B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
- GR->buildAssignPtr(B, OpElemTy, PtrCasted);
- NewOp = PtrCasted;
- }
- I->setOperand(OpNo, NewOp);
+ if (isa<PHINode>(I) || isa<SwitchInst>(I) ||
+ !(isa<ConstantData>(Op) || isa<ConstantExpr>(Op)))
+ continue;
+ unsigned OpNo = Op.getOperandNo();
+ if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
+ (II->paramHasAttr(OpNo, Attribute::ImmArg))))
+ continue;
+
+ if (!BPrepared) {
+ IsPhi ? B.SetInsertPointPastAllocas(I->getParent()->getParent())
+ : B.SetInsertPoint(I);
+ BPrepared = true;
}
+ Type *OpTy = Op->getType();
+ Value *OpTyVal = Op;
+ if (OpTy->isTargetExtTy())
+ OpTyVal = getNormalizedPoisonValue(OpTy);
+ Value *NewOp = Op;
+ if (OpTy->isTargetExtTy())
+ NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
+ {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
+ Type *OpElemTy = nullptr;
+ if (!IsConstComposite && isPointerTy(OpTy) &&
+ (OpElemTy = GR->findDeducedElementType(Op)) != nullptr &&
+ OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
+ GR->buildAssignPtr(B, IntegerType::getInt8Ty(I->getContext()), NewOp);
+ SmallVector<Type *, 2> Types = {OpTy, OpTy};
+ SmallVector<Value *, 2> Args = {
+ NewOp, buildMD(getNormalizedPoisonValue(OpElemTy)),
+ B.getInt32(getPointerAddressSpace(OpTy))};
+ CallInst *PtrCasted =
+ B.CreateIntrinsic(Intrinsic::spv_ptrcast, {Types}, Args);
+ GR->buildAssignPtr(B, OpElemTy, PtrCasted);
+ NewOp = PtrCasted;
+ }
+ if (NewOp != Op)
+ I->setOperand(OpNo, NewOp);
}
emitAssignName(I, B);
}
@@ -2417,7 +2421,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
deduceOperandElementType(&Phi, nullptr);
for (auto *I : Worklist) {
- TrackConstants = true;
+ TrackConstants = false;//true;
if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
setInsertPointAfterDef(B, I);
// Visitors return either the original/newly created instruction for further
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 3779a4b6ccd34..edf215f0ce00f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -133,32 +133,25 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
MI->eraseFromParent();
}
-static void
-foldConstantsIntoIntrinsics(MachineFunction &MF,
- const SmallSet<Register, 4> &TrackedConstRegs) {
- SmallVector<MachineInstr *, 10> ToErase;
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const unsigned AssignNameOperandShift = 2;
+static void foldConstantsIntoIntrinsics(MachineFunction &MF,
+ MachineIRBuilder MIB) {
+ SmallVector<MachineInstr *, 64> ToErase;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
if (!isSpvIntrinsic(MI, Intrinsic::spv_assign_name))
continue;
- unsigned NumOp = MI.getNumExplicitDefs() + AssignNameOperandShift;
- while (MI.getOperand(NumOp).isReg()) {
- MachineOperand &MOp = MI.getOperand(NumOp);
- MachineInstr *ConstMI = MRI.getVRegDef(MOp.getReg());
- assert(ConstMI->getOpcode() == TargetOpcode::G_CONSTANT);
- MI.removeOperand(NumOp);
- MI.addOperand(MachineOperand::CreateImm(
- ConstMI->getOperand(1).getCImm()->getZExtValue()));
- Register DefReg = ConstMI->getOperand(0).getReg();
- if (MRI.use_empty(DefReg) && !TrackedConstRegs.contains(DefReg))
- ToErase.push_back(ConstMI);
+ const MDNode *MD = MI.getOperand(2).getMetadata();
+ StringRef ValueName = cast<MDString>(MD->getOperand(0))->getString();
+ if (ValueName.size() > 0) {
+ MIB.setInsertPt(*MI.getParent(), MI);
+ buildOpName(MI.getOperand(1).getReg(), ValueName, MIB);
}
+ ToErase.push_back(&MI);
}
+ for (MachineInstr *MI : ToErase)
+ MI->eraseFromParent();
+ ToErase.clear();
}
- for (MachineInstr *MI : ToErase)
- MI->eraseFromParent();
}
static MachineInstr *findAssignTypeInstr(Register Reg,
@@ -1043,7 +1036,7 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
// to keep record of tracked constants
SmallSet<Register, 4> TrackedConstRegs;
addConstantsToTrack(MF, GR, ST, TargetExtConstTypes, TrackedConstRegs);
- foldConstantsIntoIntrinsics(MF, TrackedConstRegs);
+ foldConstantsIntoIntrinsics(MF, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index ce4f6d6c9288f..05bebb5a0e9c1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -307,20 +307,11 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
- MachineInstr *ConstInstr =
- MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT
- ? MRI->getVRegDef(MI->getOperand(1).getReg())
- : MI;
- if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
- if (GI->is(Intrinsic::spv_track_constant)) {
- ConstReg = ConstInstr->getOperand(2).getReg();
- return MRI->getVRegDef(ConstReg);
- }
- } else if (ConstInstr->getOpcode() == SPIRV::ASSIGN_TYPE) {
- ConstReg = ConstInstr->getOperand(1).getReg();
- return MRI->getVRegDef(ConstReg);
- }
- return MRI->getVRegDef(ConstReg);
+ if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
+ return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
+ return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ return MI;
}
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI) {
>From c2fcf6357b015fc1272d3658ca45db604fb9b19b Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Mon, 10 Mar 2025 11:39:29 -0700
Subject: [PATCH 2/9] fixes
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 5 ++-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 29 ++++++++---------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 3 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 11 +++++++
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 32 +++++++++++++++++--
.../test/CodeGen/SPIRV/SampledImageRetType.ll | 6 ++--
6 files changed, 60 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index f5c31ea737839..e6c0a526a9cec 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -1968,8 +1968,7 @@ static bool generateReadImageInst(const StringRef DemangledCall,
Sampler = GR->buildConstantSampler(
Register(), getSamplerAddressingModeFromBitmask(SamplerMask),
getSamplerParamFromBitmask(SamplerMask),
- getSamplerFilterModeFromBitmask(SamplerMask), MIRBuilder,
- GR->getSPIRVTypeForVReg(Sampler));
+ getSamplerFilterModeFromBitmask(SamplerMask), MIRBuilder);
}
SPIRVType *ImageType = GR->getSPIRVTypeForVReg(Image);
SPIRVType *SampledImageType =
@@ -2056,7 +2055,7 @@ static bool generateSampleImageInst(const StringRef DemangledCall,
Register Sampler = GR->buildConstantSampler(
Call->ReturnRegister, getSamplerAddressingModeFromBitmask(Bitmask),
getSamplerParamFromBitmask(Bitmask),
- getSamplerFilterModeFromBitmask(Bitmask), MIRBuilder, Call->ReturnType);
+ getSamplerFilterModeFromBitmask(Bitmask), MIRBuilder);
return Sampler.isValid();
} else if (Call->Builtin->Name.contains_insensitive("__spirv_SampledImage")) {
// Create OpSampledImage.
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index cbec1c95eadc3..fb718d9ddd0b4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -398,7 +398,9 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
SPIRV::AccessQualifier::ReadWrite, EmitIR);
DT.add(ConstInt, &MIRBuilder.getMF(), Res);
if (EmitIR) {
- MIRBuilder.buildConstant(Res, *ConstInt);
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildConstant(Res, *ConstInt);
+ });
} else {
Register SpvTypeReg = getSPIRVTypeID(SpvType);
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
@@ -605,7 +607,9 @@ Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
DT.add(CA, CurMF, SpvVecConst);
if (EmitIR) {
- MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
+ });
} else {
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
if (Val) {
@@ -668,17 +672,10 @@ SPIRVGlobalRegistry::getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
return Res;
}
-Register SPIRVGlobalRegistry::buildConstantSampler(
- Register ResReg, unsigned AddrMode, unsigned Param, unsigned FilerMode,
- MachineIRBuilder &MIRBuilder, SPIRVType *SpvType) {
- SPIRVType *SampTy;
- if (SpvType)
- SampTy = getOrCreateSPIRVType(getTypeForSPIRVType(SpvType), MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else if ((SampTy = getOrCreateSPIRVTypeByName("opencl.sampler_t", MIRBuilder,
- false)) == nullptr)
- report_fatal_error("Unable to recognize SPIRV type name: opencl.sampler_t");
-
+Register
+SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
+ unsigned Param, unsigned FilerMode,
+ MachineIRBuilder &MIRBuilder) {
auto Sampler =
ResReg.isValid()
? ResReg
@@ -686,7 +683,7 @@ Register SPIRVGlobalRegistry::buildConstantSampler(
auto Res = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
.addDef(Sampler)
- .addUse(getSPIRVTypeID(SampTy))
+ .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
.addImm(AddrMode)
.addImm(Param)
.addImm(FilerMode);
@@ -1383,7 +1380,9 @@ SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
return Res;
Register ResVReg = createTypeVReg(MIRBuilder);
DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 89599f17ef737..467d9b73e2e39 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -544,8 +544,7 @@ class SPIRVGlobalRegistry {
SPIRVType *SpvType);
Register buildConstantSampler(Register Res, unsigned AddrMode, unsigned Param,
unsigned FilerMode,
- MachineIRBuilder &MIRBuilder,
- SPIRVType *SpvType);
+ MachineIRBuilder &MIRBuilder);
Register getOrCreateUndef(MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII);
Register buildGlobalVariable(Register Reg, SPIRVType *BaseType,
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index b188f36ca9a9e..ce9ce3ef3135c 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -2326,6 +2326,17 @@ static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef,
return false;
}
return true;
+ case SPIRV::OpConstantTrue:
+ case SPIRV::OpConstantFalse:
+ case SPIRV::OpConstantI:
+ case SPIRV::OpConstantF:
+ case SPIRV::OpConstantComposite:
+ case SPIRV::OpConstantCompositeContinuedINTEL:
+ case SPIRV::OpConstantSampler:
+ case SPIRV::OpConstantNull:
+ case SPIRV::OpUndef:
+ case SPIRV::OpConstantFunctionPointerINTEL:
+ return true;
}
}
return false;
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 05bebb5a0e9c1..8380cd579004d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -303,16 +303,42 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
return SPIRV::Scope::Device;
return SPIRV::Scope::CrossDevice;
}
-
+/*
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
- if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
- return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ //if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
+ // return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
+ if (auto *GI = dyn_cast<GIntrinsic>(MI))
+ if (GI->is(Intrinsic::spv_track_constant))
+ return MRI->getVRegDef(ConstReg = MI->getOperand(2).getReg());
return MI;
}
+*/
+MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
+ const MachineRegisterInfo *MRI) {
+ MachineInstr *MI = MRI->getVRegDef(ConstReg);
+ MachineInstr *ConstInstr =
+ MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT
+ ? MRI->getVRegDef(MI->getOperand(1).getReg())
+ : MI;
+ if (auto *GI = dyn_cast<GIntrinsic>(ConstInstr)) {
+ if (GI->is(Intrinsic::spv_track_constant)) {
+ ConstReg = ConstInstr->getOperand(2).getReg();
+ return MRI->getVRegDef(ConstReg);
+ }
+ } else if (ConstInstr->getOpcode() == SPIRV::ASSIGN_TYPE) {
+ ConstReg = ConstInstr->getOperand(1).getReg();
+ return MRI->getVRegDef(ConstReg);
+ } else if (ConstInstr->getOpcode() == TargetOpcode::G_CONSTANT ||
+ ConstInstr->getOpcode() == TargetOpcode::G_FCONSTANT) {
+ ConstReg = ConstInstr->getOperand(0).getReg();
+ return ConstInstr;
+ }
+ return MRI->getVRegDef(ConstReg);
+}
uint64_t getIConstVal(Register ConstReg, const MachineRegisterInfo *MRI) {
const MachineInstr *MI = getDefInstrMaybeConstant(ConstReg, MRI);
diff --git a/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll b/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
index f034f293dc6a9..91f83e09c94f0 100644
--- a/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
+++ b/llvm/test/CodeGen/SPIRV/SampledImageRetType.ll
@@ -4,9 +4,9 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK: %[[#image1d_t:]] = OpTypeImage
-; CHECK: %[[#sampler_t:]] = OpTypeSampler
-; CHECK: %[[#sampled_image_t:]] = OpTypeSampledImage
+; CHECK-DAG: %[[#image1d_t:]] = OpTypeImage
+; CHECK-DAG: %[[#sampler_t:]] = OpTypeSampler
+; CHECK-DAG: %[[#sampled_image_t:]] = OpTypeSampledImage
declare dso_local spir_func ptr addrspace(4) @_Z20__spirv_SampledImageI14ocl_image1d_roPvET0_T_11ocl_sampler(target("spirv.Image", void, 0, 0, 0, 0, 0, 0, 0) %0, target("spirv.Sampler") %1) local_unnamed_addr
>From 663108c10f9fbd46075d1710dd0beb21a1918331 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 04:44:05 -0700
Subject: [PATCH 3/9] remove duplicate tracker
---
.../lib/Target/SPIRV/SPIRVDuplicatesTracker.h | 228 ++++-----------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 275 +++++++-----------
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 41 +--
3 files changed, 165 insertions(+), 379 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
index 441e32c1eb695..21e1069adb2d3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
@@ -26,35 +26,8 @@
namespace llvm {
namespace SPIRV {
-class SPIRVInstrInfo;
-// NOTE: using MapVector instead of DenseMap because it helps getting
-// everything ordered in a stable manner for a price of extra (NumKeys)*PtrSize
-// memory and expensive removals which do not happen anyway.
-class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
- SmallVector<DTSortableEntry *, 2> Deps;
- struct FlagsTy {
- unsigned IsFunc : 1;
- unsigned IsGV : 1;
- unsigned IsConst : 1;
- // NOTE: bit-field default init is a C++20 feature.
- FlagsTy() : IsFunc(0), IsGV(0), IsConst(0) {}
- };
- FlagsTy Flags;
-
-public:
- // Common hoisting utility doesn't support function, because their hoisting
- // require hoisting of params as well.
- bool getIsFunc() const { return Flags.IsFunc; }
- bool getIsGV() const { return Flags.IsGV; }
- bool getIsConst() const { return Flags.IsConst; }
- void setIsFunc(bool V) { Flags.IsFunc = V; }
- void setIsGV(bool V) { Flags.IsGV = V; }
- void setIsConst(bool V) { Flags.IsConst = V; }
-
- const SmallVector<DTSortableEntry *, 2> &getDeps() const { return Deps; }
- void addDep(DTSortableEntry *E) { Deps.push_back(E); }
-};
+using IRHandle = std::tuple<const void *, unsigned, unsigned>;
enum SpecialTypeKind {
STK_Empty = 0,
@@ -63,12 +36,11 @@ enum SpecialTypeKind {
STK_Sampler,
STK_Pipe,
STK_DeviceEvent,
+ STK_ElementPointer,
STK_Pointer,
STK_Last = -1
};
-using SpecialTypeDescriptor = std::tuple<const Type *, unsigned, unsigned>;
-
union ImageAttrs {
struct BitFlags {
unsigned Dim : 3;
@@ -94,18 +66,18 @@ union ImageAttrs {
}
};
-inline SpecialTypeDescriptor
-make_descr_image(const Type *SampledTy, unsigned Dim, unsigned Depth,
- unsigned Arrayed, unsigned MS, unsigned Sampled,
- unsigned ImageFormat, unsigned AQ = 0) {
+inline IRHandle make_descr_image(const Type *SampledTy, unsigned Dim,
+ unsigned Depth, unsigned Arrayed, unsigned MS,
+ unsigned Sampled, unsigned ImageFormat,
+ unsigned AQ = 0) {
return std::make_tuple(
SampledTy,
ImageAttrs(Dim, Depth, Arrayed, MS, Sampled, ImageFormat, AQ).Val,
SpecialTypeKind::STK_Image);
}
-inline SpecialTypeDescriptor
-make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy) {
+inline IRHandle make_descr_sampled_image(const Type *SampledTy,
+ const MachineInstr *ImageTy) {
assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
unsigned AC = AccessQualifier::AccessQualifier::None;
if (ImageTy->getNumOperands() > 8)
@@ -120,170 +92,84 @@ make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy) {
SpecialTypeKind::STK_SampledImage);
}
-inline SpecialTypeDescriptor make_descr_sampler() {
+inline IRHandle make_descr_sampler() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_Sampler);
}
-inline SpecialTypeDescriptor make_descr_pipe(uint8_t AQ) {
+inline IRHandle make_descr_pipe(uint8_t AQ) {
return std::make_tuple(nullptr, AQ, SpecialTypeKind::STK_Pipe);
}
-inline SpecialTypeDescriptor make_descr_event() {
+inline IRHandle make_descr_event() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_DeviceEvent);
}
-inline SpecialTypeDescriptor make_descr_pointee(const Type *ElementType,
- unsigned AddressSpace) {
+inline IRHandle make_descr_pointee(const Type *ElementType,
+ unsigned AddressSpace) {
return std::make_tuple(ElementType, AddressSpace,
- SpecialTypeKind::STK_Pointer);
+ SpecialTypeKind::STK_ElementPointer);
}
-} // namespace SPIRV
-template <typename KeyTy> class SPIRVDuplicatesTrackerBase {
-public:
- // NOTE: using MapVector instead of DenseMap helps getting everything ordered
- // in a stable manner for a price of extra (NumKeys)*PtrSize memory and
- // expensive removals which don't happen anyway.
- using StorageTy = MapVector<KeyTy, SPIRV::DTSortableEntry>;
+inline IRHandle make_descr_ptr(const void *Ptr) {
+ return std::make_tuple(Ptr, 0U, SpecialTypeKind::STK_Pointer);
+}
+} // namespace SPIRV
-private:
- StorageTy Storage;
+// Bi-directional mappings between LLVM entities and (v-reg, machine function)
+// pairs support management of unique SPIR-V definitions per machine function
+// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
+class SPIRVIRMap {
+ DenseMap < std::pair<IRHandle, const MachineFunction *>, Register >> Vregs;
+ DenseMap<const MachineInstr *, IRHandle> Defs;
public:
- void add(KeyTy V, const MachineFunction *MF, Register R) {
- if (find(V, MF).isValid())
- return;
-
- auto &S = Storage[V];
- S[MF] = R;
- if (std::is_same<Function,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>() ||
- std::is_same<Argument,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsFunc(true);
- if (std::is_same<GlobalVariable,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsGV(true);
- if (std::is_same<Constant,
- typename std::remove_const<
- typename std::remove_pointer<KeyTy>::type>::type>())
- S.setIsConst(true);
- }
-
- Register find(KeyTy V, const MachineFunction *MF) const {
- auto iter = Storage.find(V);
- if (iter != Storage.end()) {
- auto Map = iter->second;
- auto iter2 = Map.find(MF);
- if (iter2 != Map.end())
- return iter2->second;
+ bool add(IRHandle Handle, const MachineInstr *MI) {
+ auto [It, Inserted] =
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()));
+ if (Inserted) {
+ It->second = MI->getOperand(0).getReg();
+ auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
+ assert(IsConsistent);
}
- return Register();
- }
-
- const StorageTy &getAllUses() const { return Storage; }
-
-private:
- StorageTy &getAllUses() { return Storage; }
-
- // The friend class needs to have access to the internal storage
- // to be able to build dependency graph, can't declare only one
- // function a 'friend' due to the incomplete declaration at this point
- // and mutual dependency problems.
- friend class SPIRVGeneralDuplicatesTracker;
-};
-
-template <typename T>
-class SPIRVDuplicatesTracker : public SPIRVDuplicatesTrackerBase<const T *> {};
-
-template <>
-class SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor>
- : public SPIRVDuplicatesTrackerBase<SPIRV::SpecialTypeDescriptor> {};
-
-class SPIRVGeneralDuplicatesTracker {
- SPIRVDuplicatesTracker<Type> TT;
- SPIRVDuplicatesTracker<Constant> CT;
- SPIRVDuplicatesTracker<GlobalVariable> GT;
- SPIRVDuplicatesTracker<Function> FT;
- SPIRVDuplicatesTracker<Argument> AT;
- SPIRVDuplicatesTracker<MachineInstr> MT;
- SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor> ST;
-
-public:
- void add(const Type *Ty, const MachineFunction *MF, Register R) {
- TT.add(unifyPtrType(Ty), MF, R);
- }
-
- void add(const Type *PointeeTy, unsigned AddressSpace,
- const MachineFunction *MF, Register R) {
- ST.add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF,
- R);
+ return Inserted1;
}
-
- void add(const Constant *C, const MachineFunction *MF, Register R) {
- CT.add(C, MF, R);
+ bool erase(const MachineInstr *MI) {
+ bool Res = false;
+ if (auto It = Defs.find(MI); It != Defs.end()) {
+ Res = Vregs.erase(std::make_pair(It->second, MI->getMF()));
+ Defs.erase(It);
+ }
+ return Res;
}
-
- void add(const GlobalVariable *GV, const MachineFunction *MF, Register R) {
- GT.add(GV, MF, R);
+ Register find(IRHandle Handle, const MachineFunction *MF) {
+ if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
+ return It->second;
+ return Register();
}
- void add(const Function *F, const MachineFunction *MF, Register R) {
- FT.add(F, MF, R);
+ // helpers
+ bool add(const Type *Ty, const MachineInstr *MI) {
+ return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
}
-
- void add(const Argument *Arg, const MachineFunction *MF, Register R) {
- AT.add(Arg, MF, R);
+ void add(const void *Key, const MachineInstr *MI) {
+ return add(SPIRV::make_descr_ptr(Key), MI);
}
-
- void add(const MachineInstr *MI, const MachineFunction *MF, Register R) {
- MT.add(MI, MF, R);
+ bool add(const Type *PointeeTy, unsigned AddressSpace,
+ const MachineInstr *MI) {
+ return add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace),
+ MI);
}
-
- void add(const SPIRV::SpecialTypeDescriptor &TD, const MachineFunction *MF,
- Register R) {
- ST.add(TD, MF, R);
- }
-
Register find(const Type *Ty, const MachineFunction *MF) {
- return TT.find(unifyPtrType(Ty), MF);
+ return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
+ }
+ Register find(const void *Key, const MachineFunction *MF) {
+ return find(SPIRV::make_descr_ptr(Key), MF);
}
-
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return ST.find(
+ return find(
SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
}
-
- Register find(const Constant *C, const MachineFunction *MF) {
- return CT.find(const_cast<Constant *>(C), MF);
- }
-
- Register find(const GlobalVariable *GV, const MachineFunction *MF) {
- return GT.find(const_cast<GlobalVariable *>(GV), MF);
- }
-
- Register find(const Function *F, const MachineFunction *MF) {
- return FT.find(const_cast<Function *>(F), MF);
- }
-
- Register find(const Argument *Arg, const MachineFunction *MF) {
- return AT.find(const_cast<Argument *>(Arg), MF);
- }
-
- Register find(const MachineInstr *MI, const MachineFunction *MF) {
- return MT.find(const_cast<MachineInstr *>(MI), MF);
- }
-
- Register find(const SPIRV::SpecialTypeDescriptor &TD,
- const MachineFunction *MF) {
- return ST.find(TD, MF);
- }
-
- const SPIRVDuplicatesTracker<Type> *getTypes() { return &TT; }
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index fb718d9ddd0b4..c897026dc2426 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -181,7 +181,7 @@ void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
// - take into account duplicate tracker case which is a known issue,
// - review other data structure wrt. possible issues related to removal
// of a machine instruction during instruction selection.
- const MachineFunction *MF = MI->getParent()->getParent();
+ const MachineFunction *MF = MI->getMF();
auto It = LastInsertedTypeMap.find(MF);
if (It == LastInsertedTypeMap.end())
return;
@@ -245,98 +245,46 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeVector(uint32_t NumElems,
});
}
-std::tuple<Register, ConstantInt *, bool, unsigned>
-SPIRVGlobalRegistry::getOrCreateConstIntReg(uint64_t Val, SPIRVType *SpvType,
- MachineIRBuilder *MIRBuilder,
- MachineInstr *I,
- const SPIRVInstrInfo *TII) {
- assert(SpvType);
- const IntegerType *LLVMIntTy =
- cast<IntegerType>(getTypeForSPIRVType(SpvType));
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- bool NewInstr = false;
- // Find a constant in DT or build a new one.
- ConstantInt *CI = ConstantInt::get(const_cast<IntegerType *>(LLVMIntTy), Val);
- Register Res = DT.find(CI, CurMF);
- if (!Res.isValid()) {
- Res =
- CurMF->getRegInfo().createGenericVirtualRegister(LLT::scalar(BitWidth));
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
- if (MIRBuilder)
- assignTypeToVReg(LLVMIntTy, Res, *MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else
- assignIntTypeToVReg(BitWidth, Res, *I, *TII);
- DT.add(CI, CurMF, Res);
- NewInstr = true;
- }
- return std::make_tuple(Res, CI, NewInstr, BitWidth);
-}
-
-std::tuple<Register, ConstantFP *, bool, unsigned>
-SPIRVGlobalRegistry::getOrCreateConstFloatReg(APFloat Val, SPIRVType *SpvType,
- MachineIRBuilder *MIRBuilder,
- MachineInstr *I,
- const SPIRVInstrInfo *TII) {
- assert(SpvType);
- LLVMContext &Ctx = CurMF->getFunction().getContext();
- const Type *LLVMFloatTy = getTypeForSPIRVType(SpvType);
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- bool NewInstr = false;
- // Find a constant in DT or build a new one.
- auto *const CI = ConstantFP::get(Ctx, Val);
- Register Res = DT.find(CI, CurMF);
- if (!Res.isValid()) {
- Res =
- CurMF->getRegInfo().createGenericVirtualRegister(LLT::scalar(BitWidth));
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
- if (MIRBuilder)
- assignTypeToVReg(LLVMFloatTy, Res, *MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- else
- assignFloatTypeToVReg(BitWidth, Res, *I, *TII);
- DT.add(CI, CurMF, Res);
- NewInstr = true;
- }
- return std::make_tuple(Res, CI, NewInstr, BitWidth);
-}
-
Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- assert(SpvType);
- ConstantFP *CI;
- Register Res;
- bool New;
- unsigned BitWidth;
- std::tie(Res, CI, New, BitWidth) =
- getOrCreateConstFloatReg(Val, SpvType, nullptr, &I, &TII);
- // If we have found Res register which is defined by the passed G_CONSTANT
- // machine instruction, a new constant instruction should be created.
- if (!New && (!I.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ LLVMContext &Ctx = CurMF->getFunction().getContext();
+ auto *const CF = ConstantFP::get(Ctx, Val);
+ Register Res = find(CF, CurMF);
+ if (Res.isValid())
return Res;
+
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
+ assignFloatTypeToVReg(BitWidth, Res, I, TII);
+
MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- // In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
- if (Val.isPosZero() && ZeroAsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(
- APInt(BitWidth, CI->getValueAPF().bitcastToAPInt().getZExtValue()),
- MIB);
- }
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(
- *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
- return MIB;
- });
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ // In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
+ if (Val.isPosZero() && ZeroAsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(APInt(BitWidth,
+ CI->getValueAPF().bitcastToAPInt().getZExtValue()),
+ MIB);
+ }
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(CI, NewType);
return Res;
}
@@ -344,36 +292,37 @@ Register SPIRVGlobalRegistry::getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- assert(SpvType);
- ConstantInt *CI;
- Register Res;
- bool New;
- unsigned BitWidth;
- std::tie(Res, CI, New, BitWidth) =
- getOrCreateConstIntReg(Val, SpvType, nullptr, &I, &TII);
- // If we have found Res register which is defined by the passed G_CONSTANT
- // machine instruction, a new constant instruction should be created.
- if (!New && (!I.getOperand(0).isReg() || Res != I.getOperand(0).getReg()))
+ const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+ Register Res = find(CI, CurMF);
+ if (Res.isValid())
return Res;
-
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignIntTypeToVReg(BitWidth, Res, I, TII);
MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- if (Val || !ZeroAsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(APInt(BitWidth, Val), MIB);
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- }
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(
- *MIB, *ST.getInstrInfo(), *ST.getRegisterInfo(), *ST.getRegBankInfo());
- return MIB;
- });
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ if (Val || !ZeroAsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(APInt(BitWidth, Val), MIB);
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ }
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(CI, NewType);
return Res;
}
@@ -383,27 +332,24 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
bool ZeroAsNull) {
assert(SpvType);
auto &MF = MIRBuilder.getMF();
- const IntegerType *LLVMIntTy =
- cast<IntegerType>(getTypeForSPIRVType(SpvType));
- // Find a constant in DT or build a new one.
- const auto ConstInt =
- ConstantInt::get(const_cast<IntegerType *>(LLVMIntTy), Val);
- Register Res = DT.find(ConstInt, &MF);
- if (!Res.isValid()) {
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
- LLT LLTy = LLT::scalar(BitWidth);
- Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
- MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
- assignTypeToVReg(LLVMIntTy, Res, MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, EmitIR);
- DT.add(ConstInt, &MIRBuilder.getMF(), Res);
- if (EmitIR) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildConstant(Res, *ConstInt);
- });
- } else {
- Register SpvTypeReg = getSPIRVTypeID(SpvType);
+ const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
+ auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+ Register Res = find(CI, &MF);
+ if (Res.isValid())
+ return Res;
+
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
+ LLT LLTy = LLT::scalar(BitWidth);
+ Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
+ MF.getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignTypeToVReg(Ty, Res, MIRBuilder, SPIRV::AccessQualifier::ReadWrite,
+ EmitIR);
+
+ SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ if (EmitIR)
+ return MIRBuilder.buildConstant(Res, *CI);
+ Register SpvTypeReg = getSPIRVTypeID(SpvType);
MachineInstrBuilder MIB;
if (Val || !ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
@@ -421,8 +367,7 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
*Subtarget.getRegBankInfo());
return MIB;
});
- }
- }
+ add(ConstInt, NewType);
return Res;
}
@@ -430,31 +375,30 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val,
MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
auto &MF = MIRBuilder.getMF();
- auto &Ctx = MF.getFunction().getContext();
- if (!SpvType) {
- const Type *LLVMFPTy = Type::getFloatTy(Ctx);
- SpvType = getOrCreateSPIRVType(LLVMFPTy, MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
- }
- // Find a constant in DT or build a new one.
- const auto ConstFP = ConstantFP::get(Ctx, Val);
- Register Res = DT.find(ConstFP, &MF);
- if (!Res.isValid()) {
- Res = MF.getRegInfo().createGenericVirtualRegister(
- LLT::scalar(getScalarOrVectorBitWidth(SpvType)));
- MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
- assignSPIRVTypeToVReg(SpvType, Res, MF);
- DT.add(ConstFP, &MF, Res);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- addNumImm(ConstFP->getValueAPF().bitcastToAPInt(), MIB);
- return MIB;
- });
- }
+ if (!SpvType)
+ SpvType = getOrCreateSPIRVType(
+ Type::getFloatTy(MF.getFunction().getContext()), MIRBuilder,
+ SPIRV::AccessQualifier::ReadWrite, true);
+ auto *const CF = ConstantFP::get(Ctx, Val);
+ Register Res = find(CF, &MF);
+ if (Res.isValid())
+ return Res;
+ LLT LLTy = LLT::scalar(getScalarOrVectorBitWidth(SpvType));
+ Res = MF.getRegInfo().createGenericVirtualRegister(LLTy);
+ MF.getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, MF);
+
+ SPIRVType *NewType =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantF)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ addNumImm(CF->getValueAPF().bitcastToAPInt(), MIB);
+ return MIB;
+ });
+ add(CF, NewType);
return Res;
}
@@ -1044,13 +988,8 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
if (isSpecialOpaqueType(Ty))
return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
- auto &TypeToSPIRVTypeMap = DT.getTypes()->getAllUses();
- auto t = TypeToSPIRVTypeMap.find(Ty);
- if (t != TypeToSPIRVTypeMap.end()) {
- auto tt = t->second.find(&MIRBuilder.getMF());
- if (tt != t->second.end())
- return getSPIRVTypeForVReg(tt->second);
- }
+ if (Register TyReg = DT.find(Ty, &MIRBuilder.getMF()); TyReg.isValid())
+ return getSPIRVTypeForVReg(TyReg);
if (auto IType = dyn_cast<IntegerType>(Ty)) {
const unsigned Width = IType->getBitWidth();
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 467d9b73e2e39..8840401fe996d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -27,7 +27,7 @@ namespace llvm {
class SPIRVSubtarget;
using SPIRVType = const MachineInstr;
-class SPIRVGlobalRegistry {
+class SPIRVGlobalRegistry : public SPIRVIRMap {
// Registers holding values which have types associated with them.
// Initialized upon VReg definition in IRTranslator.
// Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
@@ -37,9 +37,6 @@ class SPIRVGlobalRegistry {
DenseMap<const MachineFunction *, DenseMap<Register, SPIRVType *>>
VRegToTypeMap;
- // Map LLVM Type* to <MF, Reg>
- SPIRVGeneralDuplicatesTracker DT;
-
DenseMap<SPIRVType *, const Type *> SPIRVToLLVMType;
// map a Function to its definition (as a machine instruction operand)
@@ -119,42 +116,6 @@ class SPIRVGlobalRegistry {
MachineFunction *CurMF;
- void add(const Constant *C, MachineFunction *MF, Register R) {
- DT.add(C, MF, R);
- }
-
- void add(const GlobalVariable *GV, MachineFunction *MF, Register R) {
- DT.add(GV, MF, R);
- }
-
- void add(const Function *F, MachineFunction *MF, Register R) {
- DT.add(F, MF, R);
- }
-
- void add(const Argument *Arg, MachineFunction *MF, Register R) {
- DT.add(Arg, MF, R);
- }
-
- void add(const MachineInstr *MI, MachineFunction *MF, Register R) {
- DT.add(MI, MF, R);
- }
-
- Register find(const MachineInstr *MI, MachineFunction *MF) {
- return DT.find(MI, MF);
- }
-
- Register find(const Constant *C, MachineFunction *MF) {
- return DT.find(C, MF);
- }
-
- Register find(const GlobalVariable *GV, MachineFunction *MF) {
- return DT.find(GV, MF);
- }
-
- Register find(const Function *F, MachineFunction *MF) {
- return DT.find(F, MF);
- }
-
void setBound(unsigned V) { Bound = V; }
unsigned getBound() { return Bound; }
>From 5da3d35fe0a1e8292f11f5746ad7c24697f0199e Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 05:37:03 -0700
Subject: [PATCH 4/9] add a new duplicate tracker
---
.../lib/Target/SPIRV/SPIRVDuplicatesTracker.h | 14 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 361 +++++++++---------
2 files changed, 192 insertions(+), 183 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
index 21e1069adb2d3..aa3171f3e7d10 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
@@ -119,15 +119,15 @@ inline IRHandle make_descr_ptr(const void *Ptr) {
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMap {
- DenseMap < std::pair<IRHandle, const MachineFunction *>, Register >> Vregs;
+ DenseMap < std::pair<IRHandle, const MachineFunction *>,
+ const MachineInstr *MI >> Vregs;
DenseMap<const MachineInstr *, IRHandle> Defs;
public:
bool add(IRHandle Handle, const MachineInstr *MI) {
auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()));
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
if (Inserted) {
- It->second = MI->getOperand(0).getReg();
auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
assert(IsConsistent);
}
@@ -141,10 +141,14 @@ class SPIRVIRMap {
}
return Res;
}
- Register find(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *findMI(IRHandle Handle, const MachineFunction *MF) {
if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
return It->second;
- return Register();
+ return nullptr;
+ }
+ Register find(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *MI = findMI(Handle, MF);
+ return MI ? MI->getOperand(0).getReg() : Register();
}
// helpers
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index c897026dc2426..c0735f380f82b 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -426,47 +426,42 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
Constant *Val, MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII, Constant *CA, unsigned BitWidth,
unsigned ElemCnt, bool ZeroAsNull) {
- // Find a constant vector or array in DT or build a new one.
- Register Res = DT.find(CA, CurMF);
- // If no values are attached, the composite is null constant.
+ if (Register R = find(CA, CurMF); R.isValid())
+ return R;
+
bool IsNull = Val->isNullValue() && ZeroAsNull;
- if (!Res.isValid()) {
- // SpvScalConst should be created before SpvVecConst to avoid undefined ID
- // error on validation.
- // TODO: can moved below once sorting of types/consts/defs is implemented.
- Register SpvScalConst;
- if (!IsNull)
- SpvScalConst =
- getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
-
- LLT LLTy = LLT::scalar(64);
- Register SpvVecConst =
- CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(SpvVecConst, getRegClass(SpvType));
- assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
- DT.add(CA, CurMF, SpvVecConst);
- MachineIRBuilder MIRBuilder(I);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- MachineInstrBuilder MIB;
- if (!IsNull) {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
- for (unsigned i = 0; i < ElemCnt; ++i)
- MIB.addUse(SpvScalConst);
- } else {
- MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
- }
- const auto &Subtarget = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
- *Subtarget.getRegisterInfo(),
- *Subtarget.getRegBankInfo());
- return MIB;
- });
- return SpvVecConst;
- }
+ Register ElemReg;
+ if (!IsNull)
+ ElemReg =
+ getOrCreateBaseRegister(Val, I, SpvType, TII, BitWidth, ZeroAsNull);
+
+ LLT LLTy = LLT::scalar(64);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, getRegClass(SpvType));
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ MachineIRBuilder MIRBuilder(I);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ MachineInstrBuilder MIB;
+ if (!IsNull) {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ for (unsigned i = 0; i < ElemCnt; ++i)
+ MIB.addUse(ElemReg);
+ } else {
+ MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ }
+ const auto &Subtarget = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *Subtarget.getInstrInfo(),
+ *Subtarget.getRegisterInfo(),
+ *Subtarget.getRegBankInfo());
+ return MIB;
+ });
+ add(CA, NewMI);
return Res;
}
@@ -536,42 +531,38 @@ Register SPIRVGlobalRegistry::getOrCreateConstIntArray(
Register SPIRVGlobalRegistry::getOrCreateIntCompositeOrNull(
uint64_t Val, MachineIRBuilder &MIRBuilder, SPIRVType *SpvType, bool EmitIR,
Constant *CA, unsigned BitWidth, unsigned ElemCnt) {
- Register Res = DT.find(CA, CurMF);
- if (!Res.isValid()) {
- Register SpvScalConst;
- if (Val || EmitIR) {
- SPIRVType *SpvBaseType =
- getOrCreateSPIRVIntegerType(BitWidth, MIRBuilder);
- SpvScalConst = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
- }
- LLT LLTy = EmitIR ? LLT::fixed_vector(ElemCnt, BitWidth) : LLT::scalar(64);
- Register SpvVecConst =
- CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(SpvVecConst, &SPIRV::iIDRegClass);
- assignSPIRVTypeToVReg(SpvType, SpvVecConst, *CurMF);
- DT.add(CA, CurMF, SpvVecConst);
- if (EmitIR) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildSplatBuildVector(SpvVecConst, SpvScalConst);
- });
- } else {
+ if (Register R = find(CA, CurMF); R.isValid())
+ return R;
+
+ Register ElemReg;
+ if (Val || EmitIR) {
+ SPIRVType *SpvBaseType = getOrCreateSPIRVIntegerType(BitWidth, MIRBuilder);
+ ElemReg = buildConstantInt(Val, MIRBuilder, SpvBaseType, EmitIR);
+ }
+ LLT LLTy = EmitIR ? LLT::fixed_vector(ElemCnt, BitWidth) : LLT::scalar(64);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ if (EmitIR)
+ return MIRBuilder.buildSplatBuildVector(Res, ElemReg);
+
if (Val) {
auto MIB = MIRBuilder.buildInstr(SPIRV::OpConstantComposite)
- .addDef(SpvVecConst)
+ .addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
for (unsigned i = 0; i < ElemCnt; ++i)
- MIB.addUse(SpvScalConst);
+ MIB.addUse(ElemReg);
return MIB;
- } else {
- return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(SpvVecConst)
- .addUse(getSPIRVTypeID(SpvType));
}
+
+ return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
});
- }
- return SpvVecConst;
- }
+ add(CA, NewMI);
return Res;
}
@@ -595,24 +586,26 @@ SPIRVGlobalRegistry::getOrCreateConsIntVector(uint64_t Val,
Register
SPIRVGlobalRegistry::getOrCreateConstNullPtr(MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
- const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- unsigned AddressSpace = typeToAddressSpace(LLVMTy);
- // Find a constant in DT or build a new one.
- Constant *CP = ConstantPointerNull::get(
- PointerType::get(LLVMTy->getContext(), AddressSpace));
- Register Res = DT.find(CP, CurMF);
- if (!Res.isValid()) {
- LLT LLTy = LLT::pointer(AddressSpace, PointerSize);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
- CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
- assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- });
- DT.add(CP, CurMF, Res);
- }
+ const Type *Ty = getTypeForSPIRVType(SpvType);
+ unsigned AddressSpace = typeToAddressSpace(Ty);
+ const Constant *CP = ConstantPointerNull::get(
+ PointerType::get(Ty->getContext(), AddressSpace));
+ Register Res = find(CP, CurMF);
+ if (Res.isValid())
+ return Res;
+
+ LLT LLTy = LLT::pointer(AddressSpace, PointerSize);
+ Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ CurMF->getRegInfo().setRegClass(Res, &SPIRV::pIDRegClass);
+ assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpConstantNull)
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ });
+ add(CP, NewMI);
return Res;
}
@@ -620,7 +613,10 @@ Register
SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
unsigned Param, unsigned FilerMode,
MachineIRBuilder &MIRBuilder) {
- auto Sampler =
+ Register Res = find(CP, CurMF);
+ if (Res.isValid())
+ return Res;
+auto Sampler =
ResReg.isValid()
? ResReg
: MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
@@ -1290,117 +1286,125 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
SPIRV::ImageFormat::ImageFormat ImageFormat,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto TD = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
- Depth, Arrayed, Multisampled, Sampled,
- ImageFormat, AccessQual);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeImage)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(SampledType))
- .addImm(Dim)
- .addImm(Depth) // Depth (whether or not it is a Depth image).
- .addImm(Arrayed) // Arrayed.
- .addImm(Multisampled) // Multisampled (0 = only single-sample).
- .addImm(Sampled) // Sampled (0 = usage known at runtime).
- .addImm(ImageFormat);
-
- if (AccessQual != SPIRV::AccessQualifier::None)
- MIB.addImm(AccessQual);
- return MIB;
+ auto Key = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
+ Depth, Arrayed, Multisampled, Sampled,
+ ImageFormat, AccessQual);
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB =
+ MIRBuilder.buildInstr(SPIRV::OpTypeImage)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(SampledType))
+ .addImm(Dim)
+ .addImm(Depth) // Depth (whether or not it is a Depth image).
+ .addImm(Arrayed) // Arrayed.
+ .addImm(Multisampled) // Multisampled (0 = only single-sample).
+ .addImm(Sampled) // Sampled (0 = usage known at runtime).
+ .addImm(ImageFormat);
+ if (AccessQual != SPIRV::AccessQualifier::None)
+ MIB.addImm(AccessQual);
+ return MIB;
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *
SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_sampler();
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampler).addDef(ResVReg);
- });
+ auto Key = SPIRV::make_descr_sampler();
+ const MachineFunction *MF = &MIRBuilder.getMF();
+ if (const MachineInstr *MI = findMI(Key, MF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampler)
+ .addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto TD = SPIRV::make_descr_pipe(AccessQual);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
- .addDef(ResVReg)
- .addImm(AccessQual);
+ auto Key = SPIRV::make_descr_pipe(AccessQual);
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypePipe)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addImm(AccessQual);
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_event();
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent).addDef(ResVReg);
+ auto Key = SPIRV::make_descr_event();
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeDeviceEvent)
+ .addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
SPIRVType *ImageType, MachineIRBuilder &MIRBuilder) {
- auto TD = SPIRV::make_descr_sampled_image(
+ auto Key = SPIRV::make_descr_sampled_image(
SPIRVToLLVMType.lookup(MIRBuilder.getMF().getRegInfo().getVRegDef(
ImageType->getOperand(1).getReg())),
ImageType);
- if (auto *Res = checkSpecialInstr(TD, MIRBuilder))
- return Res;
- Register ResVReg = createTypeVReg(MIRBuilder);
- DT.add(TD, &MIRBuilder.getMF(), ResVReg);
- return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(ImageType));
+ if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpTypeSampledImage)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(ImageType));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeCoopMatr(
MachineIRBuilder &MIRBuilder, const TargetExtType *ExtensionType,
const SPIRVType *ElemType, uint32_t Scope, uint32_t Rows, uint32_t Columns,
uint32_t Use, bool EmitIR) {
- Register ResVReg = DT.find(ExtensionType, &MIRBuilder.getMF());
- if (ResVReg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(ResVReg);
- ResVReg = createTypeVReg(MIRBuilder);
- SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
- SPIRVType *SpirvTy =
- MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
- .addDef(ResVReg)
- .addUse(getSPIRVTypeID(ElemType))
- .addUse(buildConstantInt(Scope, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Rows, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
- .addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
- DT.add(ExtensionType, &MIRBuilder.getMF(), ResVReg);
- return SpirvTy;
+ if (const MachineInstr *MI = findMI(ExtensionType, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, MIRBuilder);
+ return MIRBuilder.buildInstr(SPIRV::OpTypeCooperativeMatrixKHR)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(ElemType))
+ .addUse(buildConstantInt(Scope, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Rows, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
+ .addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
const Type *Ty, MachineIRBuilder &MIRBuilder, unsigned Opcode) {
- Register ResVReg = DT.find(Ty, &MIRBuilder.getMF());
- if (ResVReg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(ResVReg);
- ResVReg = createTypeVReg(MIRBuilder);
- SPIRVType *SpirvTy = MIRBuilder.buildInstr(Opcode).addDef(ResVReg);
- DT.add(Ty, &MIRBuilder.getMF(), ResVReg);
- return SpirvTy;
-}
-
-const MachineInstr *
-SPIRVGlobalRegistry::checkSpecialInstr(const SPIRV::SpecialTypeDescriptor &TD,
- MachineIRBuilder &MIRBuilder) {
- Register Reg = DT.find(TD, &MIRBuilder.getMF());
- if (Reg.isValid())
- return MIRBuilder.getMF().getRegInfo().getUniqueVRegDef(Reg);
- return nullptr;
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(Opcode).addDef(createTypeVReg(MIRBuilder));
+ });
+ add(Key, NewMI);
+ return NewMI;
}
// Returns nullptr if unable to recognize SPIRV type name
@@ -1470,16 +1474,17 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
MachineInstr &I,
const SPIRVInstrInfo &TII,
unsigned SPIRVOPcode,
- Type *LLVMTy) {
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRVOPcode))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addImm(BitWidth)
- .addImm(0);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
+ Type *Ty) {
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addImm(BitWidth)
+ .addImm(0);
+ });
+ add(LLVMTy, NewMI);
return finishCreatingSPIRVType(LLVMTy, MIB);
}
>From 1ab3c988c266a834074d227ebef17829cb47aff7 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 05:39:47 -0700
Subject: [PATCH 5/9] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 10 ++--------
.../{SPIRVDuplicatesTracker.h => SPIRVIRMapping.h} | 8 ++++----
2 files changed, 6 insertions(+), 12 deletions(-)
rename llvm/lib/Target/SPIRV/{SPIRVDuplicatesTracker.h => SPIRVIRMapping.h} (96%)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 8840401fe996d..6c2f08e315e3a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -17,7 +17,7 @@
#define LLVM_LIB_TARGET_SPIRV_SPIRVTYPEMANAGER_H
#include "MCTargetDesc/SPIRVBaseInfo.h"
-#include "SPIRVDuplicatesTracker.h"
+#include "SPIRVIRMapping.h"
#include "SPIRVInstrInfo.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/IR/Constant.h"
@@ -27,7 +27,7 @@ namespace llvm {
class SPIRVSubtarget;
using SPIRVType = const MachineInstr;
-class SPIRVGlobalRegistry : public SPIRVIRMap {
+class SPIRVGlobalRegistry : public SPIRVIRMapping {
// Registers holding values which have types associated with them.
// Initialized upon VReg definition in IRTranslator.
// Do not confuse this with DuplicatesTracker as DT maps Type* to <MF, Reg>
@@ -454,12 +454,6 @@ class SPIRVGlobalRegistry : public SPIRVIRMap {
getOrCreateSpecialType(const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccQual);
- std::tuple<Register, ConstantInt *, bool, unsigned> getOrCreateConstIntReg(
- uint64_t Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder,
- MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr);
- std::tuple<Register, ConstantFP *, bool, unsigned> getOrCreateConstFloatReg(
- APFloat Val, SPIRVType *SpvType, MachineIRBuilder *MIRBuilder,
- MachineInstr *I = nullptr, const SPIRVInstrInfo *TII = nullptr);
SPIRVType *finishCreatingSPIRVType(const Type *LLVMTy, SPIRVType *SpirvType);
Register getOrCreateBaseRegister(Constant *Val, MachineInstr &I,
SPIRVType *SpvType,
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
similarity index 96%
rename from llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
rename to llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index aa3171f3e7d10..248384e50eac1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
-#define LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
+#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
+#define LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
#include "MCTargetDesc/SPIRVBaseInfo.h"
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
@@ -118,7 +118,7 @@ inline IRHandle make_descr_ptr(const void *Ptr) {
// Bi-directional mappings between LLVM entities and (v-reg, machine function)
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
-class SPIRVIRMap {
+class SPIRVIRMapping {
DenseMap < std::pair<IRHandle, const MachineFunction *>,
const MachineInstr *MI >> Vregs;
DenseMap<const MachineInstr *, IRHandle> Defs;
@@ -176,4 +176,4 @@ class SPIRVIRMap {
}
};
} // namespace llvm
-#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
+#endif // LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
>From 27285488b0d8e25cc3e29b623d77a29e1b172917 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 07:03:18 -0700
Subject: [PATCH 6/9] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 299 +++++++++---------
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 4 +-
2 files changed, 148 insertions(+), 155 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index c0735f380f82b..69d707ca2ec15 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -613,23 +613,22 @@ Register
SPIRVGlobalRegistry::buildConstantSampler(Register ResReg, unsigned AddrMode,
unsigned Param, unsigned FilerMode,
MachineIRBuilder &MIRBuilder) {
- Register Res = find(CP, CurMF);
- if (Res.isValid())
- return Res;
-auto Sampler =
+ auto Sampler =
ResReg.isValid()
? ResReg
: MIRBuilder.getMRI()->createVirtualRegister(&SPIRV::iIDRegClass);
- auto Res = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
- .addDef(Sampler)
- .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
- .addImm(AddrMode)
- .addImm(Param)
- .addImm(FilerMode);
- });
- assert(Res->getOperand(0).isReg());
- return Res->getOperand(0).getReg();
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return MIRBuilder.buildInstr(SPIRV::OpConstantSampler)
+ .addDef(Sampler)
+ .addUse(getSPIRVTypeID(getOrCreateOpTypeSampler(MIRBuilder)))
+ .addImm(AddrMode)
+ .addImm(Param)
+ .addImm(FilerMode);
+ });
+ // TODO: this is a constant and it needs a usual control flow of add()/find()
+ // as other constants
+ return NewMI->getOperand(0).getReg();
}
Register SPIRVGlobalRegistry::buildGlobalVariable(
@@ -639,9 +638,9 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
SPIRV::LinkageType::LinkageType LinkageType, MachineIRBuilder &MIRBuilder,
bool IsInstSelector) {
const GlobalVariable *GVar = nullptr;
- if (GV)
+ if (GV) {
GVar = cast<const GlobalVariable>(GV);
- else {
+ } else {
// If GV is not passed explicitly, use the name to find or construct
// the global variable.
Module *M = MIRBuilder.getMF().getFunction().getParent();
@@ -655,7 +654,9 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
}
GV = GVar;
}
- Register Reg = DT.find(GVar, &MIRBuilder.getMF());
+
+ const MachineFunction *MF = &MIRBuilder.getMF();
+ Register Reg = find(GVar, MF);
if (Reg.isValid()) {
if (Reg != ResVReg)
MIRBuilder.buildCopy(ResVReg, Reg);
@@ -666,11 +667,8 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
.addDef(ResVReg)
.addUse(getSPIRVTypeID(BaseType))
.addImm(static_cast<uint32_t>(Storage));
-
- if (Init != 0) {
+ if (Init != 0)
MIB.addUse(Init->getOperand(0).getReg());
- }
-
// ISel may introduce a new register on this step, so we need to add it to
// DT and correct its type avoiding fails on the next stage.
if (IsInstSelector) {
@@ -679,9 +677,10 @@ Register SPIRVGlobalRegistry::buildGlobalVariable(
*Subtarget.getRegisterInfo(),
*Subtarget.getRegBankInfo());
}
+ add(GVar, MIB);
+
Reg = MIB->getOperand(0).getReg();
- DT.add(GVar, &MIRBuilder.getMF(), Reg);
- addGlobalObject(GVar, &MIRBuilder.getMF(), Reg);
+ addGlobalObject(GVar, MF, Reg);
// Set to Reg the same type as ResVReg has.
auto MRI = MIRBuilder.getMRI();
@@ -866,23 +865,18 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeStruct(
if (Ty->isPacked())
buildOpDecorate(ResVReg, MIRBuilder, SPIRV::Decoration::CPacked, {});
- auto SPVType = createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIBStruct = MIRBuilder.buildInstr(SPIRV::OpTypeStruct).addDef(ResVReg);
for (size_t I = 0; I < SPIRVStructNumElements; ++I)
- MIB.addUse(FieldTypes[I]);
- return MIB;
- });
-
- for (size_t I = SPIRVStructNumElements; I < NumElements;
- I += MaxNumElements) {
- createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
+ MIBStruct.addUse(FieldTypes[I]);
+ for (size_t I = SPIRVStructNumElements; I < NumElements;
+ I += MaxNumElements) {
+ auto MIBCont = MIRBuilder.buildInstr(SPIRV::OpTypeStructContinuedINTEL);
for (size_t J = I; J < std::min(I + MaxNumElements, NumElements); ++J)
- MIB.addUse(FieldTypes[I]);
- return MIB;
- });
- }
- return SPVType;
+ MIBCont.addUse(FieldTypes[I]);
+ }
+ return MIBStruct;
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSpecialType(
@@ -918,33 +912,33 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeForwardPointer(
SPIRVType *SPIRVGlobalRegistry::getOpTypeFunction(
SPIRVType *RetType, const SmallVectorImpl<SPIRVType *> &ArgTypes,
MachineIRBuilder &MIRBuilder) {
- auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
- .addDef(createTypeVReg(MIRBuilder))
- .addUse(getSPIRVTypeID(RetType));
- for (const SPIRVType *ArgType : ArgTypes)
- MIB.addUse(getSPIRVTypeID(ArgType));
- return MIB;
+ return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpTypeFunction)
+ .addDef(createTypeVReg(MIRBuilder))
+ .addUse(getSPIRVTypeID(RetType));
+ for (const SPIRVType *ArgType : ArgTypes)
+ MIB.addUse(getSPIRVTypeID(ArgType));
+ return MIB;
+ });
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeFunctionWithArgs(
const Type *Ty, SPIRVType *RetType,
const SmallVectorImpl<SPIRVType *> &ArgTypes,
MachineIRBuilder &MIRBuilder) {
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- SPIRVType *SpirvType = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
- DT.add(Ty, CurMF, getSPIRVTypeID(SpirvType));
- return finishCreatingSPIRVType(Ty, SpirvType);
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
+ const MachineInstr *NewMI = getOpTypeFunction(RetType, ArgTypes, MIRBuilder);
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::findSPIRVType(
const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
Ty = adjustIntTypeByWidth(Ty);
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
if (auto It = ForwardPointerTypes.find(Ty); It != ForwardPointerTypes.end())
return It->second;
return restOfCreateSPIRVType(Ty, MIRBuilder, AccQual, EmitIR);
@@ -984,8 +978,9 @@ SPIRVType *SPIRVGlobalRegistry::createSPIRVType(
SPIRV::AccessQualifier::AccessQualifier AccQual, bool EmitIR) {
if (isSpecialOpaqueType(Ty))
return getOrCreateSpecialType(Ty, MIRBuilder, AccQual);
- if (Register TyReg = DT.find(Ty, &MIRBuilder.getMF()); TyReg.isValid())
- return getSPIRVTypeForVReg(TyReg);
+
+ if (const MachineInstr *MI = findMI(Ty, &MIRBuilder.getMF()))
+ return MI;
if (auto IType = dyn_cast<IntegerType>(Ty)) {
const unsigned Width = IType->getBitWidth();
@@ -1060,27 +1055,22 @@ SPIRVType *SPIRVGlobalRegistry::restOfCreateSPIRVType(
TypesInProcessing.erase(Ty);
VRegToTypeMap[&MIRBuilder.getMF()][getSPIRVTypeID(SpirvType)] = SpirvType;
SPIRVToLLVMType[SpirvType] = unifyPtrType(Ty);
- Register Reg = DT.find(Ty, &MIRBuilder.getMF());
- // Do not add OpTypeForwardPointer to DT, a corresponding normal pointer type
- // will be added later. For special types it is already added to DT.
- if (SpirvType->getOpcode() != SPIRV::OpTypeForwardPointer && !Reg.isValid() &&
- !isSpecialOpaqueType(Ty)) {
- if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
- ExtTy && isTypedPointerWrapper(ExtTy))
- DT.add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
- &MIRBuilder.getMF(), getSPIRVTypeID(SpirvType));
- else if (!isPointerTy(Ty))
- DT.add(Ty, &MIRBuilder.getMF(), getSPIRVTypeID(SpirvType));
- else if (isTypedPointerTy(Ty))
- DT.add(cast<TypedPointerType>(Ty)->getElementType(),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF(),
- getSPIRVTypeID(SpirvType));
- else
- DT.add(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF(),
- getSPIRVTypeID(SpirvType));
- }
+ if (SpirvType->getOpcode() == SPIRV::OpTypeForwardPointer ||
+ findMI(Ty, &MIRBuilder.getMF()) || isSpecialOpaqueType(Ty))
+ return SpirvType;
+
+ if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
+ ExtTy && isTypedPointerWrapper(ExtTy))
+ add(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), SpirvType);
+ else if (!isPointerTy(Ty))
+ add(Ty, SpirvType);
+ else if (isTypedPointerTy(Ty))
+ add(cast<TypedPointerType>(Ty)->getElementType(),
+ getPointerAddressSpace(Ty), SpirvType);
+ else
+ add(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
+ getPointerAddressSpace(Ty), SpirvType);
return SpirvType;
}
@@ -1107,32 +1097,29 @@ SPIRVType *SPIRVGlobalRegistry::getResultType(Register VReg,
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(
const Type *Ty, MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual, bool EmitIR) {
+ const MachineFunction *MF = &MIRBuilder.getMF();
Register Reg;
if (auto *ExtTy = dyn_cast<TargetExtType>(Ty);
- ExtTy && isTypedPointerWrapper(ExtTy)) {
- Reg = DT.find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0),
- &MIRBuilder.getMF());
- } else if (!isPointerTy(Ty)) {
- Ty = adjustIntTypeByWidth(Ty);
- Reg = DT.find(Ty, &MIRBuilder.getMF());
- } else if (isTypedPointerTy(Ty)) {
- Reg = DT.find(cast<TypedPointerType>(Ty)->getElementType(),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF());
- } else {
- Reg =
- DT.find(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
- getPointerAddressSpace(Ty), &MIRBuilder.getMF());
- }
-
+ ExtTy && isTypedPointerWrapper(ExtTy))
+ Reg = find(ExtTy->getTypeParameter(0), ExtTy->getIntParameter(0), MF);
+ else if (!isPointerTy(Ty))
+ Reg = find(Ty = adjustIntTypeByWidth(Ty), MF);
+ else if (isTypedPointerTy(Ty))
+ Reg = find(cast<TypedPointerType>(Ty)->getElementType(),
+ getPointerAddressSpace(Ty), MF);
+ else
+ Reg = find(Type::getInt8Ty(MIRBuilder.getMF().getFunction().getContext()),
+ getPointerAddressSpace(Ty), MF);
if (Reg.isValid() && !isSpecialOpaqueType(Ty))
return getSPIRVTypeForVReg(Reg);
+
TypesInProcessing.clear();
SPIRVType *STy = restOfCreateSPIRVType(Ty, MIRBuilder, AccessQual, EmitIR);
// Create normal pointer types for the corresponding OpTypeForwardPointers.
for (auto &CU : ForwardPointerTypes) {
const Type *Ty2 = CU.first;
SPIRVType *STy2 = CU.second;
- if ((Reg = DT.find(Ty2, &MIRBuilder.getMF())).isValid())
+ if ((Reg = find(Ty2, MF)).isValid())
STy2 = getSPIRVTypeForVReg(Reg);
else
STy2 = restOfCreateSPIRVType(Ty2, MIRBuilder, AccessQual, EmitIR);
@@ -1530,15 +1517,17 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineIRBuilder &MIRBuilder,
SPIRVType *
SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = IntegerType::get(CurMF->getFunction().getContext(), 1);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeBool))
- .addDef(createTypeVReg(CurMF->getRegInfo()));
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeBool))
+ .addDef(createTypeVReg(CurMF->getRegInfo()));
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
@@ -1553,37 +1542,41 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
SPIRVType *BaseType, unsigned NumElements, MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = FixedVectorType::get(
+ Type *Ty = FixedVectorType::get(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeVector))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addUse(getSPIRVTypeID(BaseType))
- .addImm(NumElements);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeVector))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addUse(getSPIRVTypeID(BaseType))
+ .addImm(NumElements);
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
SPIRVType *BaseType, unsigned NumElements, MachineInstr &I,
const SPIRVInstrInfo &TII) {
- Type *LLVMTy = ArrayType::get(
- const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
- Register Reg = DT.find(LLVMTy, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- MachineBasicBlock &BB = *I.getParent();
+ Type *Ty = ArrayType::get(const_cast<Type *>(getTypeForSPIRVType(BaseType)),
+ NumElements);
+ if (const MachineInstr *MI = findMI(Ty, CurMF))
+ return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
- auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpTypeArray))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addUse(getSPIRVTypeID(BaseType))
- .addUse(Len);
- DT.add(LLVMTy, CurMF, getSPIRVTypeID(MIB));
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpTypeArray))
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addUse(getSPIRVTypeID(BaseType))
+ .addUse(Len);
+ });
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1591,24 +1584,21 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRV::StorageClass::StorageClass SC) {
const Type *PointerElementType = getTypeForSPIRVType(BaseType);
unsigned AddressSpace = storageClassToAddressSpace(SC);
- Type *LLVMTy = TypedPointerType::get(const_cast<Type *>(PointerElementType),
- AddressSpace);
- // check if this type is already available
- Register Reg = DT.find(PointerElementType, AddressSpace, CurMF);
- if (Reg.isValid())
- return getSPIRVTypeForVReg(Reg);
- // create a new type
- return createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB = BuildMI(MIRBuilder.getMBB(), MIRBuilder.getInsertPt(),
+ if (const MachineInstr *MI = findMI(PointerElementType, AddressSpace, CurMF))
+ return MI;
+ Type *Ty = TypedPointerType::get(const_cast<Type *>(PointerElementType),
+ AddressSpace);
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ return BuildMI(MIRBuilder.getMBB(), MIRBuilder.getInsertPt(),
MIRBuilder.getDebugLoc(),
MIRBuilder.getTII().get(SPIRV::OpTypePointer))
- .addDef(createTypeVReg(CurMF->getRegInfo()))
- .addImm(static_cast<uint32_t>(SC))
- .addUse(getSPIRVTypeID(BaseType));
- DT.add(PointerElementType, AddressSpace, CurMF, getSPIRVTypeID(MIB));
- finishCreatingSPIRVType(LLVMTy, MIB);
- return MIB;
- });
+ .addDef(createTypeVReg(CurMF->getRegInfo()))
+ .addImm(static_cast<uint32_t>(SC))
+ .addUse(getSPIRVTypeID(BaseType));
+ });
+ add(PointerElementType, AddressSpace, NewMI);
+ return finishCreatingSPIRVType(Ty, MIB);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1621,27 +1611,30 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII) {
- assert(SpvType);
- const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- assert(LLVMTy);
- // Find a constant in DT or build a new one.
- UndefValue *UV = UndefValue::get(const_cast<Type *>(LLVMTy));
- Register Res = DT.find(UV, CurMF);
+ UndefValue *UV =
+ UndefValue::get(const_cast<Type *>(getTypeForSPIRVType(SpvType)));
+ Register Res = find(UV, CurMF);
if (Res.isValid())
return Res;
+
LLT LLTy = LLT::scalar(64);
Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- DT.add(UV, CurMF, Res);
- MachineInstrBuilder MIB;
- MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
- const auto &ST = CurMF->getSubtarget();
- constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
- *ST.getRegisterInfo(), *ST.getRegBankInfo());
+ const MachineInstr *NewMI =
+ createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
+ auto MIB =
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
+ const auto &ST = CurMF->getSubtarget();
+ constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
+ *ST.getRegisterInfo(),
+ *ST.getRegBankInfo());
+ return MIB;
+ });
+ add(UV, NewMI);
return Res;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index 248384e50eac1..a70fde0a9ffc0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -110,8 +110,8 @@ inline IRHandle make_descr_pointee(const Type *ElementType,
SpecialTypeKind::STK_ElementPointer);
}
-inline IRHandle make_descr_ptr(const void *Ptr) {
- return std::make_tuple(Ptr, 0U, SpecialTypeKind::STK_Pointer);
+inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
+ return std::make_tuple(Ptr, Arg, SpecialTypeKind::STK_Pointer);
}
} // namespace SPIRV
>From d577b10229d45f3f085df0ecb0d1e0ded85dd7b0 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 11 Mar 2025 07:54:33 -0700
Subject: [PATCH 7/9] a new duplicate tracker
---
llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp | 12 ++--
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 8 +--
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 30 +++++----
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 5 --
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 29 ++++++---
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 65 ++++++++++---------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 22 +++----
7 files changed, 93 insertions(+), 78 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
index 3039f975a4df2..d55631e0146cf 100644
--- a/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVCallLowering.cpp
@@ -398,8 +398,6 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
auto MRI = MIRBuilder.getMRI();
Register FuncVReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
MRI->setRegClass(FuncVReg, &SPIRV::iIDRegClass);
- if (F.isDeclaration())
- GR->add(&F, &MIRBuilder.getMF(), FuncVReg);
FunctionType *FTy = getOriginalFunctionType(F);
Type *FRetTy = FTy->getReturnType();
if (isUntypedPointerTy(FRetTy)) {
@@ -425,6 +423,8 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
.addUse(GR->getSPIRVTypeID(FuncTy));
GR->recordFunctionDefinition(&F, &MB.getInstr()->getOperand(0));
GR->addGlobalObject(&F, &MIRBuilder.getMF(), FuncVReg);
+ if (F.isDeclaration())
+ GR->add(&F, MB);
// Add OpFunctionParameter instructions
int i = 0;
@@ -433,11 +433,11 @@ bool SPIRVCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder,
Register ArgReg = VRegs[i][0];
MRI->setRegClass(ArgReg, GR->getRegClass(ArgTypeVRegs[i]));
MRI->setType(ArgReg, GR->getRegType(ArgTypeVRegs[i]));
- MIRBuilder.buildInstr(SPIRV::OpFunctionParameter)
- .addDef(ArgReg)
- .addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));
+ auto MIB = MIRBuilder.buildInstr(SPIRV::OpFunctionParameter)
+ .addDef(ArgReg)
+ .addUse(GR->getSPIRVTypeID(ArgTypeVRegs[i]));
if (F.isDeclaration())
- GR->add(&Arg, &MIRBuilder.getMF(), ArgReg);
+ GR->add(&Arg, MIB);
GR->addGlobalObject(&Arg, &MIRBuilder.getMF(), ArgReg);
i++;
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 356f4f6dab75c..cd01d158cc861 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -63,7 +63,7 @@ class SPIRVEmitIntrinsics
SPIRVTargetMachine *TM = nullptr;
SPIRVGlobalRegistry *GR = nullptr;
Function *CurrF = nullptr;
- bool TrackConstants = false;//true;
+ bool TrackConstants = true;
bool HaveFunPtrs = false;
DenseMap<Instruction *, Constant *> AggrConsts;
DenseMap<Instruction *, Type *> AggrConstTypes;
@@ -2025,7 +2025,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
auto *II = dyn_cast<IntrinsicInst>(I);
bool IsConstComposite =
II && II->getIntrinsicID() == Intrinsic::spv_const_composite;
- if (IsConstComposite) {
+ if (IsConstComposite && TrackConstants) {
setInsertPointAfterDef(B, I);
auto t = AggrConsts.find(I);
assert(t != AggrConsts.end());
@@ -2042,7 +2042,7 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
continue;
unsigned OpNo = Op.getOperandNo();
if (II && ((II->getIntrinsicID() == Intrinsic::spv_gep && OpNo == 0) ||
- (II->paramHasAttr(OpNo, Attribute::ImmArg))))
+ (II->paramHasAttr(OpNo, Attribute::ImmArg))))
continue;
if (!BPrepared) {
@@ -2421,7 +2421,7 @@ bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) {
deduceOperandElementType(&Phi, nullptr);
for (auto *I : Worklist) {
- TrackConstants = false;//true;
+ TrackConstants = true;
if (!I->getType()->isVoidTy() || isa<StoreInst>(I))
setInsertPointAfterDef(B, I);
// Visitors return either the original/newly created instruction for further
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 69d707ca2ec15..62e4d50b1926a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -178,7 +178,6 @@ SPIRVType *SPIRVGlobalRegistry::getOpTypeVoid(MachineIRBuilder &MIRBuilder) {
void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
// TODO:
- // - take into account duplicate tracker case which is a known issue,
// - review other data structure wrt. possible issues related to removal
// of a machine instruction during instruction selection.
const MachineFunction *MF = MI->getMF();
@@ -187,6 +186,8 @@ void SPIRVGlobalRegistry::invalidateMachineInstr(MachineInstr *MI) {
return;
if (It->second == MI)
LastInsertedTypeMap.erase(MF);
+ // remove from the duplicate tracker to avoid incorrect reuse
+ erase(MI);
}
SPIRVType *SPIRVGlobalRegistry::createOpType(
@@ -275,7 +276,7 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
addNumImm(APInt(BitWidth,
- CI->getValueAPF().bitcastToAPInt().getZExtValue()),
+ CF->getValueAPF().bitcastToAPInt().getZExtValue()),
MIB);
}
const auto &ST = CurMF->getSubtarget();
@@ -284,7 +285,7 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
*ST.getRegBankInfo());
return MIB;
});
- add(CI, NewType);
+ add(CF, NewType);
return Res;
}
@@ -367,7 +368,7 @@ Register SPIRVGlobalRegistry::buildConstantInt(uint64_t Val,
*Subtarget.getRegBankInfo());
return MIB;
});
- add(ConstInt, NewType);
+ add(CI, NewType);
return Res;
}
@@ -375,10 +376,10 @@ Register SPIRVGlobalRegistry::buildConstantFP(APFloat Val,
MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType) {
auto &MF = MIRBuilder.getMF();
+ LLVMContext &Ctx = MF.getFunction().getContext();
if (!SpvType)
- SpvType = getOrCreateSPIRVType(
- Type::getFloatTy(MF.getFunction().getContext()), MIRBuilder,
- SPIRV::AccessQualifier::ReadWrite, true);
+ SpvType = getOrCreateSPIRVType(Type::getFloatTy(Ctx), MIRBuilder,
+ SPIRV::AccessQualifier::ReadWrite, true);
auto *const CF = ConstantFP::get(Ctx, Val);
Register Res = find(CF, &MF);
if (Res.isValid())
@@ -1378,7 +1379,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeCoopMatr(
.addUse(buildConstantInt(Columns, MIRBuilder, SpvTypeInt32, EmitIR))
.addUse(buildConstantInt(Use, MIRBuilder, SpvTypeInt32, EmitIR));
});
- add(Key, NewMI);
+ add(ExtensionType, NewMI);
return NewMI;
}
@@ -1390,7 +1391,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeByOpcode(
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return MIRBuilder.buildInstr(Opcode).addDef(createTypeVReg(MIRBuilder));
});
- add(Key, NewMI);
+ add(Ty, NewMI);
return NewMI;
}
@@ -1464,6 +1465,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
Type *Ty) {
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
@@ -1471,8 +1473,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
.addImm(BitWidth)
.addImm(0);
});
- add(LLVMTy, NewMI);
- return finishCreatingSPIRVType(LLVMTy, MIB);
+ add(Ty, NewMI);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVIntegerType(
@@ -1520,6 +1522,7 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1546,6 +1549,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1567,6 +1571,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
@@ -1598,7 +1603,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
.addUse(getSPIRVTypeID(BaseType));
});
add(PointerElementType, AddressSpace, NewMI);
- return finishCreatingSPIRVType(Ty, MIB);
+ return finishCreatingSPIRVType(Ty, NewMI);
}
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
@@ -1622,6 +1627,7 @@ Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
+ MachineIRBuilder MIRBuilder(I);
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
auto MIB =
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 6c2f08e315e3a..3c6c11fae92b3 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -55,11 +55,6 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
// map an instruction to its value's attributes (type, name)
DenseMap<MachineInstr *, std::pair<Type *, std::string>> ValueAttrs;
- // Look for an equivalent of the newType in the map. Return the equivalent
- // if it's found, otherwise insert newType to the map and return the type.
- const MachineInstr *checkSpecialInstr(const SPIRV::SpecialTypeDescriptor &TD,
- MachineIRBuilder &MIRBuilder);
-
SmallPtrSet<const Type *, 4> TypesInProcessing;
DenseMap<const Type *, SPIRVType *> ForwardPointerTypes;
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index a70fde0a9ffc0..8f1a345565630 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -119,19 +119,20 @@ inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
- DenseMap < std::pair<IRHandle, const MachineFunction *>,
- const MachineInstr *MI >> Vregs;
- DenseMap<const MachineInstr *, IRHandle> Defs;
+ DenseMap<std::pair<SPIRV::IRHandle, const MachineFunction *>,
+ const MachineInstr *>
+ Vregs;
+ DenseMap<const MachineInstr *, SPIRV::IRHandle> Defs;
public:
- bool add(IRHandle Handle, const MachineInstr *MI) {
+ bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
auto [It, Inserted] =
Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
if (Inserted) {
auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
assert(IsConsistent);
}
- return Inserted1;
+ return Inserted;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
@@ -141,12 +142,13 @@ class SPIRVIRMapping {
}
return Res;
}
- const MachineInstr *findMI(IRHandle Handle, const MachineFunction *MF) {
+ const MachineInstr *findMI(SPIRV::IRHandle Handle,
+ const MachineFunction *MF) {
if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
return It->second;
return nullptr;
}
- Register find(IRHandle Handle, const MachineFunction *MF) {
+ Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
const MachineInstr *MI = findMI(Handle, MF);
return MI ? MI->getOperand(0).getReg() : Register();
}
@@ -155,7 +157,7 @@ class SPIRVIRMapping {
bool add(const Type *Ty, const MachineInstr *MI) {
return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
}
- void add(const void *Key, const MachineInstr *MI) {
+ bool add(const void *Key, const MachineInstr *MI) {
return add(SPIRV::make_descr_ptr(Key), MI);
}
bool add(const Type *PointeeTy, unsigned AddressSpace,
@@ -166,14 +168,25 @@ class SPIRVIRMapping {
Register find(const Type *Ty, const MachineFunction *MF) {
return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
}
+ const MachineInstr *findMI(const Type *Ty, const MachineFunction *MF) {
+ return findMI(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
+ }
Register find(const void *Key, const MachineFunction *MF) {
return find(SPIRV::make_descr_ptr(Key), MF);
}
+ const MachineInstr *findMI(const void *Key, const MachineFunction *MF) {
+ return findMI(SPIRV::make_descr_ptr(Key), MF);
+ }
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
return find(
SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
}
+ const MachineInstr *findMI(const Type *PointeeTy, unsigned AddressSpace,
+ const MachineFunction *MF) {
+ return findMI(
+ SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ }
};
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVIRMAPPING_H
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index ce9ce3ef3135c..aa82f7f7d936a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1213,16 +1213,17 @@ bool SPIRVInstructionSelector::selectMemOperation(Register ResVReg,
true, GlobalValue::InternalLinkage,
Constant::getNullValue(LLVMArrTy));
Register VarReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
- GR.add(GV, GR.CurMF, VarReg);
- GR.addGlobalObject(GV, GR.CurMF, VarReg);
-
- Result &=
+ auto MIBVar =
BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpVariable))
.addDef(VarReg)
.addUse(GR.getSPIRVTypeID(VarTy))
.addImm(SPIRV::StorageClass::UniformConstant)
- .addUse(Const)
- .constrainAllUses(TII, TRI, RBI);
+ .addUse(Const);
+ Result &= MIBVar.constrainAllUses(TII, TRI, RBI);
+
+ GR.add(GV, MIBVar);
+ GR.addGlobalObject(GV, GR.CurMF, VarReg);
+
buildOpDecorate(VarReg, I, TII, SPIRV::Decoration::Constant, {});
SPIRVType *SourceTy = GR.getOrCreateSPIRVPointerType(
ValTy, I, TII, SPIRV::StorageClass::UniformConstant);
@@ -1555,7 +1556,7 @@ SPIRVInstructionSelector::buildConstGenericPtr(MachineInstr &I, Register SrcPtr,
MachineInstrBuilder MIB = buildSpecConstantOp(
I, Tmp, SrcPtr, GR.getSPIRVTypeID(GenericPtrTy),
static_cast<uint32_t>(SPIRV::Opcode::PtrCastToGeneric));
- GR.add(MIB.getInstr(), MF, Tmp);
+ GR.add(MIB.getInstr(), MIB);
return MIB;
}
@@ -2505,20 +2506,18 @@ SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
bool Result = true;
if (!NewReg.isValid()) {
NewReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
- GR.add(ConstInt, GR.CurMF, NewReg);
- MachineInstr *MI;
MachineBasicBlock &BB = *I.getParent();
- if (Val == 0) {
- MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(SpvI32Ty));
- } else {
- MI = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(SpvI32Ty))
- .addImm(APInt(32, Val).getZExtValue());
- }
+ MachineInstr *MI =
+ Val == 0
+ ? BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(SpvI32Ty))
+ : BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(SpvI32Ty))
+ .addImm(APInt(32, Val).getZExtValue());
Result &= constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ GR.add(ConstInt, MI);
}
return {NewReg, Result};
}
@@ -2895,18 +2894,18 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
}
// Create a new register for the wrapper
WrapReg = MRI->createVirtualRegister(GR.getRegClass(OpType));
- GR.add(OpDefine, MF, WrapReg);
CompositeArgs.push_back(WrapReg);
// Decorate the wrapper register and generate a new instruction
MRI->setType(WrapReg, LLT::pointer(0, 64));
GR.assignSPIRVTypeToVReg(OpType, WrapReg, *MF);
- MachineBasicBlock &BB = *I.getParent();
- Result = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpSpecConstantOp))
- .addDef(WrapReg)
- .addUse(GR.getSPIRVTypeID(OpType))
- .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
- .addUse(OpReg)
- .constrainAllUses(TII, TRI, RBI);
+ auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(),
+ TII.get(SPIRV::OpSpecConstantOp))
+ .addDef(WrapReg)
+ .addUse(GR.getSPIRVTypeID(OpType))
+ .addImm(static_cast<uint32_t>(SPIRV::Opcode::Bitcast))
+ .addUse(OpReg);
+ GR.add(OpDefine, MIB);
+ Result = MIB.constrainAllUses(TII, TRI, RBI);
if (!Result)
break;
}
@@ -3844,7 +3843,6 @@ bool SPIRVInstructionSelector::selectGlobalValue(
Register NewReg = GR.find(ConstVal, GR.CurMF);
if (!NewReg.isValid()) {
Register NewReg = ResVReg;
- GR.add(ConstVal, GR.CurMF, NewReg);
const Function *GVFun =
STI.canUseExtension(SPIRV::Extension::SPV_INTEL_function_pointers)
? dyn_cast<Function>(GV)
@@ -3872,15 +3870,18 @@ bool SPIRVInstructionSelector::selectGlobalValue(
.addDef(NewReg)
.addUse(ResTypeReg)
.addUse(FuncVReg);
+ GR.add(ConstVal, MIB2);
// mapping the function pointer to the used Function
GR.recordFunctionPointer(&MIB2.getInstr()->getOperand(2), GVFun);
return MIB1.constrainAllUses(TII, TRI, RBI) &&
MIB2.constrainAllUses(TII, TRI, RBI);
}
- return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
- .addDef(NewReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .constrainAllUses(TII, TRI, RBI);
+ MachineInstrBuilder MIB3 =
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantNull))
+ .addDef(NewReg)
+ .addUse(GR.getSPIRVTypeID(ResType));
+ GR.add(ConstVal, MIB3);
+ return MIB3.constrainAllUses(TII, TRI, RBI);
}
assert(NewReg != ResVReg);
return BuildCOPY(ResVReg, NewReg, I);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index edf215f0ce00f..da837c9ed85dd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -48,8 +48,7 @@ void SPIRVPreLegalizer::getAnalysisUsage(AnalysisUsage &AU) const {
static void
addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
const SPIRVSubtarget &STI,
- DenseMap<MachineInstr *, Type *> &TargetExtConstTypes,
- SmallSet<Register, 4> &TrackedConstRegs) {
+ DenseMap<MachineInstr *, Type *> &TargetExtConstTypes) {
MachineRegisterInfo &MRI = MF.getRegInfo();
DenseMap<MachineInstr *, Register> RegsAlreadyAddedToDT;
SmallVector<MachineInstr *, 10> ToErase, ToEraseComposites;
@@ -66,7 +65,7 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (auto *GV = dyn_cast<GlobalValue>(Const)) {
Register Reg = GR->find(GV, &MF);
if (!Reg.isValid()) {
- GR->add(GV, &MF, SrcReg);
+ GR->add(GV, MRI.getVRegDef(SrcReg));
GR->addGlobalObject(GV, &MF, SrcReg);
} else
RegsAlreadyAddedToDT[&MI] = Reg;
@@ -77,22 +76,24 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto *BuildVec = MRI.getVRegDef(SrcReg);
assert(BuildVec &&
BuildVec->getOpcode() == TargetOpcode::G_BUILD_VECTOR);
+ GR->add(Const, BuildVec);
for (unsigned i = 0; i < ConstVec->getNumElements(); ++i) {
// Ensure that OpConstantComposite reuses a constant when it's
// already created and available in the same machine function.
Constant *ElemConst = ConstVec->getElementAsConstant(i);
Register ElemReg = GR->find(ElemConst, &MF);
if (!ElemReg.isValid())
- GR->add(ElemConst, &MF, BuildVec->getOperand(1 + i).getReg());
+ GR->add(ElemConst,
+ MRI.getVRegDef(BuildVec->getOperand(1 + i).getReg()));
else
BuildVec->getOperand(1 + i).setReg(ElemReg);
}
}
- GR->add(Const, &MF, SrcReg);
- TrackedConstRegs.insert(SrcReg);
if (Const->getType()->isTargetExtTy()) {
// remember association so that we can restore it when assign types
MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
+ if (SrcMI)
+ GR->add(Const, SrcMI);
if (SrcMI && (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT ||
SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
TargetExtConstTypes[SrcMI] = Const->getType();
@@ -595,7 +596,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
// pointers/PtrCast-null-in-OpSpecConstantOp.ll).
Register PrimaryReg = GR->find(OpCI, &MF);
if (!PrimaryReg.isValid()) {
- GR->add(OpCI, &MF, Reg);
+ GR->add(OpCI, &MI);
} else if (PrimaryReg != Reg &&
MRI.getType(Reg) == MRI.getType(PrimaryReg)) {
auto *RCReg = MRI.getRegClassOrNull(Reg);
@@ -730,7 +731,7 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto AsmTargetMIB =
MIRBuilder.buildInstr(SPIRV::OpAsmTargetINTEL).addDef(AsmTargetReg);
addStringImm(ST.getTargetTripleAsStr(), AsmTargetMIB);
- GR->add(AsmTargetMIB.getInstr(), &MF, AsmTargetReg);
+ GR->add(AsmTargetMIB.getInstr(), AsmTargetMIB);
}
// create types
@@ -761,7 +762,7 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
addStringImm(cast<MDString>(I1->getOperand(2).getMetadata()->getOperand(0))
->getString(),
AsmMIB);
- GR->add(AsmMIB.getInstr(), &MF, AsmReg);
+ GR->add(AsmMIB.getInstr(), AsmMIB);
// calls the inline assembly instruction
unsigned ExtraInfo = I2->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
@@ -1034,8 +1035,7 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
// a registry of target extension constants
DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
// to keep record of tracked constants
- SmallSet<Register, 4> TrackedConstRegs;
- addConstantsToTrack(MF, GR, ST, TargetExtConstTypes, TrackedConstRegs);
+ addConstantsToTrack(MF, GR, ST, TargetExtConstTypes);
foldConstantsIntoIntrinsics(MF, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
>From 429551babc8637c4bcb58d07fae45ca3b4c6f568 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Fri, 14 Mar 2025 08:39:19 -0700
Subject: [PATCH 8/9] rework assign_type, type/const instruction selection
---
llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 2 +-
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp | 113 ++++---
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 6 +
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 155 ++++++---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 6 +-
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 297 +++++++++---------
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp | 39 +--
llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h | 2 -
llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp | 10 +-
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 126 +++++---
.../SPIRV/SPIRVPreLegalizerCombiner.cpp | 7 +-
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 96 +++++-
llvm/lib/Target/SPIRV/SPIRVUtils.h | 12 +
llvm/test/CodeGen/SPIRV/atomicrmw.ll | 4 +-
.../SPIRV/debug-info/debug-type-pointer.ll | 44 +--
llvm/test/CodeGen/SPIRV/freeze.ll | 11 +-
.../SPIRV/hlsl-intrinsics/dot4add_i8packed.ll | 2 +-
.../SPIRV/hlsl-intrinsics/dot4add_u8packed.ll | 2 +-
.../hlsl-resources/StorageImageDynIdx.ll | 8 +-
.../StorageImageNonUniformIdx.ll | 10 +-
.../llvm-intrinsics/smul.with.overflow.ll | 6 +-
.../llvm-intrinsics/uadd.with.overflow.ll | 6 +-
.../llvm-intrinsics/umul.with.overflow.ll | 6 +-
.../llvm-intrinsics/usub.with.overflow.ll | 6 +-
24 files changed, 577 insertions(+), 399 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
index e6c0a526a9cec..4f5984d8823ab 100644
--- a/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp
@@ -535,7 +535,7 @@ static Register buildBuiltinVariableLoad(
/// assign SPIRVType to both registers. If SpirvTy is provided, use it as
/// SPIRVType in ASSIGN_TYPE, otherwise create it from \p Ty. Defined in
/// SPIRVPreLegalizer.cpp.
-extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
+extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
SPIRVGlobalRegistry *GR,
MachineIRBuilder &MIB,
MachineRegisterInfo &MRI);
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 62e4d50b1926a..07138c625a1af 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -250,24 +250,32 @@ Register SPIRVGlobalRegistry::getOrCreateConstFP(APFloat Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLVMContext &Ctx = CurMF->getFunction().getContext();
auto *const CF = ConstantFP::get(Ctx, Val);
- Register Res = find(CF, CurMF);
- if (Res.isValid())
- return Res;
+ const MachineInstr *MI = findMI(CF, CurMF);
+ if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
+ MI->getOpcode() == SPIRV::OpConstantF))
+ return MI->getOperand(0).getReg();
+ return createConstFP(CF, I, SpvType, TII, ZeroAsNull);
+}
+Register SPIRVGlobalRegistry::createConstFP(const ConstantFP *CF,
+ MachineInstr &I, SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLT LLTy = LLT::scalar(BitWidth);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::fIDRegClass);
assignFloatTypeToVReg(BitWidth, Res, I, TII);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
// In OpenCL OpConstantNull - Scalar floating point: +0.0 (all bits 0)
- if (Val.isPosZero() && ZeroAsNull) {
+ if (CF->getValue().isPosZero() && ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
@@ -294,24 +302,35 @@ Register SPIRVGlobalRegistry::getOrCreateConstInt(uint64_t Val, MachineInstr &I,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
- unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
- Register Res = find(CI, CurMF);
- if (Res.isValid())
- return Res;
+ const MachineInstr *MI = findMI(CI, CurMF);
+ if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
+ MI->getOpcode() == SPIRV::OpConstantI))
+ return MI->getOperand(0).getReg();
+ return createConstInt(CI, I, SpvType, TII, ZeroAsNull);
+}
+
+Register SPIRVGlobalRegistry::createConstInt(const ConstantInt *CI,
+ MachineInstr &I,
+ SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
+ unsigned BitWidth = getScalarOrVectorBitWidth(SpvType);
LLT LLTy = LLT::scalar(BitWidth);
- Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
+ Register Res = CurMF->getRegInfo().createGenericVirtualRegister(LLTy);
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignIntTypeToVReg(BitWidth, Res, I, TII);
- MachineIRBuilder MIRBuilder(I);
+
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
SPIRVType *NewType =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
- if (Val || !ZeroAsNull) {
+ if (!CI->isZero() || !ZeroAsNull) {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantI)
.addDef(Res)
.addUse(getSPIRVTypeID(SpvType));
- addNumImm(APInt(BitWidth, Val), MIB);
+ addNumImm(APInt(BitWidth, CI->getZExtValue()), MIB);
} else {
MIB = MIRBuilder.buildInstr(SPIRV::OpConstantNull)
.addDef(Res)
@@ -441,7 +460,8 @@ Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
CurMF->getRegInfo().setRegClass(Res, getRegClass(SpvType));
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
MachineInstrBuilder MIB;
@@ -751,11 +771,7 @@ static std::string buildSpirvTypeName(const SPIRVType *Type,
MachineRegisterInfo *MRI = MIRBuilder.getMRI();
Register ElementTypeReg = Type->getOperand(1).getReg();
auto *ElementType = MRI->getUniqueVRegDef(ElementTypeReg);
- const SPIRVType *TypeInst = MRI->getVRegDef(Type->getOperand(2).getReg());
- assert(TypeInst->getOpcode() != SPIRV::OpConstantI);
- MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
- assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
- uint32_t ArraySize = ImmInst->getOperand(1).getCImm()->getZExtValue();
+ uint32_t ArraySize = getArrayComponentCount(MRI, Type);
return (buildSpirvTypeName(ElementType, MIRBuilder) + Twine("[") +
Twine(ArraySize) + Twine("]"))
.str();
@@ -1274,9 +1290,9 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
uint32_t Depth, uint32_t Arrayed, uint32_t Multisampled, uint32_t Sampled,
SPIRV::ImageFormat::ImageFormat ImageFormat,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto Key = SPIRV::make_descr_image(SPIRVToLLVMType.lookup(SampledType), Dim,
- Depth, Arrayed, Multisampled, Sampled,
- ImageFormat, AccessQual);
+ auto Key = SPIRV::irhandle_image(SPIRVToLLVMType.lookup(SampledType), Dim,
+ Depth, Arrayed, Multisampled, Sampled,
+ ImageFormat, AccessQual);
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1301,7 +1317,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeImage(
SPIRVType *
SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_sampler();
+ auto Key = SPIRV::irhandle_sampler();
const MachineFunction *MF = &MIRBuilder.getMF();
if (const MachineInstr *MI = findMI(Key, MF))
return MI;
@@ -1317,7 +1333,7 @@ SPIRVGlobalRegistry::getOrCreateOpTypeSampler(MachineIRBuilder &MIRBuilder) {
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
MachineIRBuilder &MIRBuilder,
SPIRV::AccessQualifier::AccessQualifier AccessQual) {
- auto Key = SPIRV::make_descr_pipe(AccessQual);
+ auto Key = SPIRV::irhandle_pipe(AccessQual);
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1332,7 +1348,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypePipe(
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_event();
+ auto Key = SPIRV::irhandle_event();
if (const MachineInstr *MI = findMI(Key, &MIRBuilder.getMF()))
return MI;
const MachineInstr *NewMI =
@@ -1346,7 +1362,7 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeDeviceEvent(
SPIRVType *SPIRVGlobalRegistry::getOrCreateOpTypeSampledImage(
SPIRVType *ImageType, MachineIRBuilder &MIRBuilder) {
- auto Key = SPIRV::make_descr_sampled_image(
+ auto Key = SPIRV::irhandle_sampled_image(
SPIRVToLLVMType.lookup(MIRBuilder.getMF().getRegInfo().getVRegDef(
ImageType->getOperand(1).getReg())),
ImageType);
@@ -1465,10 +1481,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVType(unsigned BitWidth,
Type *Ty) {
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRVOPcode))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRVOPcode))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addImm(BitWidth)
.addImm(0);
@@ -1522,11 +1540,12 @@ SPIRVGlobalRegistry::getOrCreateSPIRVBoolType(MachineInstr &I,
Type *Ty = IntegerType::get(CurMF->getFunction().getContext(), 1);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, DepMBB.getFirstNonPHI());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeBool))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeBool))
.addDef(createTypeVReg(CurMF->getRegInfo()));
});
add(Ty, NewMI);
@@ -1549,11 +1568,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVVectorType(
const_cast<Type *>(getTypeForSPIRVType(BaseType)), NumElements);
if (const MachineInstr *MI = findMI(Ty, CurMF))
return MI;
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(BaseType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeVector))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeVector))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addUse(getSPIRVTypeID(BaseType))
.addImm(NumElements);
@@ -1571,11 +1591,12 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVArrayType(
return MI;
SPIRVType *SpvTypeInt32 = getOrCreateSPIRVIntegerType(32, I, TII);
Register Len = getOrCreateConstInt(NumElements, I, SpvTypeInt32, TII);
- MachineIRBuilder MIRBuilder(I);
+ MachineBasicBlock &DepMBB = I.getMF()->front();
+ MachineIRBuilder MIRBuilder(DepMBB, getInsertPtValidEnd(&DepMBB));
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- return BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(SPIRV::OpTypeArray))
+ return BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpTypeArray))
.addDef(createTypeVReg(CurMF->getRegInfo()))
.addUse(getSPIRVTypeID(BaseType))
.addUse(Len);
@@ -1609,7 +1630,8 @@ SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRVType *SPIRVGlobalRegistry::getOrCreateSPIRVPointerType(
SPIRVType *BaseType, MachineInstr &I, const SPIRVInstrInfo &,
SPIRV::StorageClass::StorageClass SC) {
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(BaseType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
return getOrCreateSPIRVPointerType(BaseType, MIRBuilder, SC);
}
@@ -1627,13 +1649,14 @@ Register SPIRVGlobalRegistry::getOrCreateUndef(MachineInstr &I,
CurMF->getRegInfo().setRegClass(Res, &SPIRV::iIDRegClass);
assignSPIRVTypeToVReg(SpvType, Res, *CurMF);
- MachineIRBuilder MIRBuilder(I);
+ MachineInstr *DepMI = const_cast<MachineInstr *>(SpvType);
+ MachineIRBuilder MIRBuilder(*DepMI->getParent(), DepMI->getIterator());
const MachineInstr *NewMI =
createOpType(MIRBuilder, [&](MachineIRBuilder &MIRBuilder) {
- auto MIB =
- BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(SPIRV::OpUndef))
- .addDef(Res)
- .addUse(getSPIRVTypeID(SpvType));
+ auto MIB = BuildMI(MIRBuilder.getMBB(), *MIRBuilder.getInsertPt(),
+ MIRBuilder.getDL(), TII.get(SPIRV::OpUndef))
+ .addDef(Res)
+ .addUse(getSPIRVTypeID(SpvType));
const auto &ST = CurMF->getSubtarget();
constrainSelectedInstRegOperands(*MIB, *ST.getInstrInfo(),
*ST.getRegisterInfo(),
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index 3c6c11fae92b3..385e424092d4a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -473,9 +473,15 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register createConstInt(const ConstantInt *CI, MachineInstr &I,
+ SPIRVType *SpvType, const SPIRVInstrInfo &TII,
+ bool ZeroAsNull);
Register getOrCreateConstFP(APFloat Val, MachineInstr &I, SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register createConstFP(const ConstantFP *CF, MachineInstr &I,
+ SPIRVType *SpvType, const SPIRVInstrInfo &TII,
+ bool ZeroAsNull);
Register buildConstantFP(APFloat Val, MachineIRBuilder &MIRBuilder,
SPIRVType *SpvType = nullptr);
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index 8f1a345565630..bec2a989483e8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -18,7 +18,7 @@
#include "MCTargetDesc/SPIRVMCTargetDesc.h"
#include "SPIRVUtils.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -27,7 +27,39 @@
namespace llvm {
namespace SPIRV {
+inline size_t to_hash(const MachineInstr *MI,
+ std::unordered_set<const MachineInstr *> &Visited) {
+ if (!MI || !Visited.insert(MI).second)
+ return 0;
+ const MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
+ SmallVector<size_t, 16> Codes{MI->getOpcode()};
+ size_t H;
+ for (unsigned I = MI->getNumDefs(); I < MI->getNumOperands(); ++I) {
+ const MachineOperand &MO = MI->getOperand(I);
+ H = MO.isReg() ? to_hash(getDef(MO, &MRI), Visited)
+ : size_t(llvm::hash_value(MO));
+ Codes.push_back(H);
+ }
+ return llvm::hash_combine(Codes.begin(), Codes.end());
+}
+
+inline size_t to_hash(const MachineInstr *MI) {
+ std::unordered_set<const MachineInstr *> Visited;
+ return to_hash(MI, Visited);
+}
+
+using MIHandle = std::pair<const MachineInstr *, size_t>;
+
+inline MIHandle getMIKey(const MachineInstr *MI) {
+ return std::make_pair(MI, SPIRV::to_hash(MI));
+}
+
using IRHandle = std::tuple<const void *, unsigned, unsigned>;
+using IRHandleMF = std::pair<IRHandle, const MachineFunction *>;
+
+inline IRHandleMF getIRHandleMF(IRHandle Handle, const MachineFunction *MF) {
+ return std::make_pair(Handle, MF);
+}
enum SpecialTypeKind {
STK_Empty = 0,
@@ -37,7 +69,9 @@ enum SpecialTypeKind {
STK_Pipe,
STK_DeviceEvent,
STK_ElementPointer,
- STK_Pointer,
+ STK_Type,
+ STK_Value,
+ STK_MachineInstr,
STK_Last = -1
};
@@ -66,18 +100,18 @@ union ImageAttrs {
}
};
-inline IRHandle make_descr_image(const Type *SampledTy, unsigned Dim,
- unsigned Depth, unsigned Arrayed, unsigned MS,
- unsigned Sampled, unsigned ImageFormat,
- unsigned AQ = 0) {
+inline IRHandle irhandle_image(const Type *SampledTy, unsigned Dim,
+ unsigned Depth, unsigned Arrayed, unsigned MS,
+ unsigned Sampled, unsigned ImageFormat,
+ unsigned AQ = 0) {
return std::make_tuple(
SampledTy,
ImageAttrs(Dim, Depth, Arrayed, MS, Sampled, ImageFormat, AQ).Val,
SpecialTypeKind::STK_Image);
}
-inline IRHandle make_descr_sampled_image(const Type *SampledTy,
- const MachineInstr *ImageTy) {
+inline IRHandle irhandle_sampled_image(const Type *SampledTy,
+ const MachineInstr *ImageTy) {
assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
unsigned AC = AccessQualifier::AccessQualifier::None;
if (ImageTy->getNumOperands() > 8)
@@ -92,61 +126,90 @@ inline IRHandle make_descr_sampled_image(const Type *SampledTy,
SpecialTypeKind::STK_SampledImage);
}
-inline IRHandle make_descr_sampler() {
+inline IRHandle irhandle_sampler() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_Sampler);
}
-inline IRHandle make_descr_pipe(uint8_t AQ) {
+inline IRHandle irhandle_pipe(uint8_t AQ) {
return std::make_tuple(nullptr, AQ, SpecialTypeKind::STK_Pipe);
}
-inline IRHandle make_descr_event() {
+inline IRHandle irhandle_event() {
return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_DeviceEvent);
}
-inline IRHandle make_descr_pointee(const Type *ElementType,
- unsigned AddressSpace) {
- return std::make_tuple(ElementType, AddressSpace,
+inline IRHandle irhandle_pointee(const Type *ElementType,
+ unsigned AddressSpace) {
+ return std::make_tuple(unifyPtrType(ElementType), AddressSpace,
SpecialTypeKind::STK_ElementPointer);
}
-inline IRHandle make_descr_ptr(const void *Ptr, unsigned Arg = 0U) {
- return std::make_tuple(Ptr, Arg, SpecialTypeKind::STK_Pointer);
+inline IRHandle irhandle_ptr(const void *Ptr, unsigned Arg,
+ enum SpecialTypeKind STK) {
+ return std::make_tuple(Ptr, Arg, STK);
+}
+
+inline IRHandle handle(const Type *Ty) {
+ const Type *WrpTy = unifyPtrType(Ty);
+ return irhandle_ptr(WrpTy, Ty->getTypeID(), STK_Type);
}
+
+inline IRHandle handle(const Value *V) {
+ return irhandle_ptr(V, V->getValueID(), STK_Value);
+}
+
+inline IRHandle handle(const MachineInstr *KeyMI) {
+ return irhandle_ptr(KeyMI, SPIRV::to_hash(KeyMI), STK_MachineInstr);
+}
+
} // namespace SPIRV
// Bi-directional mappings between LLVM entities and (v-reg, machine function)
// pairs support management of unique SPIR-V definitions per machine function
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
- DenseMap<std::pair<SPIRV::IRHandle, const MachineFunction *>,
- const MachineInstr *>
- Vregs;
- DenseMap<const MachineInstr *, SPIRV::IRHandle> Defs;
+ DenseMap<SPIRV::IRHandleMF, SPIRV::MIHandle> Vregs;
+ DenseMap<SPIRV::MIHandle, SPIRV::IRHandle> Defs;
public:
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
+ if (std::get<1>(Handle) == 17 && std::get<2>(Handle) == 8) {
+ const Value *Ptr = (const Value *)std::get<0>(Handle);
+ if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Ptr)) {
+ if (CI->getZExtValue() == 8 || CI->getZExtValue() == 5) {
+ [[maybe_unused]] uint64_t v = CI->getZExtValue();
+ }
+ }
+ }
+ auto MIKey = SPIRV::getMIKey(MI);
auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MI);
+ Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MIKey);
if (Inserted) {
- auto [_, IsConsistent] = Defs.insert_or_assign(MI, Handle);
+ [[maybe_unused]] auto [_, IsConsistent] =
+ Defs.insert_or_assign(MIKey, Handle);
assert(IsConsistent);
}
return Inserted;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
- if (auto It = Defs.find(MI); It != Defs.end()) {
- Res = Vregs.erase(std::make_pair(It->second, MI->getMF()));
+ if (auto It = Defs.find(SPIRV::getMIKey(MI)); It != Defs.end()) {
+ Res = Vregs.erase(SPIRV::getIRHandleMF(It->second, MI->getMF()));
Defs.erase(It);
}
return Res;
}
const MachineInstr *findMI(SPIRV::IRHandle Handle,
const MachineFunction *MF) {
- if (auto It = Vregs.find(std::make_pair(Handle, MF)); It != Vregs.end())
- return It->second;
- return nullptr;
+ auto It = Vregs.find(SPIRV::getIRHandleMF(Handle, MF));
+ if (It == Vregs.end())
+ return nullptr;
+ auto [MI, Hash] = It->second;
+ if (SPIRV::to_hash(MI) != Hash) {
+ erase(MI);
+ return nullptr;
+ }
+ return MI;
}
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
const MachineInstr *MI = findMI(Handle, MF);
@@ -154,38 +217,28 @@ class SPIRVIRMapping {
}
// helpers
- bool add(const Type *Ty, const MachineInstr *MI) {
- return add(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MI);
- }
- bool add(const void *Key, const MachineInstr *MI) {
- return add(SPIRV::make_descr_ptr(Key), MI);
- }
bool add(const Type *PointeeTy, unsigned AddressSpace,
const MachineInstr *MI) {
- return add(SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace),
- MI);
- }
- Register find(const Type *Ty, const MachineFunction *MF) {
- return find(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
- }
- const MachineInstr *findMI(const Type *Ty, const MachineFunction *MF) {
- return findMI(SPIRV::make_descr_ptr(unifyPtrType(Ty)), MF);
- }
- Register find(const void *Key, const MachineFunction *MF) {
- return find(SPIRV::make_descr_ptr(Key), MF);
- }
- const MachineInstr *findMI(const void *Key, const MachineFunction *MF) {
- return findMI(SPIRV::make_descr_ptr(Key), MF);
+ return add(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MI);
}
Register find(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return find(
- SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ return find(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MF);
}
const MachineInstr *findMI(const Type *PointeeTy, unsigned AddressSpace,
const MachineFunction *MF) {
- return findMI(
- SPIRV::make_descr_pointee(unifyPtrType(PointeeTy), AddressSpace), MF);
+ return findMI(SPIRV::irhandle_pointee(PointeeTy, AddressSpace), MF);
+ }
+
+ template <typename T> bool add(const T *Obj, const MachineInstr *MI) {
+ return add(SPIRV::handle(Obj), MI);
+ }
+ template <typename T> Register find(const T *Obj, const MachineFunction *MF) {
+ return find(SPIRV::handle(Obj), MF);
+ }
+ template <typename T>
+ const MachineInstr *findMI(const T *Obj, const MachineFunction *MF) {
+ return findMI(SPIRV::handle(Obj), MF);
}
};
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index a8f862271dbab..4b9bddd661f63 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -15,6 +15,7 @@ include "SPIRVSymbolicOperands.td"
// Codegen only metadata instructions
let isCodeGenOnly=1 in {
+ def TYPEREF: Pseudo<(outs), (ins ID:$src_id, TYPE:$src_ty)>;
def ASSIGN_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def DECL_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def GET_ID: Pseudo<(outs iID:$dst_id), (ins iID:$src)>;
@@ -28,8 +29,10 @@ let isCodeGenOnly=1 in {
def SPVTypeBin : SDTypeProfile<1, 2, []>;
def assigntype : SDNode<"SPIRVISD::AssignType", SPVTypeBin>;
+def typeref : SDNode<"SPIRVISD::TypeRef", SPVTypeBin>;
def : GINodeEquiv<ASSIGN_TYPE, assigntype>;
+def : GINodeEquiv<TYPEREF, typeref>;
class BinOp<string name, bits<16> opCode, list<dag> pattern=[]>
: Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, ID:$src, ID:$src2),
@@ -472,11 +475,8 @@ def OpConvertBF16ToFINTEL : UnOp<"OpConvertBF16ToFINTEL", 6117>;
// 3.42.12 Composite Instructions
-//def OpVectorExtractDynamic: Op<77, (outs ID:$res), (ins TYPE:$type, vID:$vec, ID:$idx),
-// "$res = OpVectorExtractDynamic $type $vec $idx", [(set ID:$res, (assigntype (extractelt vID:$vec, ID:$idx), TYPE:$type))]>;
def OpVectorExtractDynamic: Op<77, (outs ID:$res), (ins TYPE:$type, vID:$vec, ID:$idx),
"$res = OpVectorExtractDynamic $type $vec $idx">;
-
def OpVectorInsertDynamic: Op<78, (outs ID:$res), (ins TYPE:$ty, ID:$vec, ID:$comp, ID:$idx),
"$res = OpVectorInsertDynamic $ty $vec $comp $idx">;
def OpVectorShuffle: Op<79, (outs ID:$res), (ins TYPE:$ty, ID:$v1, ID:$v2, variable_ops),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index aa82f7f7d936a..8f1ac07dd9450 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -393,27 +393,84 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
}
for (const auto &MBB : MF) {
for (const auto &MI : MBB) {
- if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
- continue;
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
-
- const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
- const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
- if (DstRC != SrcRC && SrcRC)
- MRI.setRegClass(DstReg, SrcRC);
+ if (MI.getOpcode() == SPIRV::ASSIGN_TYPE) {
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+
+ const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
+ const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
+ if (DstRC != SrcRC && SrcRC)
+ MRI.setRegClass(DstReg, SrcRC);
+ } else if (MI.getOpcode() == SPIRV::TYPEREF) {
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+ }
}
}
}
-static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI);
+// Return true if the type represents a constant register
+static bool isConstReg(MachineRegisterInfo *MRI, MachineInstr *OpDef,
+ SmallPtrSet<SPIRVType *, 4> &Visited) {
+ OpDef = passCopy(OpDef, MRI);
+
+ if (Visited.contains(OpDef))
+ return true;
+ Visited.insert(OpDef);
+
+ unsigned Opcode = OpDef->getOpcode();
+ switch (Opcode) {
+ case TargetOpcode::G_CONSTANT:
+ case TargetOpcode::G_FCONSTANT:
+ return true;
+ case TargetOpcode::G_INTRINSIC:
+ case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
+ case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
+ return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
+ Intrinsic::spv_const_composite;
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_SPLAT_VECTOR: {
+ for (unsigned i = OpDef->getNumExplicitDefs(); i < OpDef->getNumOperands();
+ i++) {
+ MachineInstr *OpNestedDef =
+ OpDef->getOperand(i).isReg()
+ ? MRI->getVRegDef(OpDef->getOperand(i).getReg())
+ : nullptr;
+ if (OpNestedDef && !isConstReg(MRI, OpNestedDef, Visited))
+ return false;
+ }
+ return true;
+ case SPIRV::OpConstantTrue:
+ case SPIRV::OpConstantFalse:
+ case SPIRV::OpConstantI:
+ case SPIRV::OpConstantF:
+ case SPIRV::OpConstantComposite:
+ case SPIRV::OpConstantCompositeContinuedINTEL:
+ case SPIRV::OpConstantSampler:
+ case SPIRV::OpConstantNull:
+ case SPIRV::OpUndef:
+ case SPIRV::OpConstantFunctionPointerINTEL:
+ return true;
+ }
+ }
+ return false;
+}
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
+// Return true if the virtual register represents a constant
+static bool isConstReg(MachineRegisterInfo *MRI, Register OpReg) {
+ SmallPtrSet<SPIRVType *, 4> Visited;
+ if (MachineInstr *OpDef = MRI->getVRegDef(OpReg))
+ return isConstReg(MRI, OpDef, Visited);
+ return false;
+}
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI) {
for (const auto &MO : MI.all_defs()) {
@@ -466,6 +523,27 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
+ } else if (Opcode == SPIRV::TYPEREF) {
+ Register SrcReg = I.getOperand(0).getReg();
+ auto *Def = MRI->getVRegDef(SrcReg);
+ if (isTypeFoldingSupported(Def->getOpcode())) {
+ bool Res = selectImpl(I, *CoverageInfo);
+ LLVM_DEBUG({
+ if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
+ dbgs() << "Unexpected pattern in ASSIGN_TYPE.\nInstruction: ";
+ I.print(dbgs());
+ }
+ });
+ assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
+ if (Res) {
+ if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
+ DeadMIs.insert(Def);
+ return Res;
+ }
+ }
+ GR.invalidateMachineInstr(&I);
+ I.removeFromParent();
+ return true;
} else if (I.getNumDefs() == 1) {
// Make all vregs 64 bits (for SPIR-V IDs).
MRI->setType(I.getOperand(0).getReg(), LLT::scalar(64));
@@ -766,7 +844,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
assert(((*II).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
(*II).getOpcode() == TargetOpcode::COPY ||
(*II).getOpcode() == SPIRV::OpVariable) &&
- isImm(I.getOperand(2), MRI));
+ getImm(I.getOperand(2), MRI));
// It may be the initialization of a global variable.
bool IsGVInit = false;
for (MachineRegisterInfo::use_instr_iterator
@@ -2003,27 +2081,30 @@ bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
auto ExtractOp =
Signed ? SPIRV::OpBitFieldSExtract : SPIRV::OpBitFieldUExtract;
+ bool ZeroAsNull = STI.isOpenCLEnv();
// Extract the i8 element, multiply and add it to the accumulator
for (unsigned i = 0; i < 4; i++) {
// A[i]
Register AElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(AElt)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(2).getReg())
- .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(AElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(2).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// B[i]
Register BElt = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(BElt)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(I.getOperand(3).getReg())
- .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(BElt)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(I.getOperand(3).getReg())
+ .addUse(GR.getOrCreateConstInt(i * 8, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// A[i] * B[i]
Register Mul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
@@ -2036,13 +2117,14 @@ bool SPIRVInstructionSelector::selectDot4AddPackedExpansion(
// Discard 24 highest-bits so that stored i32 register is i8 equivalent
Register MaskMul = MRI->createVirtualRegister(&SPIRV::IDRegClass);
- Result &= BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
- .addDef(MaskMul)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(Mul)
- .addUse(GR.getOrCreateConstInt(0, I, EltType, TII))
- .addUse(GR.getOrCreateConstInt(8, I, EltType, TII))
- .constrainAllUses(TII, TRI, RBI);
+ Result &=
+ BuildMI(BB, I, I.getDebugLoc(), TII.get(ExtractOp))
+ .addDef(MaskMul)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(Mul)
+ .addUse(GR.getOrCreateConstInt(0, I, EltType, TII, ZeroAsNull))
+ .addUse(GR.getOrCreateConstInt(8, I, EltType, TII, ZeroAsNull))
+ .constrainAllUses(TII, TRI, RBI);
// Acc = Acc + A[i] * B[i]
Register Sum =
@@ -2139,7 +2221,7 @@ bool SPIRVInstructionSelector::selectWaveOpInst(Register ResVReg,
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I,
- IntTy, TII));
+ IntTy, TII, STI.isOpenCLEnv()));
for (unsigned J = 2; J < I.getNumOperands(); J++) {
BMI.addUse(I.getOperand(J).getReg());
@@ -2158,15 +2240,15 @@ bool SPIRVInstructionSelector::selectWaveActiveCountBits(
SPIRV::OpGroupNonUniformBallot);
MachineBasicBlock &BB = *I.getParent();
- Result &=
- BuildMI(BB, I, I.getDebugLoc(),
- TII.get(SPIRV::OpGroupNonUniformBallotBitCount))
- .addDef(ResVReg)
- .addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
- .addImm(SPIRV::GroupOperation::Reduce)
- .addUse(BallotReg)
- .constrainAllUses(TII, TRI, RBI);
+ Result &= BuildMI(BB, I, I.getDebugLoc(),
+ TII.get(SPIRV::OpGroupNonUniformBallotBitCount))
+ .addDef(ResVReg)
+ .addUse(GR.getSPIRVTypeID(ResType))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy,
+ TII, STI.isOpenCLEnv()))
+ .addImm(SPIRV::GroupOperation::Reduce)
+ .addUse(BallotReg)
+ .constrainAllUses(TII, TRI, RBI);
return Result;
}
@@ -2193,7 +2275,8 @@ bool SPIRVInstructionSelector::selectWaveReduceMax(Register ResVReg,
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
+ STI.isOpenCLEnv()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg())
.constrainAllUses(TII, TRI, RBI);
@@ -2219,7 +2302,8 @@ bool SPIRVInstructionSelector::selectWaveReduceSum(Register ResVReg,
return BuildMI(BB, I, I.getDebugLoc(), TII.get(Opcode))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
- .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII))
+ .addUse(GR.getOrCreateConstInt(SPIRV::Scope::Subgroup, I, IntTy, TII,
+ STI.isOpenCLEnv()))
.addImm(SPIRV::GroupOperation::Reduce)
.addUse(I.getOperand(2).getReg());
}
@@ -2247,6 +2331,8 @@ bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
return false;
Register OpReg = I.getOperand(1).getReg();
if (MachineInstr *Def = MRI->getVRegDef(OpReg)) {
+ if (Def->getOpcode() == TargetOpcode::COPY)
+ Def = MRI->getVRegDef(Def->getOperand(1).getReg());
Register Reg;
switch (Def->getOpcode()) {
case SPIRV::ASSIGN_TYPE:
@@ -2275,82 +2361,6 @@ bool SPIRVInstructionSelector::selectFreeze(Register ResVReg,
return false;
}
-static unsigned getArrayComponentCount(MachineRegisterInfo *MRI,
- const SPIRVType *ResType) {
- Register OpReg = ResType->getOperand(2).getReg();
- SPIRVType *OpDef = MRI->getVRegDef(OpReg);
- if (!OpDef)
- return 0;
- if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
- OpDef->getOperand(1).isReg()) {
- if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
- OpDef = RefDef;
- }
- unsigned N = OpDef->getOpcode() == TargetOpcode::G_CONSTANT
- ? OpDef->getOperand(1).getCImm()->getValue().getZExtValue()
- : 0;
- return N;
-}
-
-// Return true if the type represents a constant register
-static bool isConstReg(MachineRegisterInfo *MRI, SPIRVType *OpDef,
- SmallPtrSet<SPIRVType *, 4> &Visited) {
- if (OpDef->getOpcode() == SPIRV::ASSIGN_TYPE &&
- OpDef->getOperand(1).isReg()) {
- if (SPIRVType *RefDef = MRI->getVRegDef(OpDef->getOperand(1).getReg()))
- OpDef = RefDef;
- }
-
- if (Visited.contains(OpDef))
- return true;
- Visited.insert(OpDef);
-
- unsigned Opcode = OpDef->getOpcode();
- switch (Opcode) {
- case TargetOpcode::G_CONSTANT:
- case TargetOpcode::G_FCONSTANT:
- return true;
- case TargetOpcode::G_INTRINSIC:
- case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
- case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
- return cast<GIntrinsic>(*OpDef).getIntrinsicID() ==
- Intrinsic::spv_const_composite;
- case TargetOpcode::G_BUILD_VECTOR:
- case TargetOpcode::G_SPLAT_VECTOR: {
- for (unsigned i = OpDef->getNumExplicitDefs(); i < OpDef->getNumOperands();
- i++) {
- SPIRVType *OpNestedDef =
- OpDef->getOperand(i).isReg()
- ? MRI->getVRegDef(OpDef->getOperand(i).getReg())
- : nullptr;
- if (OpNestedDef && !isConstReg(MRI, OpNestedDef, Visited))
- return false;
- }
- return true;
- case SPIRV::OpConstantTrue:
- case SPIRV::OpConstantFalse:
- case SPIRV::OpConstantI:
- case SPIRV::OpConstantF:
- case SPIRV::OpConstantComposite:
- case SPIRV::OpConstantCompositeContinuedINTEL:
- case SPIRV::OpConstantSampler:
- case SPIRV::OpConstantNull:
- case SPIRV::OpUndef:
- case SPIRV::OpConstantFunctionPointerINTEL:
- return true;
- }
- }
- return false;
-}
-
-// Return true if the virtual register represents a constant
-static bool isConstReg(MachineRegisterInfo *MRI, Register OpReg) {
- SmallPtrSet<SPIRVType *, 4> Visited;
- if (SPIRVType *OpDef = MRI->getVRegDef(OpReg))
- return isConstReg(MRI, OpDef, Visited);
- return false;
-}
-
bool SPIRVInstructionSelector::selectBuildVector(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
@@ -2740,7 +2750,15 @@ bool SPIRVInstructionSelector::selectConst(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
if (TyOpcode == SPIRV::OpTypeInt) {
assert(Imm.getBitWidth() <= 64 && "Unsupported integer width!");
- Register Reg = GR.getOrCreateConstInt(Imm.getZExtValue(), I, ResType, TII);
+ const ConstantInt *CI =
+ ConstantInt::get(const_cast<IntegerType *>(cast<IntegerType>(
+ GR.getTypeForSPIRVType(ResType))),
+ Imm.getZExtValue());
+ const MachineInstr *ConstMI = GR.findMI(CI, GR.CurMF);
+ Register Reg =
+ (ConstMI && ConstMI != &I)
+ ? ConstMI->getOperand(0).getReg()
+ : GR.createConstInt(CI, I, ResType, TII, STI.isOpenCLEnv());
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
}
auto MIB = BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpConstantI))
@@ -2761,25 +2779,6 @@ bool SPIRVInstructionSelector::selectOpUndef(Register ResVReg,
.constrainAllUses(TII, TRI, RBI);
}
-static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
- assert(MO.isReg());
- const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
- if (TypeInst->getOpcode() == SPIRV::ASSIGN_TYPE) {
- assert(TypeInst->getOperand(1).isReg());
- MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
- return ImmInst->getOpcode() == TargetOpcode::G_CONSTANT;
- }
- return TypeInst->getOpcode() == SPIRV::OpConstantI;
-}
-
-static int64_t foldImm(const MachineOperand &MO, MachineRegisterInfo *MRI) {
- const SPIRVType *TypeInst = MRI->getVRegDef(MO.getReg());
- if (TypeInst->getOpcode() == SPIRV::OpConstantI)
- return TypeInst->getOperand(2).getImm();
- MachineInstr *ImmInst = MRI->getVRegDef(TypeInst->getOperand(1).getReg());
- assert(ImmInst->getOpcode() == TargetOpcode::G_CONSTANT);
- return ImmInst->getOperand(1).getCImm()->getZExtValue();
-}
bool SPIRVInstructionSelector::selectInsertVal(Register ResVReg,
const SPIRVType *ResType,
@@ -2813,7 +2812,7 @@ bool SPIRVInstructionSelector::selectExtractVal(Register ResVReg,
bool SPIRVInstructionSelector::selectInsertElt(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
- if (isImm(I.getOperand(4), MRI))
+ if (getImm(I.getOperand(4), MRI))
return selectInsertVal(ResVReg, ResType, I);
MachineBasicBlock &BB = *I.getParent();
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorInsertDynamic))
@@ -2828,7 +2827,7 @@ bool SPIRVInstructionSelector::selectInsertElt(Register ResVReg,
bool SPIRVInstructionSelector::selectExtractElt(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I) const {
- if (isImm(I.getOperand(3), MRI))
+ if (getImm(I.getOperand(3), MRI))
return selectExtractVal(ResVReg, ResType, I);
MachineBasicBlock &BB = *I.getParent();
return BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpVectorExtractDynamic))
@@ -2875,7 +2874,7 @@ bool SPIRVInstructionSelector::wrapIntoSpecConstantOp(
unsigned Lim = I.getNumExplicitOperands();
for (unsigned i = I.getNumExplicitDefs() + 1; i < Lim; ++i) {
Register OpReg = I.getOperand(i).getReg();
- SPIRVType *OpDefine = MRI->getVRegDef(OpReg);
+ MachineInstr *OpDefine = MRI->getVRegDef(OpReg);
SPIRVType *OpType = GR.getSPIRVTypeForVReg(OpReg);
SmallPtrSet<SPIRVType *, 4> Visited;
if (!OpDefine || !OpType || isConstReg(MRI, OpDefine, Visited) ||
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
index daa8ea52ffe03..520ea169fd638 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.cpp
@@ -24,43 +24,6 @@ using namespace llvm;
using namespace llvm::LegalizeActions;
using namespace llvm::LegalityPredicates;
-// clang-format off
-static const std::set<unsigned> TypeFoldingSupportingOpcs = {
- TargetOpcode::G_ADD,
- TargetOpcode::G_FADD,
- TargetOpcode::G_STRICT_FADD,
- TargetOpcode::G_SUB,
- TargetOpcode::G_FSUB,
- TargetOpcode::G_STRICT_FSUB,
- TargetOpcode::G_MUL,
- TargetOpcode::G_FMUL,
- TargetOpcode::G_STRICT_FMUL,
- TargetOpcode::G_SDIV,
- TargetOpcode::G_UDIV,
- TargetOpcode::G_FDIV,
- TargetOpcode::G_STRICT_FDIV,
- TargetOpcode::G_SREM,
- TargetOpcode::G_UREM,
- TargetOpcode::G_FREM,
- TargetOpcode::G_STRICT_FREM,
- TargetOpcode::G_FNEG,
- TargetOpcode::G_CONSTANT,
- TargetOpcode::G_FCONSTANT,
- TargetOpcode::G_AND,
- TargetOpcode::G_OR,
- TargetOpcode::G_XOR,
- TargetOpcode::G_SHL,
- TargetOpcode::G_ASHR,
- TargetOpcode::G_LSHR,
- TargetOpcode::G_SELECT,
- TargetOpcode::G_EXTRACT_VECTOR_ELT,
-};
-// clang-format on
-
-bool isTypeFoldingSupported(unsigned Opcode) {
- return TypeFoldingSupportingOpcs.count(Opcode) > 0;
-}
-
LegalityPredicate typeOfExtendedScalars(unsigned TypeIdx, bool IsExtendedInts) {
return [IsExtendedInts, TypeIdx](const LegalityQuery &Query) {
const LLT Ty = Query.Types[TypeIdx];
@@ -181,7 +144,7 @@ SPIRVLegalizerInfo::SPIRVLegalizerInfo(const SPIRVSubtarget &ST) {
return IsExtendedInts && Ty.isValid();
};
- for (auto Opc : TypeFoldingSupportingOpcs)
+ for (auto Opc : getTypeFoldingSupportedOpcodes())
getActionDefinitionsBuilder(Opc).custom();
getActionDefinitionsBuilder(G_GLOBAL_VALUE).alwaysLegal();
diff --git a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
index f18b15b7f1696..6335f211e1986 100644
--- a/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
+++ b/llvm/lib/Target/SPIRV/SPIRVLegalizerInfo.h
@@ -16,8 +16,6 @@
#include "SPIRVGlobalRegistry.h"
#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
-bool isTypeFoldingSupported(unsigned Opcode);
-
namespace llvm {
class LLVMContext;
diff --git a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
index e7b942e42b0a2..4c20688e9e983 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPostLegalizer.cpp
@@ -41,15 +41,11 @@ class SPIRVPostLegalizer : public MachineFunctionPass {
};
} // namespace
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
-
namespace llvm {
// Defined in SPIRVPreLegalizer.cpp.
-extern Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
- SPIRVGlobalRegistry *GR,
- MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI);
+extern void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpirvTy,
+ SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI);
extern void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR);
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index da837c9ed85dd..0ece31ee88abe 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -98,7 +98,8 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
SrcMI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF))
TargetExtConstTypes[SrcMI] = Const->getType();
if (Const->isNullValue()) {
- MachineIRBuilder MIB(MF);
+ MachineBasicBlock &DepMBB = MF.front();
+ MachineIRBuilder MIB(DepMBB, DepMBB.getFirstNonPHI());
SPIRVType *ExtType = GR->getOrCreateSPIRVType(
Const->getType(), MIB, SPIRV::AccessQualifier::ReadWrite,
true);
@@ -128,13 +129,17 @@ addConstantsToTrack(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (!MRI.getRegClassOrNull(Reg) && RC)
MRI.setRegClass(Reg, RC);
MRI.replaceRegWith(MI->getOperand(0).getReg(), Reg);
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
}
- for (MachineInstr *MI : ToEraseComposites)
+ for (MachineInstr *MI : ToEraseComposites) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void foldConstantsIntoIntrinsics(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR,
MachineIRBuilder MIB) {
SmallVector<MachineInstr *, 64> ToErase;
for (MachineBasicBlock &MBB : MF) {
@@ -149,8 +154,10 @@ static void foldConstantsIntoIntrinsics(MachineFunction &MF,
}
ToErase.push_back(&MI);
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
ToErase.clear();
}
}
@@ -219,8 +226,10 @@ static void selectOpBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToErase.push_back(&MI);
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
@@ -264,8 +273,10 @@ static void insertBitcasts(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// Translating GV, IRTranslator sometimes generates following IR:
@@ -384,7 +395,7 @@ static void widenScalarLLTNextPow2(Register Reg, MachineRegisterInfo &MRI) {
if (NewSz != Sz)
MRI.setType(Reg, LLT::scalar(NewSz));
}
-
+/*
static std::pair<Register, unsigned>
createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI,
const SPIRVGlobalRegistry &GR) {
@@ -406,7 +417,7 @@ createNewIdReg(SPIRVType *SpvType, Register SrcReg, MachineRegisterInfo &MRI,
GetIdOp = SPIRV::GET_vID;
return {Reg, GetIdOp};
}
-
+*/
static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def) {
MachineBasicBlock &MBB = *Def->getParent();
MachineBasicBlock::iterator DefIt =
@@ -418,21 +429,31 @@ static void setInsertPtAfterDef(MachineIRBuilder &MIB, MachineInstr *Def) {
MIB.setInsertPt(MBB, DefIt);
}
-// Insert ASSIGN_TYPE instuction between Reg and its definition, set NewReg as
-// a dst of the definition, assign SPIRVType to both registers. If SpvType is
-// provided, use it as SPIRVType in ASSIGN_TYPE, otherwise create it from Ty.
-// It's used also in SPIRVBuiltins.cpp.
-// TODO: maybe move to SPIRVUtils.
namespace llvm {
-Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
- SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
- MachineRegisterInfo &MRI) {
+void insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
+ SPIRVGlobalRegistry *GR, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI) {
assert((Ty || SpvType) && "Either LLVM or SPIRV type is expected.");
MachineInstr *Def = MRI.getVRegDef(Reg);
setInsertPtAfterDef(MIB, Def);
- SpvType = SpvType ? SpvType
- : GR->getOrCreateSPIRVType(
- Ty, MIB, SPIRV::AccessQualifier::ReadWrite, true);
+ if (!SpvType)
+ SpvType = GR->getOrCreateSPIRVType(Ty, MIB,
+ SPIRV::AccessQualifier::ReadWrite, true);
+
+ if (!isTypeFoldingSupported(Def->getOpcode())) {
+ // No need to generate SPIRV::ASSIGN_TYPE pseudo-instruction
+ if (!GR->getSPIRVTypeForVReg(Reg, &MRI.getMF())) {
+ if (!MRI.getRegClassOrNull(Reg))
+ MRI.setRegClass(Reg, GR->getRegClass(SpvType));
+ if (!MRI.getType(Reg).isValid())
+ MRI.setType(Reg, GR->getRegType(SpvType));
+ GR->assignSPIRVTypeToVReg(SpvType, Reg, MIB.getMF());
+ }
+ return;
+ }
+
+ // Tablegen definition assumes SPIRV::ASSIGN_TYPE pseudo-instruction is
+ // present after each auto-folded instruction to take a type reference from.
Register NewReg = MRI.createGenericVirtualRegister(MRI.getType(Reg));
if (auto *RC = MRI.getRegClassOrNull(Reg)) {
MRI.setRegClass(NewReg, RC);
@@ -460,12 +481,27 @@ Register insertAssignInstr(Register Reg, Type *Ty, SPIRVType *SpvType,
break;
}
}
- return NewReg;
}
void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
MIB.setInsertPt(*MI.getParent(), MI.getIterator());
+ for (auto &Op : MI.operands()) {
+ if (!Op.isReg() || Op.isDef())
+ continue;
+ Register OpReg = Op.getReg();
+ SPIRVType *SpvType = GR->getSPIRVTypeForVReg(OpReg);
+ assert(SpvType);
+ if (!MRI.getRegClassOrNull(OpReg))
+ MRI.setRegClass(OpReg, GR->getRegClass(SpvType));
+ if (!MRI.getType(OpReg).isValid())
+ MRI.setType(OpReg, GR->getRegType(SpvType));
+ }
+}
+
+/*void processInstr2(MachineInstr &MI, MachineIRBuilder &MIB,
+ MachineRegisterInfo &MRI, SPIRVGlobalRegistry *GR) {
+ MIB.setInsertPt(*MI.getParent(), MI.getIterator());
for (auto &Op : MI.operands()) {
if (!Op.isReg() || Op.isDef())
continue;
@@ -478,7 +514,7 @@ void processInstr(MachineInstr &MI, MachineIRBuilder &MIB,
MRI.setRegClass(OpReg, RC);
Op.setReg(IdOpInfo.first);
}
-}
+}*/
} // namespace llvm
static void
@@ -528,7 +564,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ Def->getOpcode() != SPIRV::TYPEREF)
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
MF.getRegInfo());
ToErase.push_back(&MI);
@@ -539,7 +576,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ Def->getOpcode() != SPIRV::TYPEREF)
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
ToErase.push_back(&MI);
} else if (MIOp == TargetOpcode::FAKE_USE && MI.getNumOperands() > 0) {
@@ -576,7 +614,8 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
continue;
- if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
+ if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE ||
+ UseMI.getOpcode() == SPIRV::TYPEREF)
NeedAssignType = false;
}
Type *Ty = nullptr;
@@ -620,11 +659,18 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
} else if (ElemMI->getOpcode() == TargetOpcode::G_FCONSTANT) {
ElemTy = ElemMI->getOperand(1).getFPImm()->getType();
} else {
- // There may be a case when we already know Reg's type.
- MachineInstr *NextMI = MI.getNextNode();
- if (!NextMI || NextMI->getOpcode() != SPIRV::ASSIGN_TYPE ||
- NextMI->getOperand(1).getReg() != Reg)
- llvm_unreachable("Unexpected opcode");
+ if (const SPIRVType *ElemSpvType =
+ GR->getSPIRVTypeForVReg(MI.getOperand(1).getReg(), &MF))
+ ElemTy = const_cast<Type *>(GR->getTypeForSPIRVType(ElemSpvType));
+ if (!ElemTy) {
+ // There may be a case when we already know Reg's type.
+ MachineInstr *NextMI = MI.getNextNode();
+ if (!NextMI ||
+ (NextMI->getOpcode() != SPIRV::ASSIGN_TYPE &&
+ NextMI->getOpcode() != SPIRV::TYPEREF) ||
+ NextMI->getOperand(1).getReg() != Reg)
+ llvm_unreachable("Unexpected opcode");
+ }
}
if (ElemTy)
Ty = VectorType::get(
@@ -649,6 +695,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
auto It = RegsAlreadyAddedToDT.find(MI);
if (It != RegsAlreadyAddedToDT.end())
MRI.replaceRegWith(MI->getOperand(0).getReg(), It->second);
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
}
@@ -671,9 +718,6 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
}
}
-// Defined in SPIRVLegalizerInfo.cpp.
-extern bool isTypeFoldingSupported(unsigned Opcode);
-
static void processInstrsWithTypeFolding(MachineFunction &MF,
SPIRVGlobalRegistry *GR,
MachineIRBuilder MIB) {
@@ -788,8 +832,10 @@ insertInlineAsmProcess(MachineFunction &MF, SPIRVGlobalRegistry *GR,
for (unsigned IntrIdx = 3; IntrIdx < I1->getNumOperands(); ++IntrIdx)
AsmCall.addUse(I1->getOperand(IntrIdx).getReg());
}
- for (MachineInstr *MI : ToProcess)
+ for (MachineInstr *MI : ToProcess) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
static void insertInlineAsm(MachineFunction &MF, SPIRVGlobalRegistry *GR,
@@ -835,8 +881,10 @@ static void insertSpirvDecorations(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ToErase.push_back(&MI);
}
}
- for (MachineInstr *MI : ToErase)
+ for (MachineInstr *MI : ToErase) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// LLVM allows the switches to use registers as cases, while SPIR-V required
@@ -875,7 +923,8 @@ static void processSwitchesConstants(MachineFunction &MF,
// Some instructions are used during CodeGen but should never be emitted.
// Cleaning up those.
-static void cleanupHelperInstructions(MachineFunction &MF) {
+static void cleanupHelperInstructions(MachineFunction &MF,
+ SPIRVGlobalRegistry *GR) {
SmallVector<MachineInstr *, 8> ToEraseMI;
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : MBB) {
@@ -885,8 +934,10 @@ static void cleanupHelperInstructions(MachineFunction &MF) {
}
}
- for (MachineInstr *MI : ToEraseMI)
+ for (MachineInstr *MI : ToEraseMI) {
+ GR->invalidateMachineInstr(MI);
MI->eraseFromParent();
+ }
}
// Find all usages of G_BLOCK_ADDR in our intrinsics and replace those
@@ -988,6 +1039,7 @@ static void processBlockAddr(MachineFunction &MF, SPIRVGlobalRegistry *GR,
ConstantExpr::getIntToPtr(Replacement, BA->getType()));
BA->destroyConstant();
}
+ GR->invalidateMachineInstr(BlockAddrI);
BlockAddrI->eraseFromParent();
}
}
@@ -1036,13 +1088,13 @@ bool SPIRVPreLegalizer::runOnMachineFunction(MachineFunction &MF) {
DenseMap<MachineInstr *, Type *> TargetExtConstTypes;
// to keep record of tracked constants
addConstantsToTrack(MF, GR, ST, TargetExtConstTypes);
- foldConstantsIntoIntrinsics(MF, MIB);
+ foldConstantsIntoIntrinsics(MF, GR, MIB);
insertBitcasts(MF, GR, MIB);
generateAssignInstrs(MF, GR, MIB, TargetExtConstTypes);
processSwitchesConstants(MF, GR, MIB);
processBlockAddr(MF, GR, MIB);
- cleanupHelperInstructions(MF);
+ cleanupHelperInstructions(MF, GR);
processInstrsWithTypeFolding(MF, GR, MIB);
removeImplicitFallthroughs(MF, MIB);
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
index 269524b2410c2..71f08aedd7777 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizerCombiner.cpp
@@ -96,16 +96,21 @@ void applySPIRVDistance(MachineInstr &MI, MachineRegisterInfo &MRI,
.addUse(SubOperand1) // Operand X
.addUse(SubOperand2); // Operand Y
+ SPIRVGlobalRegistry *GR =
+ MI.getMF()->getSubtarget<SPIRVSubtarget>().getSPIRVGlobalRegistry();
auto RemoveAllUses = [&](Register Reg) {
SmallVector<MachineInstr *, 4> UsesToErase;
for (auto &UseMI : MRI.use_instructions(Reg))
UsesToErase.push_back(&UseMI);
// calling eraseFromParent to early invalidates the iterator.
- for (auto *MIToErase : UsesToErase)
+ for (auto *MIToErase : UsesToErase) {
+ GR->invalidateMachineInstr(MIToErase);
MIToErase->eraseFromParent();
+ }
};
RemoveAllUses(SubDestReg); // remove all uses of FSUB Result
+ GR->invalidateMachineInstr(SubInstr);
SubInstr->eraseFromParent(); // remove FSUB instruction
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 8380cd579004d..6e6125c7bd66d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -186,7 +186,8 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
IsHeader = true;
} else if (IsHeader &&
- !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
+ !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::TYPEREF ||
+ Opcode == SPIRV::OpLabel)) {
++It;
break;
}
@@ -303,20 +304,7 @@ SPIRV::Scope::Scope getMemScope(LLVMContext &Ctx, SyncScope::ID Id) {
return SPIRV::Scope::Device;
return SPIRV::Scope::CrossDevice;
}
-/*
-MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
- const MachineRegisterInfo *MRI) {
- MachineInstr *MI = MRI->getVRegDef(ConstReg);
- //if (MI->getOpcode() == SPIRV::G_TRUNC || MI->getOpcode() == SPIRV::G_ZEXT)
- // return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
- if (MI->getOpcode() == SPIRV::ASSIGN_TYPE)
- return getDefInstrMaybeConstant(ConstReg = MI->getOperand(1).getReg(), MRI);
- if (auto *GI = dyn_cast<GIntrinsic>(MI))
- if (GI->is(Intrinsic::spv_track_constant))
- return MRI->getVRegDef(ConstReg = MI->getOperand(2).getReg());
- return MI;
-}
-*/
+
MachineInstr *getDefInstrMaybeConstant(Register &ConstReg,
const MachineRegisterInfo *MRI) {
MachineInstr *MI = MRI->getVRegDef(ConstReg);
@@ -860,4 +848,82 @@ void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
}
}
+const std::set<unsigned> &getTypeFoldingSupportedOpcodes() {
+ // clang-format off
+ static const std::set<unsigned> TypeFoldingSupportingOpcs = {
+ TargetOpcode::G_ADD,
+ TargetOpcode::G_FADD,
+ TargetOpcode::G_STRICT_FADD,
+ TargetOpcode::G_SUB,
+ TargetOpcode::G_FSUB,
+ TargetOpcode::G_STRICT_FSUB,
+ TargetOpcode::G_MUL,
+ TargetOpcode::G_FMUL,
+ TargetOpcode::G_STRICT_FMUL,
+ TargetOpcode::G_SDIV,
+ TargetOpcode::G_UDIV,
+ TargetOpcode::G_FDIV,
+ TargetOpcode::G_STRICT_FDIV,
+ TargetOpcode::G_SREM,
+ TargetOpcode::G_UREM,
+ TargetOpcode::G_FREM,
+ TargetOpcode::G_STRICT_FREM,
+ TargetOpcode::G_FNEG,
+ TargetOpcode::G_CONSTANT,
+ TargetOpcode::G_FCONSTANT,
+ TargetOpcode::G_AND,
+ TargetOpcode::G_OR,
+ TargetOpcode::G_XOR,
+ TargetOpcode::G_SHL,
+ TargetOpcode::G_ASHR,
+ TargetOpcode::G_LSHR,
+ TargetOpcode::G_SELECT,
+ TargetOpcode::G_EXTRACT_VECTOR_ELT,
+ };
+ // clang-format on
+ return TypeFoldingSupportingOpcs;
+}
+
+bool isTypeFoldingSupported(unsigned Opcode) {
+ return getTypeFoldingSupportedOpcodes().count(Opcode) > 0;
+}
+
+// Traversing [g]MIR accounting for pseudo-instructions.
+MachineInstr *passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI) {
+ return (Def->getOpcode() == SPIRV::ASSIGN_TYPE ||
+ Def->getOpcode() == TargetOpcode::COPY)
+ ? MRI->getVRegDef(Def->getOperand(1).getReg())
+ : Def;
+}
+
+MachineInstr *getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = MRI->getVRegDef(MO.getReg()))
+ return passCopy(Def, MRI);
+ return nullptr;
+}
+
+MachineInstr *getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = getDef(MO, MRI)) {
+ if (Def->getOpcode() == TargetOpcode::G_CONSTANT ||
+ Def->getOpcode() == SPIRV::OpConstantI)
+ return Def;
+ }
+ return nullptr;
+}
+
+int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
+ if (MachineInstr *Def = getImm(MO, MRI)) {
+ if (Def->getOpcode() == SPIRV::OpConstantI)
+ return Def->getOperand(2).getImm();
+ if (Def->getOpcode() == TargetOpcode::G_CONSTANT)
+ return Def->getOperand(1).getCImm()->getZExtValue();
+ }
+ llvm_unreachable("Unexpected integer constant pattern");
+}
+
+unsigned getArrayComponentCount(const MachineRegisterInfo *MRI,
+ const MachineInstr *ResType) {
+ return foldImm(ResType->getOperand(2), MRI);
+}
+
} // namespace llvm
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h
index 180d3a29d170f..a0b8ba18fc7ba 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.h
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h
@@ -459,5 +459,17 @@ void createContinuedInstructions(MachineIRBuilder &MIRBuilder, unsigned Opcode,
ArrayRef<Register> Args,
Register ReturnRegister, Register TypeID);
+// Instruction selection directed by type folding.
+const std::set<unsigned> &getTypeFoldingSupportedOpcodes();
+bool isTypeFoldingSupported(unsigned Opcode);
+
+// Traversing [g]MIR accounting for pseudo-instructions.
+MachineInstr *passCopy(MachineInstr *Def, const MachineRegisterInfo *MRI);
+MachineInstr *getDef(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+MachineInstr *getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+int64_t foldImm(const MachineOperand &MO, const MachineRegisterInfo *MRI);
+unsigned getArrayComponentCount(const MachineRegisterInfo *MRI,
+ const MachineInstr *ResType);
+
} // namespace llvm
#endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H
diff --git a/llvm/test/CodeGen/SPIRV/atomicrmw.ll b/llvm/test/CodeGen/SPIRV/atomicrmw.ll
index 07576056117cb..a6cfe56cd06c3 100644
--- a/llvm/test/CodeGen/SPIRV/atomicrmw.ll
+++ b/llvm/test/CodeGen/SPIRV/atomicrmw.ll
@@ -4,8 +4,8 @@
; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-; CHECK: %[[#Int:]] = OpTypeInt 32 0
-; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstant %[[#Int]] 0{{$}}
+; CHECK-DAG: %[[#Int:]] = OpTypeInt 32 0
+; CHECK-DAG: %[[#Scope_CrossDevice:]] = OpConstantNull %[[#Int]]
; CHECK-DAG: %[[#MemSem_Acquire:]] = OpConstant %[[#Int]] 2
; CHECK-DAG: %[[#MemSem_Release:]] = OpConstant %[[#Int]] 4{{$}}
; CHECK-DAG: %[[#MemSem_AcquireRelease:]] = OpConstant %[[#Int]] 8
diff --git a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
index 93ea49afc6589..2b29b4fca5671 100644
--- a/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
+++ b/llvm/test/CodeGen/SPIRV/debug-info/debug-type-pointer.ll
@@ -6,23 +6,23 @@
; CHECK-MIR-DAG: [[i32type:%[0-9]+\:type]] = OpTypeInt 32, 0
; CHECK-MIR-DAG: [[void_type:%[0-9]+\:type\(s64\)]] = OpTypeVoid
-; CHECK-MIR-DAG: [[i32_8:%[0-9]+\:iid]] = OpConstantI [[i32type]], 8
-; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:iid]] = OpConstantI [[i32type]], 0
-; CHECK-MIR-DAG: [[i32_5:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 5
-; CHECK-MIR-DAG: [[enc_float:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 3
-; CHECK-MIR-DAG: [[enc_boolean:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 2
+; CHECK-MIR-DAG: [[i32_8:%[0-9]+\:iid]] = OpConstantI [[i32type]], 8{{$}}
+; CHECK-MIR-DAG: [[i32_0:%[0-9]+\:pid]] = OpConstantNull
+; CHECK-MIR-DAG: [[i32_5:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 5{{$}}
+; CHECK-MIR-DAG: [[enc_float:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 3{{$}}
+; CHECK-MIR-DAG: [[enc_boolean:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 2{{$}}
; CHECK-MIR-DAG: [[bool:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[enc_boolean]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_16:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 16
-; CHECK-MIR-DAG: [[enc_signed:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 4
+; CHECK-MIR-DAG: [[i32_16:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 16{{$}}
+; CHECK-MIR-DAG: [[enc_signed:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 4{{$}}
; CHECK-MIR-DAG: [[short:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_16]], [[enc_signed]], [[i32_0]]
; CHECK-MIR-DAG: [[char:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[i32_5]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_64:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 64
+; CHECK-MIR-DAG: [[i32_64:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 64{{$}}
; CHECK-MIR-DAG: [[long:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_64]], [[enc_signed]], [[i32_0]]
-; CHECK-MIR-DAG: [[i32_32:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 32
-; CHECK-MIR-DAG: [[enc_unsigned:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 6
+; CHECK-MIR-DAG: [[i32_32:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 32{{$}}
+; CHECK-MIR-DAG: [[enc_unsigned:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 6{{$}}
; CHECK-MIR-DAG: [[unsigned_int:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_32]], [[enc_unsigned]], [[i32_0]]
; CHECK-MIR-DAG: [[unsigned_short:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_16]], [[enc_unsigned]], [[i32_0]]
-; CHECK-MIR-DAG: [[enc_unsigned_char:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 7
+; CHECK-MIR-DAG: [[enc_unsigned_char:%[0-9]+\:iid\(s32\)]] = OpConstantI [[i32type]], 7{{$}}
; CHECK-MIR-DAG: [[unsigned_char:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_8]], [[enc_unsigned_char]], [[i32_0]]
; CHECK-MIR-DAG: [[unsigned_long:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_64]], [[enc_unsigned]], [[i32_0]]
; CHECK-MIR-DAG: [[float:%[0-9]+\:id\(s32\)]] = OpExtInst [[void_type]], 3, 2, {{%[0-9]+\:[a-z0-9\(\)]+}}, [[i32_32]], [[enc_float]], [[i32_0]]
@@ -43,17 +43,17 @@
; CHECK-MIR-DAG: OpExtInst [[void_type]], 3, 3, [[debug_info_none]], [[i32_5]], [[i32_0]]
; CHECK-SPIRV: [[i32type:%[0-9]+]] = OpTypeInt 32 0
-; CHECK-SPIRV-DAG: [[i32_8:%[0-9]+]] = OpConstant [[i32type]] 8
-; CHECK-SPIRV-DAG: [[i32_0:%[0-9]+]] = OpConstant [[i32type]] 0
-; CHECK-SPIRV-DAG: [[i32_5:%[0-9]+]] = OpConstant [[i32type]] 5
-; CHECK-SPIRV-DAG: [[enc_float:%[0-9]+]] = OpConstant [[i32type]] 3
-; CHECK-SPIRV-DAG: [[enc_boolean:%[0-9]+]] = OpConstant [[i32type]] 2
-; CHECK-SPIRV-DAG: [[i32_16:%[0-9]+]] = OpConstant [[i32type]] 16
-; CHECK-SPIRV-DAG: [[enc_signed:%[0-9]+]] = OpConstant [[i32type]] 4
-; CHECK-SPIRV-DAG: [[i32_64:%[0-9]+]] = OpConstant [[i32type]] 64
-; CHECK-SPIRV-DAG: [[i32_32:%[0-9]+]] = OpConstant [[i32type]] 32
-; CHECK-SPIRV-DAG: [[enc_unsigned:%[0-9]+]] = OpConstant [[i32type]] 6
-; CHECK-SPIRV-DAG: [[enc_unsigned_char:%[0-9]+]] = OpConstant [[i32type]] 7
+; CHECK-SPIRV-DAG: [[i32_8:%[0-9]+]] = OpConstant [[i32type]] 8{{$}}
+; CHECK-SPIRV-DAG: [[i32_0:%[0-9]+]] = OpConstant [[i32type]] 0{{$}}
+; CHECK-SPIRV-DAG: [[i32_5:%[0-9]+]] = OpConstant [[i32type]] 5{{$}}
+; CHECK-SPIRV-DAG: [[enc_float:%[0-9]+]] = OpConstant [[i32type]] 3{{$}}
+; CHECK-SPIRV-DAG: [[enc_boolean:%[0-9]+]] = OpConstant [[i32type]] 2{{$}}
+; CHECK-SPIRV-DAG: [[i32_16:%[0-9]+]] = OpConstant [[i32type]] 16{{$}}
+; CHECK-SPIRV-DAG: [[enc_signed:%[0-9]+]] = OpConstant [[i32type]] 4{{$}}
+; CHECK-SPIRV-DAG: [[i32_64:%[0-9]+]] = OpConstant [[i32type]] 64{{$}}
+; CHECK-SPIRV-DAG: [[i32_32:%[0-9]+]] = OpConstant [[i32type]] 32{{$}}
+; CHECK-SPIRV-DAG: [[enc_unsigned:%[0-9]+]] = OpConstant [[i32type]] 6{{$}}
+; CHECK-SPIRV-DAG: [[enc_unsigned_char:%[0-9]+]] = OpConstant [[i32type]] 7{{$}}
; CHECK-SPIRV-DAG: [[bool:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_8]] [[enc_boolean]] [[i32_0]]
; CHECK-SPIRV-DAG: [[short:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_16]] [[enc_signed]] [[i32_0]]
; CHECK-SPIRV-DAG: [[char:%[0-9]+]] = OpExtInst {{%[0-9]+ %[0-9]+}} DebugTypeBasic {{%[0-9]+}} [[i32_8]] [[i32_5]] [[i32_0]]
diff --git a/llvm/test/CodeGen/SPIRV/freeze.ll b/llvm/test/CodeGen/SPIRV/freeze.ll
index fe4335722fe8b..9077d2ede72a9 100644
--- a/llvm/test/CodeGen/SPIRV/freeze.ll
+++ b/llvm/test/CodeGen/SPIRV/freeze.ll
@@ -14,15 +14,12 @@
; CHECK-DAG: %[[FloatTy:.*]] = OpTypeFloat 32
; CHECK-DAG: %[[ShortTy:.*]] = OpTypeInt 16 0
; CHECK-DAG: %[[IntTy:.*]] = OpTypeInt 32 0
-; CHECK-DAG: %[[Undef:.*]] = OpUndef %[[ShortTy]]
+; CHECK-DAG: %[[Undef16:.*]] = OpUndef %[[ShortTy]]
+; CHECK-DAG: %[[Undef32:.*]] = OpUndef %[[IntTy]]
+; CHECK-DAG: %[[UndefFloat:.*]] = OpUndef %[[FloatTy]]
; CHECK-DAG: %[[Const100]] = OpConstant %[[IntTy]] 100
-; CHECK-DAG: %[[StaticPoisonIntFreeze]] = OpConstantNull %[[IntTy]]
-; CHECK-DAG: %[[StaticPoisonFloatFreeze]] = OpConstantNull %[[FloatTy]]
; CHECK: %[[Arg1]] = OpFunctionParameter %[[FloatTy]]
-; CHECK: %[[NotAStaticPoison]] = OpIAdd %[[ShortTy]] %[[Arg2]] %[[Undef]]
-
-target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
-target triple = "spir64-unknown-unknown"
+; CHECK: %[[NotAStaticPoison]] = OpIAdd %[[ShortTy]] %[[Arg2]] %[[Undef16]]
define spir_func void @foo(float %arg1, i16 %arg2) {
entry:
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
index 2ac557b43916b..8715fc324c071 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_i8packed.ll
@@ -11,7 +11,7 @@
; CHECK: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-EXP-DAG: %[[#int_8:]] = OpTypeInt 8 0
-; CHECK-EXP-DAG: %[[#zero:]] = OpConstantNull %[[#int_8]]
+; CHECK-EXP-DAG: %[[#zero:]] = OpConstant %[[#int_8]] 0{{$}}
; CHECK-EXP-DAG: %[[#eight:]] = OpConstant %[[#int_8]] 8
; CHECK-EXP-DAG: %[[#sixteen:]] = OpConstant %[[#int_8]] 16
; CHECK-EXP-DAG: %[[#twentyfour:]] = OpConstant %[[#int_8]] 24
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
index 8acdb7d2ea324..a43d0be9e775b 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-intrinsics/dot4add_u8packed.ll
@@ -11,7 +11,7 @@
; CHECK: %[[#int_32:]] = OpTypeInt 32 0
; CHECK-EXP-DAG: %[[#int_8:]] = OpTypeInt 8 0
-; CHECK-EXP-DAG: %[[#zero:]] = OpConstantNull %[[#int_8]]
+; CHECK-EXP-DAG: %[[#zero:]] = OpConstant %[[#int_8]] 0{{$}}
; CHECK-EXP-DAG: %[[#eight:]] = OpConstant %[[#int_8]] 8
; CHECK-EXP-DAG: %[[#sixteen:]] = OpConstant %[[#int_8]] 16
; CHECK-EXP-DAG: %[[#twentyfour:]] = OpConstant %[[#int_8]] 24
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
index 94ebe74148b95..6a6d810e6babd 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageDynIdx.ll
@@ -1,9 +1,9 @@
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
-; CHECK: OpCapability Shader
-; CHECK-NEXT: OpCapability StorageImageArrayDynamicIndexing
-; CHECK-NEXT: OpCapability Image1D
+; CHECK-DAG: OpCapability Shader
+; CHECK-DAG: OpCapability StorageImageArrayDynamicIndexing
+; CHECK-DAG: OpCapability Image1D
; CHECK-NOT: OpCapability
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
@@ -14,7 +14,7 @@
; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
; CHECK-DAG: [[One:%[0-9]+]] = OpConstant [[int]] 1
-; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0
+; CHECK-DAG: [[Zero:%[0-9]+]] = OpConstant [[int]] 0{{$}}
; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
diff --git a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
index f9466e431c19c..16f3724d5d10a 100644
--- a/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
+++ b/llvm/test/CodeGen/SPIRV/hlsl-resources/StorageImageNonUniformIdx.ll
@@ -1,10 +1,10 @@
; RUN: llc -O0 -verify-machineinstrs -mtriple=spirv1.5-vulkan-library %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv1.5-vulkan-library %s -o - -filetype=obj | spirv-val %}
-; CHECK: OpCapability Shader
-; CHECK: OpCapability ShaderNonUniformEXT
-; CHECK-NEXT: OpCapability StorageImageArrayNonUniformIndexing
-; CHECK-NEXT: OpCapability Image1D
+; CHECK-DAG: OpCapability Shader
+; CHECK-DAG: OpCapability ShaderNonUniformEXT
+; CHECK-DAG: OpCapability StorageImageArrayNonUniformIndexing
+; CHECK-DAG: OpCapability Image1D
; CHECK-NOT: OpCapability
; CHECK-DAG: OpDecorate [[Var:%[0-9]+]] DescriptorSet 3
@@ -21,7 +21,7 @@
; CHECK-DAG: [[BufferPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferType]]
; CHECK-DAG: [[ArraySize:%[0-9]+]] = OpConstant [[int]] 3
; CHECK-DAG: [[One]] = OpConstant [[int]] 1
-; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0
+; CHECK-DAG: [[Zero]] = OpConstant [[int]] 0{{$}}
; CHECK-DAG: [[BufferArrayType:%[0-9]+]] = OpTypeArray [[BufferType]] [[ArraySize]]
; CHECK-DAG: [[ArrayPtrType:%[0-9]+]] = OpTypePointer UniformConstant [[BufferArrayType]]
; CHECK-DAG: [[Var]] = OpVariable [[ArrayPtrType]] UniformConstant
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
index 2281ccf52bbb4..f839774b4f3e3 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/smul.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpSMulExtended %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpSMulExtended %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
index 1c77800a1630d..fc3e9b6ab3f89 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/uadd.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -29,7 +31,7 @@
; CHECK: %[[Struct:.*]] = OpIAddCarry %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -50,7 +52,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpIAddCarry %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
index 7113dd692f6ac..e01489d6995f7 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/umul.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpUMulExtended %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpUMulExtended %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
diff --git a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
index 963dd70f606b6..f7ea655e6529a 100644
--- a/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
+++ b/llvm/test/CodeGen/SPIRV/llvm-intrinsics/usub.with.overflow.ll
@@ -9,10 +9,12 @@
; CHECK-DAG: %[[PtrChar:.*]] = OpTypePointer Function %[[Char]]
; CHECK-DAG: %[[StructChar:.*]] = OpTypeStruct %[[Char]] %[[Char]]
; CHECK-DAG: %[[ZeroChar:.*]] = OpConstant %[[Char]] 0
+; CHECK-DAG: %[[NullChar:.*]] = OpConstantNull %[[Char]]
; CHECK-DAG: %[[Int:.*]] = OpTypeInt 32 0
; CHECK-DAG: %[[PtrInt:.*]] = OpTypePointer Function %[[Int]]
; CHECK-DAG: %[[StructInt:.*]] = OpTypeStruct %[[Int]] %[[Int]]
; CHECK-DAG: %[[ZeroInt:.*]] = OpConstant %[[Int]] 0
+; CHECK-DAG: %[[NullInt:.*]] = OpConstantNull %[[Int]]
; CHECK-DAG: %[[Bool:.*]] = OpTypeBool
; CHECK-DAG: %[[V2Bool:.*]] = OpTypeVector %[[Bool]] 2
; CHECK-DAG: %[[Long:.*]] = OpTypeInt 64 0
@@ -28,7 +30,7 @@
; CHECK: %[[Struct:.*]] = OpISubBorrow %[[StructChar]] %[[A]] %[[B]]
; CHECK: %[[Val:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 0
; CHECK: %[[Over:.*]] = OpCompositeExtract %[[Char]] %[[Struct]] 1
-; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[ZeroChar]]
+; CHECK: %[[IsOver:.*]] = OpINotEqual %[[Bool]] %[[Over]] %[[NullChar]]
; CHECK: %[[Res:.*]] = OpSelect %[[Char]] %[[IsOver]] %[[ZeroChar]] %[[Val]]
; CHECK: OpStore %[[Ptr]] %[[Res]] Aligned 1
; CHECK: OpReturn
@@ -49,7 +51,7 @@ entry:
; CHECK: %[[Struct2:.*]] = OpISubBorrow %[[StructInt]] %[[B2]] %[[A2]]
; CHECK: %[[Val2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 0
; CHECK: %[[Over2:.*]] = OpCompositeExtract %[[Int]] %[[Struct2]] 1
-; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[ZeroInt]]
+; CHECK: %[[IsOver2:.*]] = OpINotEqual %[[Bool]] %[[Over2]] %[[NullInt]]
; CHECK: %[[Res2:.*]] = OpSelect %[[Int]] %[[IsOver2]] %[[ZeroInt]] %[[Val2]]
; CHECK: OpStore %[[Ptr2]] %[[Res2]] Aligned 4
; CHECK: OpReturn
>From a9cd2191767d844c7e87a5998b0e23d7a249b9bb Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Fri, 14 Mar 2025 10:41:27 -0700
Subject: [PATCH 9/9] experiment with cashes
---
llvm/lib/Target/SPIRV/SPIRVIRMapping.h | 67 +++++++++++++------
llvm/lib/Target/SPIRV/SPIRVInstrInfo.td | 3 -
.../Target/SPIRV/SPIRVInstructionSelector.cpp | 56 +++++-----------
llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 13 ++--
llvm/lib/Target/SPIRV/SPIRVUtils.cpp | 3 +-
5 files changed, 65 insertions(+), 77 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
index bec2a989483e8..feee13c0b3117 100644
--- a/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
+++ b/llvm/lib/Target/SPIRV/SPIRVIRMapping.h
@@ -26,7 +26,7 @@
namespace llvm {
namespace SPIRV {
-
+/*
inline size_t to_hash(const MachineInstr *MI,
std::unordered_set<const MachineInstr *> &Visited) {
if (!MI || !Visited.insert(MI).second)
@@ -47,6 +47,21 @@ inline size_t to_hash(const MachineInstr *MI) {
std::unordered_set<const MachineInstr *> Visited;
return to_hash(MI, Visited);
}
+*/
+
+inline size_t to_hash(const MachineInstr *MI) {
+ hash_code H = llvm::hash_combine(MI->getOpcode(), MI->getNumOperands());
+ for (unsigned I = MI->getNumDefs(); I < MI->getNumOperands(); ++I) {
+ const MachineOperand &MO = MI->getOperand(I);
+ if (MO.getType() == MachineOperand::MO_CImmediate)
+ H = llvm::hash_combine(H, MO.getType(), MO.getCImm());
+ else if (MO.getType() == MachineOperand::MO_FPImmediate)
+ H = llvm::hash_combine(H, MO.getType(), MO.getFPImm());
+ else
+ H = llvm::hash_combine(H, MO.getType());
+ }
+ return H;
+}
using MIHandle = std::pair<const MachineInstr *, size_t>;
@@ -169,46 +184,54 @@ inline IRHandle handle(const MachineInstr *KeyMI) {
// per an LLVM/GlobalISel entity (e.g., Type, Constant, Machine Instruction).
class SPIRVIRMapping {
DenseMap<SPIRV::IRHandleMF, SPIRV::MIHandle> Vregs;
- DenseMap<SPIRV::MIHandle, SPIRV::IRHandle> Defs;
+ DenseMap<const MachineInstr *, SPIRV::IRHandleMF> Defs;
public:
bool add(SPIRV::IRHandle Handle, const MachineInstr *MI) {
- if (std::get<1>(Handle) == 17 && std::get<2>(Handle) == 8) {
- const Value *Ptr = (const Value *)std::get<0>(Handle);
- if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(Ptr)) {
- if (CI->getZExtValue() == 8 || CI->getZExtValue() == 5) {
- [[maybe_unused]] uint64_t v = CI->getZExtValue();
- }
- }
+ if (auto DefIt = Defs.find(MI); DefIt != Defs.end()) {
+ auto [ExistHandle, ExistMF] = DefIt->second;
+ if (Handle == ExistHandle && MI->getMF() == ExistMF)
+ return false; // already exists
+ // invalidate the record
+ Vregs.erase(DefIt->second);
+ Defs.erase(DefIt);
}
- auto MIKey = SPIRV::getMIKey(MI);
- auto [It, Inserted] =
- Vregs.try_emplace(std::make_pair(Handle, MI->getMF()), MIKey);
- if (Inserted) {
- [[maybe_unused]] auto [_, IsConsistent] =
- Defs.insert_or_assign(MIKey, Handle);
- assert(IsConsistent);
+ SPIRV::IRHandleMF HandleMF = SPIRV::getIRHandleMF(Handle, MI->getMF());
+ SPIRV::MIHandle MIKey = SPIRV::getMIKey(MI);
+ auto It1 = Vregs.try_emplace(HandleMF, MIKey);
+ if (!It1.second) {
+ // there is an expired record
+ auto [ExistMI, _] = It1.first->second;
+ // invalidate the record
+ Defs.erase(ExistMI);
+ // update the record
+ It1.first->second = MIKey;
}
- return Inserted;
+ [[maybe_unused]] auto It2 = Defs.try_emplace(MI, HandleMF);
+ assert(It2.second);
+ return true;
}
bool erase(const MachineInstr *MI) {
bool Res = false;
- if (auto It = Defs.find(SPIRV::getMIKey(MI)); It != Defs.end()) {
- Res = Vregs.erase(SPIRV::getIRHandleMF(It->second, MI->getMF()));
+ if (auto It = Defs.find(MI); It != Defs.end()) {
+ Res = Vregs.erase(It->second);
Defs.erase(It);
}
return Res;
}
const MachineInstr *findMI(SPIRV::IRHandle Handle,
const MachineFunction *MF) {
- auto It = Vregs.find(SPIRV::getIRHandleMF(Handle, MF));
+ SPIRV::IRHandleMF HandleMF = SPIRV::getIRHandleMF(Handle, MF);
+ auto It = Vregs.find(HandleMF);
if (It == Vregs.end())
return nullptr;
auto [MI, Hash] = It->second;
- if (SPIRV::to_hash(MI) != Hash) {
+ assert(SPIRV::to_hash(MI) == Hash);
+ assert(Defs.find(MI) != Defs.end() && Defs.find(MI)->second == HandleMF);
+ /*if (SPIRV::to_hash(MI) != Hash) {
erase(MI);
return nullptr;
- }
+ }*/
return MI;
}
Register find(SPIRV::IRHandle Handle, const MachineFunction *MF) {
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
index 4b9bddd661f63..3499c2340a2dd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.td
@@ -15,7 +15,6 @@ include "SPIRVSymbolicOperands.td"
// Codegen only metadata instructions
let isCodeGenOnly=1 in {
- def TYPEREF: Pseudo<(outs), (ins ID:$src_id, TYPE:$src_ty)>;
def ASSIGN_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def DECL_TYPE: Pseudo<(outs ID:$dst_id), (ins ID:$src_id, TYPE:$src_ty)>;
def GET_ID: Pseudo<(outs iID:$dst_id), (ins iID:$src)>;
@@ -29,10 +28,8 @@ let isCodeGenOnly=1 in {
def SPVTypeBin : SDTypeProfile<1, 2, []>;
def assigntype : SDNode<"SPIRVISD::AssignType", SPVTypeBin>;
-def typeref : SDNode<"SPIRVISD::TypeRef", SPVTypeBin>;
def : GINodeEquiv<ASSIGN_TYPE, assigntype>;
-def : GINodeEquiv<TYPEREF, typeref>;
class BinOp<string name, bits<16> opCode, list<dag> pattern=[]>
: Op<opCode, (outs ID:$dst), (ins TYPE:$src_ty, ID:$src, ID:$src2),
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 8f1ac07dd9450..64d9a291f637d 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -393,26 +393,21 @@ void SPIRVInstructionSelector::resetVRegsType(MachineFunction &MF) {
}
for (const auto &MBB : MF) {
for (const auto &MI : MBB) {
- if (MI.getOpcode() == SPIRV::ASSIGN_TYPE) {
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
-
- const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
- const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
- if (DstRC != SrcRC && SrcRC)
- MRI.setRegClass(DstReg, SrcRC);
- } else if (MI.getOpcode() == SPIRV::TYPEREF) {
- Register DstReg = MI.getOperand(0).getReg();
- LLT DstType = MRI.getType(DstReg);
- Register SrcReg = MI.getOperand(1).getReg();
- LLT SrcType = MRI.getType(SrcReg);
- if (DstType != SrcType)
- MRI.setType(DstReg, MRI.getType(SrcReg));
- }
+ //GR.invalidateMachineInstr(&I);
+ if (MI.getOpcode() != SPIRV::ASSIGN_TYPE)
+ continue;
+
+ Register DstReg = MI.getOperand(0).getReg();
+ LLT DstType = MRI.getType(DstReg);
+ Register SrcReg = MI.getOperand(1).getReg();
+ LLT SrcType = MRI.getType(SrcReg);
+ if (DstType != SrcType)
+ MRI.setType(DstReg, MRI.getType(SrcReg));
+
+ const TargetRegisterClass *DstRC = MRI.getRegClassOrNull(DstReg);
+ const TargetRegisterClass *SrcRC = MRI.getRegClassOrNull(SrcReg);
+ if (DstRC != SrcRC && SrcRC)
+ MRI.setRegClass(DstReg, SrcRC);
}
}
}
@@ -523,27 +518,6 @@ bool SPIRVInstructionSelector::select(MachineInstr &I) {
GR.invalidateMachineInstr(&I);
I.removeFromParent();
return true;
- } else if (Opcode == SPIRV::TYPEREF) {
- Register SrcReg = I.getOperand(0).getReg();
- auto *Def = MRI->getVRegDef(SrcReg);
- if (isTypeFoldingSupported(Def->getOpcode())) {
- bool Res = selectImpl(I, *CoverageInfo);
- LLVM_DEBUG({
- if (!Res && Def->getOpcode() != TargetOpcode::G_CONSTANT) {
- dbgs() << "Unexpected pattern in ASSIGN_TYPE.\nInstruction: ";
- I.print(dbgs());
- }
- });
- assert(Res || Def->getOpcode() == TargetOpcode::G_CONSTANT);
- if (Res) {
- if (!isTriviallyDead(*Def, *MRI) && isDead(*Def, *MRI))
- DeadMIs.insert(Def);
- return Res;
- }
- }
- GR.invalidateMachineInstr(&I);
- I.removeFromParent();
- return true;
} else if (I.getNumDefs() == 1) {
// Make all vregs 64 bits (for SPIR-V IDs).
MRI->setType(I.getOperand(0).getReg(), LLT::scalar(64));
diff --git a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
index 0ece31ee88abe..aea49c6a618cd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
@@ -564,8 +564,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
- Def->getOpcode() != SPIRV::TYPEREF)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, nullptr, AssignedPtrType, GR, MIB,
MF.getRegInfo());
ToErase.push_back(&MI);
@@ -576,8 +575,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
assert(Def && "Expecting an instruction that defines the register");
// G_GLOBAL_VALUE already has type info.
if (Def->getOpcode() != TargetOpcode::G_GLOBAL_VALUE &&
- Def->getOpcode() != SPIRV::ASSIGN_TYPE &&
- Def->getOpcode() != SPIRV::TYPEREF)
+ Def->getOpcode() != SPIRV::ASSIGN_TYPE)
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MF.getRegInfo());
ToErase.push_back(&MI);
} else if (MIOp == TargetOpcode::FAKE_USE && MI.getNumOperands() > 0) {
@@ -614,8 +612,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (isSpvIntrinsic(UseMI, Intrinsic::spv_assign_type) ||
isSpvIntrinsic(UseMI, Intrinsic::spv_assign_name))
continue;
- if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE ||
- UseMI.getOpcode() == SPIRV::TYPEREF)
+ if (UseMI.getOpcode() == SPIRV::ASSIGN_TYPE)
NeedAssignType = false;
}
Type *Ty = nullptr;
@@ -665,9 +662,7 @@ generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
if (!ElemTy) {
// There may be a case when we already know Reg's type.
MachineInstr *NextMI = MI.getNextNode();
- if (!NextMI ||
- (NextMI->getOpcode() != SPIRV::ASSIGN_TYPE &&
- NextMI->getOpcode() != SPIRV::TYPEREF) ||
+ if (!NextMI || NextMI->getOpcode() != SPIRV::ASSIGN_TYPE ||
NextMI->getOperand(1).getReg() != Reg)
llvm_unreachable("Unexpected opcode");
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
index 6e6125c7bd66d..b101e562051a4 100644
--- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp
@@ -186,8 +186,7 @@ MachineBasicBlock::iterator getOpVariableMBBIt(MachineInstr &I) {
if (Opcode == SPIRV::OpFunction || Opcode == SPIRV::OpFunctionParameter) {
IsHeader = true;
} else if (IsHeader &&
- !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::TYPEREF ||
- Opcode == SPIRV::OpLabel)) {
+ !(Opcode == SPIRV::ASSIGN_TYPE || Opcode == SPIRV::OpLabel)) {
++It;
break;
}
More information about the llvm-commits
mailing list