@@ -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