[llvm] [MachineSSAUpdater][AMDGPU] Add faster version of MachineSSAUpdater class. (PR #145722)

Juan Manuel Martinez CaamaƱo via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 26 05:47:28 PDT 2025


================
@@ -0,0 +1,185 @@
+//===- MachineSSAUpdater2.cpp - Unstructured SSA Update Tool
+//------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MachineSSAUpdater2 class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/MachineSSAUpdater2.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Analysis/IteratedDominanceFrontier.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm {
+
+template <bool IsPostDom>
+class MachineIDFCalculator final
+    : public IDFCalculatorBase<MachineBasicBlock, IsPostDom> {
+public:
+  using IDFCalculatorBase =
+      typename llvm::IDFCalculatorBase<MachineBasicBlock, IsPostDom>;
+  using ChildrenGetterTy = typename IDFCalculatorBase::ChildrenGetterTy;
+
+  MachineIDFCalculator(DominatorTreeBase<MachineBasicBlock, IsPostDom> &DT)
+      : IDFCalculatorBase(DT) {}
+};
+
+using MachineForwardIDFCalculator = MachineIDFCalculator<false>;
+using MachineReverseIDFCalculator = MachineIDFCalculator<true>;
+
+} // namespace llvm
+
+using namespace llvm;
+
+/// Given sets of UsingBlocks and DefBlocks, compute the set of LiveInBlocks.
+/// This is basically a subgraph limited by DefBlocks and UsingBlocks.
+static void
+ComputeLiveInBlocks(const SmallPtrSetImpl<MachineBasicBlock *> &UsingBlocks,
+                    const SmallPtrSetImpl<MachineBasicBlock *> &DefBlocks,
+                    SmallPtrSetImpl<MachineBasicBlock *> &LiveInBlocks) {
+  // To determine liveness, we must iterate through the predecessors of blocks
+  // where the def is live.  Blocks are added to the worklist if we need to
+  // check their predecessors.  Start with all the using blocks.
+  SmallVector<MachineBasicBlock *, 64> LiveInBlockWorklist(UsingBlocks.begin(),
+                                                           UsingBlocks.end());
+
+  // Now that we have a set of blocks where the phi is live-in, recursively add
+  // their predecessors until we find the full region the value is live.
+  while (!LiveInBlockWorklist.empty()) {
+    MachineBasicBlock *BB = LiveInBlockWorklist.pop_back_val();
+
+    // The block really is live in here, insert it into the set.  If already in
+    // the set, then it has already been processed.
+    if (!LiveInBlocks.insert(BB).second)
+      continue;
+
+    // Since the value is live into BB, it is either defined in a predecessor or
+    // live into it to.  Add the preds to the worklist unless they are a
+    // defining block.
+    for (MachineBasicBlock *P : BB->predecessors()) {
+      // The value is not live into a predecessor if it defines the value.
+      if (DefBlocks.count(P))
+        continue;
+
+      // Otherwise it is, add to the worklist.
+      LiveInBlockWorklist.push_back(P);
+    }
+  }
+}
+
+MachineInstrBuilder
+MachineSSAUpdater2::CreateInst(unsigned Opc, MachineBasicBlock *BB,
+                               MachineBasicBlock::iterator I) {
+  return BuildMI(*BB, I, DebugLoc(), TII.get(Opc),
+                 MRI.createVirtualRegister(RegAttrs));
+}
+
+// IsLiveOut indicates whether we are computing live-out values (true) or
+// live-in values (false).
+Register MachineSSAUpdater2::ComputeValue(MachineBasicBlock *BB,
+                                          bool IsLiveOut) {
+  auto *BBInfo = &BBInfos[BB];
+
+  if (IsLiveOut && BBInfo->LiveOutValue)
+    return BBInfo->LiveOutValue;
+
+  if (BBInfo->LiveInValue)
+    return BBInfo->LiveInValue;
+
+  SmallVector<BBValueInfo *, 4> Stack = {BBInfo};
+  MachineBasicBlock *DomBB = BB;
+  Register V;
+
+  while (DT.isReachableFromEntry(DomBB) && !DomBB->pred_empty() &&
+         (DomBB = DT.getNode(DomBB)->getIDom()->getBlock())) {
+    BBInfo = &BBInfos[DomBB];
+    if (BBInfo->LiveOutValue) {
+      V = BBInfo->LiveOutValue;
+      break;
+    }
+    if (BBInfo->LiveInValue) {
+      V = BBInfo->LiveInValue;
+      break;
+    }
+    Stack.emplace_back(BBInfo);
+  }
+
+  for (auto *BBInfo : Stack)
+    // Loop above can insert new entries into the BBInfos map: assume the
+    // map shouldn't grow due to [1] and BBInfo references are valid.
+    BBInfo->LiveInValue = V;
----------------
jmmartinez wrote:

What do you think about creating the implicit def in the last basic-block of "Stack" such that it dominates all the rest ? Then we could loop over the blocks in the "stack" and use it as the live-in/live-out.

https://github.com/llvm/llvm-project/pull/145722


More information about the llvm-commits mailing list