[llvm] [CodeGen] Introduce MIR-level target-independent rematerialization helper (PR #177080)

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 12 17:54:44 PST 2026


================
@@ -0,0 +1,737 @@
+//=====-- Rematerializer.cpp - MIR rematerialization support ----*- C++ -*-===//
+//
+// 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
+//
+//==-----------------------------------------------------------------------===//
+//
+/// \file
+/// Implements helpers for target-independent rematerialization at the MIR
+/// level.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/Rematerializer.h"
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/Register.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "rematerializer"
+
+using namespace llvm;
+
+static bool isAvailableAtUse(const VNInfo *OVNI, LaneBitmask Mask,
+                             SlotIndex UseIdx, const LiveInterval &LI) {
+  assert(OVNI);
+  if (OVNI != LI.getVNInfoAt(UseIdx))
+    return false;
+
+  // Check that subrange is live at user.
+  if (LI.hasSubRanges()) {
+    for (const LiveInterval::SubRange &SR : LI.subranges()) {
+      if ((SR.LaneMask & Mask).none())
+        continue;
+      if (!SR.liveAt(UseIdx))
+        return false;
+
+      // Early exit if all used lanes are checked. No need to continue.
+      Mask &= ~SR.LaneMask;
+      if (Mask.none())
+        break;
+    }
+  }
+  return true;
+}
+
+static Register isRegDependency(const MachineOperand &MO) {
+  if (!MO.isReg() || !MO.readsReg())
+    return Register();
+  Register Reg = MO.getReg();
+  if (Reg.isPhysical()) {
+    // By the requirements on trivially rematerializable instructions, a
+    // physical register use is either constant or ignorable.
+    return Register();
+  }
+  return Reg;
+}
+
+unsigned Rematerializer::rematerializeToRegion(unsigned RootIdx,
+                                               unsigned UseRegion,
+                                               DependencyReuseInfo &DRI) {
+
+  MachineInstr *FirstMI =
+      getReg(RootIdx).getRegionUseBounds(UseRegion, LIS).first;
+  unsigned NewRegIdx = rematerializeToPos(RootIdx, FirstMI, DRI);
+  transferRegionUsers(RootIdx, NewRegIdx, UseRegion);
+  return NewRegIdx;
+}
+
+unsigned
+Rematerializer::rematerializeToPos(unsigned RootIdx,
+                                   MachineBasicBlock::iterator InsertPos,
+                                   DependencyReuseInfo &DRI) {
+  LLVM_DEBUG({
+    rdbgs() << "Rematerializing " << printID(RootIdx) << " to "
+            << printUser(&*InsertPos) << '\n';
+    ++CallDepth;
+  });
+
+  // Create/identify dependencies for the new register. Copy the dependencies
+  // vector because underlying updates to the backing vector of registers may
+  // invalidate references.
+  SmallVector<Reg::Dependency, 2> NewDeps, Deps(Regs[RootIdx].Dependencies);
+  for (const Reg::Dependency &Dep : Deps) {
+    if (auto NewDep = DRI.DependencyMap.find(Dep.RegIdx);
+        NewDep != DRI.DependencyMap.end()) {
----------------
qcolombet wrote:

Could you do the assignment outside of the `if`?
Having 2 statements in the `if` looks wrong to me

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


More information about the llvm-commits mailing list