@@ -367,9 +367,7 @@ class SPIRVInstructionSelector : public InstructionSelector {
367367 MachineInstr &I) const ;
368368 bool loadHandleBeforePosition (Register &HandleReg, const SPIRVType *ResType,
369369 GIntrinsic &HandleDef, MachineInstr &Pos) const ;
370- void recursivelyDecorateChildAsNonUniform (Register &NonUniformReg,
371- const SPIRVType *RegType,
372- MachineInstr &I) const ;
370+ void decorateUsesAsNonUniform (Register &NonUniformReg) const ;
373371};
374372
375373bool sampledTypeIsSignedInteger (const llvm::Type *HandleType) {
@@ -3734,41 +3732,38 @@ bool SPIRVInstructionSelector::selectResourceNonUniformIndex(
37343732 // load/store/sample/atomic must be decorated, so we need to propagate the
37353733 // decoration through access chains and copies.
37363734 // https://docs.vulkan.org/samples/latest/samples/extensions/descriptor_indexing/README.html#_when_to_use_non_uniform_indexing_qualifier
3737- recursivelyDecorateChildAsNonUniform (ResVReg, ResType, I );
3735+ decorateUsesAsNonUniform (ResVReg);
37383736 return true ;
37393737}
37403738
3741- void SPIRVInstructionSelector::recursivelyDecorateChildAsNonUniform (
3742- Register &NonUniformReg, const SPIRVType *RegType, MachineInstr &I) const {
3743- std::vector<std::tuple<Register, const SPIRVType *, MachineInstr *>> WorkList;
3744- bool isDecorated = false ;
3745- for (MachineInstr &Use :
3746- RegType->getMF ()->getRegInfo ().use_instructions (NonUniformReg)) {
3747- if (Use.getOpcode () != SPIRV::OpDecorate &&
3748- Use.getOpcode () != SPIRV::OpAccessChain &&
3749- Use.getOpcode () != SPIRV::OpCopyObject &&
3750- Use.getOpcode () != SPIRV::OpLoad)
3751- continue ;
3752-
3753- if (Use.getOpcode () == SPIRV::OpDecorate &&
3754- Use.getOperand (1 ).getImm () == SPIRV::Decoration::NonUniformEXT) {
3755- isDecorated = true ;
3756- continue ;
3739+ void SPIRVInstructionSelector::decorateUsesAsNonUniform (
3740+ Register &NonUniformReg) const {
3741+ std::vector<Register> WorkList = {NonUniformReg};
3742+ while (WorkList.size () > 0 ) {
3743+ Register CurrentReg = WorkList.at (0 );
3744+ WorkList.erase (WorkList.begin ());
3745+
3746+ bool isDecorated = false ;
3747+ for (MachineInstr &Use : MRI->use_instructions (CurrentReg)) {
3748+ if (Use.getOpcode () == SPIRV::OpDecorate &&
3749+ Use.getOperand (1 ).getImm () == SPIRV::Decoration::NonUniformEXT) {
3750+ isDecorated = true ;
3751+ continue ;
3752+ }
3753+ // Check if the instruction has the result register and add it to the
3754+ // worklist.
3755+ if (Use.getOperand (0 ).isReg () && Use.getOperand (0 ).isDef ()) {
3756+ Register ResultReg = Use.getOperand (0 ).getReg ();
3757+ if (ResultReg == CurrentReg)
3758+ continue ;
3759+ WorkList.push_back (ResultReg);
3760+ }
37573761 }
37583762
3759- Register ResultReg = Use.getOperand (0 ).getReg ();
3760- SPIRVType *ResultType = GR.getResultType (ResultReg);
3761- WorkList.push_back (std::make_tuple (ResultReg, ResultType, &Use));
3762- }
3763-
3764- if (!isDecorated) {
3765- buildOpDecorate (NonUniformReg, I, TII, SPIRV::Decoration::NonUniformEXT,
3766- {});
3767- }
3768-
3769- for (auto &Item : WorkList) {
3770- recursivelyDecorateChildAsNonUniform (std::get<0 >(Item), std::get<1 >(Item),
3771- *std::get<2 >(Item));
3763+ if (!isDecorated) {
3764+ buildOpDecorate (CurrentReg, *MRI->getVRegDef (CurrentReg), TII,
3765+ SPIRV::Decoration::NonUniformEXT, {});
3766+ }
37723767 }
37733768 return ;
37743769}
0 commit comments