[PATCH] D149646: [LLVM][Uniformity] Propagate temporal divergence explicitly

Jay Foad via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 2 06:06:35 PDT 2023


foad added inline comments.


================
Comment at: llvm/include/llvm/ADT/GenericUniformityImpl.h:457-458
 
   /// \brief Mark all instruction as divergent that use a value defined in \p
   /// OuterDivCycle. Push their users on the worklist.
+  void propagateTemporalDivergence(const InstructionT &I,
----------------
Comment should be updated. It doesn't mention I.


================
Comment at: llvm/include/llvm/ADT/GenericUniformityImpl.h:824
     const CycleT &OuterDivCycle) {
-  // Set of blocks that are dominated by the cycle, i.e., each is only
-  // reachable from paths that pass through the cycle.
-  SmallPtrSet<BlockT *, 16> DomRegion;
-
-  // The boundary of DomRegion, formed by blocks that are not
-  // dominated by the cycle.
-  SmallVector<BlockT *> DomFrontier;
-  OuterDivCycle.getExitBlocks(DomFrontier);
-
-  // Returns true if BB is dominated by the cycle.
-  auto isInDomRegion = [&](BlockT *BB) {
-    for (auto *P : predecessors(BB)) {
-      if (OuterDivCycle.contains(P))
-        continue;
-      if (DomRegion.count(P))
-        continue;
-      return false;
-    }
-    return true;
-  };
-
-  // Keep advancing the frontier along successor edges, while
-  // promoting blocks to DomRegion.
-  while (true) {
-    bool Promoted = false;
-    SmallVector<BlockT *> Temp;
-    for (auto *W : DomFrontier) {
-      if (!isInDomRegion(W)) {
-        Temp.push_back(W);
-        continue;
-      }
-      DomRegion.insert(W);
-      Promoted = true;
-      for (auto *Succ : successors(W)) {
-        if (DomRegion.contains(Succ))
-          continue;
-        Temp.push_back(Succ);
-      }
-    }
-    if (!Promoted)
-      break;
-
-    // Restore the set property for the temporary vector
-    llvm::sort(Temp);
-    Temp.erase(std::unique(Temp.begin(), Temp.end()), Temp.end());
-
-    DomFrontier = Temp;
-  }
-
-  // At DomFrontier, only the PHI nodes are affected by temporal
-  // divergence.
-  for (const auto *UserBlock : DomFrontier) {
-    LLVM_DEBUG(dbgs() << "Analyze phis after cycle exit: "
-                      << Context.print(UserBlock) << "\n");
-    for (const auto &Phi : UserBlock->phis()) {
-      LLVM_DEBUG(dbgs() << "  " << Context.print(&Phi) << "\n");
-      analyzeTemporalDivergence(Phi, OuterDivCycle);
-    }
-  }
-
-  // All instructions inside the dominance region are affected by
-  // temporal divergence.
-  for (const auto *UserBlock : DomRegion) {
-    LLVM_DEBUG(dbgs() << "Analyze non-phi users after cycle exit: "
-                      << Context.print(UserBlock) << "\n");
-    for (const auto &I : *UserBlock) {
-      LLVM_DEBUG(dbgs() << "  " << Context.print(&I) << "\n");
-      analyzeTemporalDivergence(I, OuterDivCycle);
+  for (auto *BB : OuterDivCycle.blocks()) {
+    for (auto &II : *BB) {
----------------
I wonder if there is a quick test you could use to avoid scanning some BBs, e.g. I think if BB does not dominate any edges that exit OuterDivCycle then instructions in BB cannot have any uses outside OuterDivCycle. This should be fairly common because it applies to the body of a simple C "for" loop.


================
Comment at: llvm/lib/Analysis/UniformityAnalysis.cpp:72-73
+                                             const Cycle &DefCycle) {
+  for (const Use &U : I.uses()) {
+    auto *UserInstr = cast<Instruction>(U.getUser());
+    if (DefCycle.contains(UserInstr->getParent()))
----------------
Just iterate over `users()` instead of `uses()`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149646/new/

https://reviews.llvm.org/D149646



More information about the llvm-commits mailing list