[llvm] [SPIR-V] Remove spv_track_constant() internal intrinsics (PR #130605)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 11 05:39:59 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/5] 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/5] 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/5] 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/5] 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/5] 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
More information about the llvm-commits
mailing list