瀏覽代碼

Correct long loops for wave-sensitive tracing (#2859)

Because VisitedPhis parameter to the recursive function to cull wave
sensitive blocks was not passed by reference, PHI nodes were getting
repeated. This corrects that issue and also adds bailouts for when no
break blocks are left or when the call instruction isn't in the current
function.
Greg Roth 5 年之前
父節點
當前提交
55b5b0aa9c
共有 1 個文件被更改,包括 10 次插入5 次删除
  1. 10 5
      lib/HLSL/DxilPreparePasses.cpp

+ 10 - 5
lib/HLSL/DxilPreparePasses.cpp

@@ -1079,12 +1079,12 @@ namespace {
 // a break conditional on dx.break that breaks out of a loop that contains WaveCI
 // a break conditional on dx.break that breaks out of a loop that contains WaveCI
 // LInfo is needed to determine loop contents. VisitedPhis is needed to prevent infinit looping.
 // LInfo is needed to determine loop contents. VisitedPhis is needed to prevent infinit looping.
 static void CullSensitiveBlocks(LoopInfo *LInfo, BasicBlock *WaveBB, BasicBlock *LastBB, Instruction *Inst,
 static void CullSensitiveBlocks(LoopInfo *LInfo, BasicBlock *WaveBB, BasicBlock *LastBB, Instruction *Inst,
-                                SmallPtrSet<Instruction *, 16> VisitedPhis,
+                                SmallPtrSet<Instruction *, 16> &VisitedPhis,
                                 SmallDenseMap<BasicBlock *, Instruction *, 16> &BreakBBs) {
                                 SmallDenseMap<BasicBlock *, Instruction *, 16> &BreakBBs) {
   BasicBlock *BB = Inst->getParent();
   BasicBlock *BB = Inst->getParent();
   Loop *BreakLoop = LInfo->getLoopFor(BB);
   Loop *BreakLoop = LInfo->getLoopFor(BB);
   // If this instruction isn't in a loop, there is no need to track its sensitivity further
   // If this instruction isn't in a loop, there is no need to track its sensitivity further
-  if (!BreakLoop)
+  if (!BreakLoop || BreakBBs.empty())
     return;
     return;
 
 
   // To prevent infinite looping, only visit each PHI once
   // To prevent infinite looping, only visit each PHI once
@@ -1160,17 +1160,22 @@ public:
     SmallDenseMap<BasicBlock *, Instruction *, 16> BreakBBs;
     SmallDenseMap<BasicBlock *, Instruction *, 16> BreakBBs;
     CollectBreakBlocks(BreakFunc, &F, BreakBBs);
     CollectBreakBlocks(BreakFunc, &F, BreakBBs);
 
 
+    if (BreakBBs.empty())
+      return false;
+
     // For each wave operation, remove all the dx.break blocks that are sensitive to it
     // For each wave operation, remove all the dx.break blocks that are sensitive to it
     for (Function &IF : M->functions()) {
     for (Function &IF : M->functions()) {
       HLOpcodeGroup opgroup = hlsl::GetHLOpcodeGroup(&IF);
       HLOpcodeGroup opgroup = hlsl::GetHLOpcodeGroup(&IF);
       // Only consider wave-sensitive intrinsics or extintrinsics
       // Only consider wave-sensitive intrinsics or extintrinsics
-      if (IF.isDeclaration() && IsHLWaveSensitive(&IF) &&
+      if (IF.isDeclaration() && IsHLWaveSensitive(&IF) && !BreakBBs.empty() &&
           (opgroup == HLOpcodeGroup::HLIntrinsic || opgroup == HLOpcodeGroup::HLExtIntrinsic)) {
           (opgroup == HLOpcodeGroup::HLIntrinsic || opgroup == HLOpcodeGroup::HLExtIntrinsic)) {
         // For each user of the function, trace all its users to remove the blocks
         // For each user of the function, trace all its users to remove the blocks
         for (User *U : IF.users()) {
         for (User *U : IF.users()) {
           CallInst *CI = cast<CallInst>(U);
           CallInst *CI = cast<CallInst>(U);
-          SmallPtrSet<Instruction *, 16> VisitedPhis;
-          CullSensitiveBlocks(LInfo, CI->getParent(), nullptr, CI, VisitedPhis, BreakBBs);
+          if (CI->getParent()->getParent() == &F) {
+            SmallPtrSet<Instruction *, 16> VisitedPhis;
+            CullSensitiveBlocks(LInfo, CI->getParent(), nullptr, CI, VisitedPhis, BreakBBs);
+          }
         }
         }
       }
       }
     }
     }