[llvm] Re-apply "[AMDGPU][Scheduler] Use MIR-level rematerializer in rematerialization stage (#189491)" (PR #192443)
Lucas Ramirez via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 06:06:33 PDT 2026
================
@@ -1594,44 +1591,52 @@ bool PreRARematStage::initGCNSchedStage() {
// in at least one target region.
if (!Cand.maybeBeneficial(TargetRegions, RPTargets)) {
REMAT_DEBUG(dbgs() << "Interrupt round on stale score for "
- << Cand.print() << " | " << *Cand.Remat->DefMI);
+ << Cand.print() << " | "
+ << Remater.printRematReg(Cand.RegIdx));
break;
}
CandidateOrder.pop_back();
- RematReg &Remat = *Cand.Remat;
-
- // Remove the register from all regions where it is a live-in or live-out
- // and rematerialize it.
- REMAT_DEBUG(dbgs() << "** REMAT " << PrintCandidate(Cand) << '\n');
- removeFromLiveMaps(Remat.getReg(), Cand.LiveIn, Cand.LiveOut);
- MachineInstr *RematMI = Cand.rematerialize(DAG);
-
- // Every rematerialization we do here is likely to move the instruction
- // into a higher frequency region, increasing the total sum latency of the
- // instruction itself. This is acceptable if we are eliminating a spill in
- // the process, but when the goal is increasing occupancy we get nothing
- // out of rematerialization if occupancy is not increased in the end; in
- // such cases we want to roll back the rematerialization.
- if (TargetOcc) {
- RollbackInfo &Rollback =
- Rollbacks.emplace_back(&Remat, Cand.LiveIn, Cand.LiveOut);
- Rollback.RematMI = RematMI;
- // Make the original MI a debug value so that it does not influence
- // scheduling and replace all read registers with a sentinel register to
- // prevent operands to appear in use-lists of other MIs during LIS
- // updates. Store mappings between operand indices and original
- // registers for potential rollback.
- Remat.DefMI->setDesc(DAG.TII->get(TargetOpcode::DBG_VALUE));
- for (auto [Idx, MO] : enumerate(Remat.DefMI->operands())) {
- if (MO.isReg() && MO.readsReg()) {
- Rollback.RegMap.insert({Idx, MO.getReg()});
- MO.setReg(Register());
- }
+
+#ifdef EXPENSIVE_CHECKS
+ // All uses are known to be available / live at the remat point. Thus,
+ // the uses should already be live in to the using region.
+ for (MachineOperand &MO : Reg.DefMI->operands()) {
+ if (!MO.isReg() || !MO.getReg() || !MO.readsReg())
+ continue;
+
+ Register UseReg = MO.getReg();
+ if (!UseReg.isVirtual())
+ continue;
+
+ LiveInterval &LI = DAG.LIS->getInterval(UseReg);
+ LaneBitmask LM = DAG.MRI.getMaxLaneMaskForVReg(MO.getReg());
+ if (LI.hasSubRanges() && MO.getSubReg())
+ LM = DAG.TRI->getSubRegIndexLaneMask(MO.getSubReg());
+
+ const unsigned UseRegion = Reg.Uses.begin()->first;
+ LaneBitmask LiveInMask = DAG.LiveIns[UseRegion].at(UseReg);
+ LaneBitmask UncoveredLanes = LM & ~(LiveInMask & LM);
+ // If this register has lanes not covered by the LiveIns, be sure they
+ // do not map to any subrange. ref:
+ // machine-scheduler-sink-trivial-remats.mir::omitted_subrange
+ if (UncoveredLanes.any()) {
+ assert(LI.hasSubRanges());
+ for (LiveInterval::SubRange &SR : LI.subranges())
+ assert((SR.LaneMask & UncoveredLanes).none());
}
- } else {
- // Just delete the original instruction if it cannot be rolled back.
- DAG.deleteMI(Remat.DefRegion, Remat.DefMI);
}
+#endif
----------------
lucas-rami wrote:
This is the block that moved from `PreRARematStage::ScoredRemat::rematerialize`, where it could not read e.g., the `DAG`.
https://github.com/llvm/llvm-project/pull/192443
More information about the llvm-commits
mailing list