xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/InlineSpiller.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- InlineSpiller.cpp - Insert spills and restores inline --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // The inline spiller modifies the machine function directly instead of
100b57cec5SDimitry Andric // inserting spills and restores in VirtRegMap.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "SplitKit.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
170b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h"
180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/LiveRangeEdit.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
395ffd83dbSDimitry Andric #include "llvm/CodeGen/Spiller.h"
405ffd83dbSDimitry Andric #include "llvm/CodeGen/StackMaps.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
440b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
450b57cec5SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
460b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
470b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h"
480b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
490b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
500b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
510b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
520b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
530b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
540b57cec5SDimitry Andric #include <cassert>
550b57cec5SDimitry Andric #include <iterator>
560b57cec5SDimitry Andric #include <tuple>
570b57cec5SDimitry Andric #include <utility>
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric using namespace llvm;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric #define DEBUG_TYPE "regalloc"
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric STATISTIC(NumSpilledRanges,   "Number of spilled live ranges");
640b57cec5SDimitry Andric STATISTIC(NumSnippets,        "Number of spilled snippets");
650b57cec5SDimitry Andric STATISTIC(NumSpills,          "Number of spills inserted");
660b57cec5SDimitry Andric STATISTIC(NumSpillsRemoved,   "Number of spills removed");
670b57cec5SDimitry Andric STATISTIC(NumReloads,         "Number of reloads inserted");
680b57cec5SDimitry Andric STATISTIC(NumReloadsRemoved,  "Number of reloads removed");
690b57cec5SDimitry Andric STATISTIC(NumFolded,          "Number of folded stack accesses");
700b57cec5SDimitry Andric STATISTIC(NumFoldedLoads,     "Number of folded loads");
710b57cec5SDimitry Andric STATISTIC(NumRemats,          "Number of rematerialized defs for spilling");
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric static cl::opt<bool>
740b57cec5SDimitry Andric RestrictStatepointRemat("restrict-statepoint-remat",
750b57cec5SDimitry Andric                        cl::init(false), cl::Hidden,
760b57cec5SDimitry Andric                        cl::desc("Restrict remat for statepoint operands"));
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric namespace {
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric class HoistSpillHelper : private LiveRangeEdit::Delegate {
810b57cec5SDimitry Andric   MachineFunction &MF;
820b57cec5SDimitry Andric   LiveIntervals &LIS;
830b57cec5SDimitry Andric   LiveStacks &LSS;
840b57cec5SDimitry Andric   MachineDominatorTree &MDT;
850b57cec5SDimitry Andric   VirtRegMap &VRM;
860b57cec5SDimitry Andric   MachineRegisterInfo &MRI;
870b57cec5SDimitry Andric   const TargetInstrInfo &TII;
880b57cec5SDimitry Andric   const TargetRegisterInfo &TRI;
890b57cec5SDimitry Andric   const MachineBlockFrequencyInfo &MBFI;
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   InsertPointAnalysis IPA;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   // Map from StackSlot to the LiveInterval of the original register.
940b57cec5SDimitry Andric   // Note the LiveInterval of the original register may have been deleted
950b57cec5SDimitry Andric   // after it is spilled. We keep a copy here to track the range where
960b57cec5SDimitry Andric   // spills can be moved.
970b57cec5SDimitry Andric   DenseMap<int, std::unique_ptr<LiveInterval>> StackSlotToOrigLI;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   // Map from pair of (StackSlot and Original VNI) to a set of spills which
1000b57cec5SDimitry Andric   // have the same stackslot and have equal values defined by Original VNI.
101bdd1243dSDimitry Andric   // These spills are mergeable and are hoist candidates.
1020b57cec5SDimitry Andric   using MergeableSpillsMap =
1030b57cec5SDimitry Andric       MapVector<std::pair<int, VNInfo *>, SmallPtrSet<MachineInstr *, 16>>;
1040b57cec5SDimitry Andric   MergeableSpillsMap MergeableSpills;
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   /// This is the map from original register to a set containing all its
1070b57cec5SDimitry Andric   /// siblings. To hoist a spill to another BB, we need to find out a live
1080b57cec5SDimitry Andric   /// sibling there and use it as the source of the new spill.
1095ffd83dbSDimitry Andric   DenseMap<Register, SmallSetVector<Register, 16>> Virt2SiblingsMap;
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   bool isSpillCandBB(LiveInterval &OrigLI, VNInfo &OrigVNI,
1125ffd83dbSDimitry Andric                      MachineBasicBlock &BB, Register &LiveReg);
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   void rmRedundantSpills(
1150b57cec5SDimitry Andric       SmallPtrSet<MachineInstr *, 16> &Spills,
1160b57cec5SDimitry Andric       SmallVectorImpl<MachineInstr *> &SpillsToRm,
1170b57cec5SDimitry Andric       DenseMap<MachineDomTreeNode *, MachineInstr *> &SpillBBToSpill);
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric   void getVisitOrders(
1200b57cec5SDimitry Andric       MachineBasicBlock *Root, SmallPtrSet<MachineInstr *, 16> &Spills,
1210b57cec5SDimitry Andric       SmallVectorImpl<MachineDomTreeNode *> &Orders,
1220b57cec5SDimitry Andric       SmallVectorImpl<MachineInstr *> &SpillsToRm,
1230b57cec5SDimitry Andric       DenseMap<MachineDomTreeNode *, unsigned> &SpillsToKeep,
1240b57cec5SDimitry Andric       DenseMap<MachineDomTreeNode *, MachineInstr *> &SpillBBToSpill);
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   void runHoistSpills(LiveInterval &OrigLI, VNInfo &OrigVNI,
1270b57cec5SDimitry Andric                       SmallPtrSet<MachineInstr *, 16> &Spills,
1280b57cec5SDimitry Andric                       SmallVectorImpl<MachineInstr *> &SpillsToRm,
1290b57cec5SDimitry Andric                       DenseMap<MachineBasicBlock *, unsigned> &SpillsToIns);
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric public:
1320b57cec5SDimitry Andric   HoistSpillHelper(MachineFunctionPass &pass, MachineFunction &mf,
1330b57cec5SDimitry Andric                    VirtRegMap &vrm)
134*0fca6ea1SDimitry Andric       : MF(mf), LIS(pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
1350b57cec5SDimitry Andric         LSS(pass.getAnalysis<LiveStacks>()),
136*0fca6ea1SDimitry Andric         MDT(pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
137*0fca6ea1SDimitry Andric         VRM(vrm), MRI(mf.getRegInfo()), TII(*mf.getSubtarget().getInstrInfo()),
1380b57cec5SDimitry Andric         TRI(*mf.getSubtarget().getRegisterInfo()),
139*0fca6ea1SDimitry Andric         MBFI(
140*0fca6ea1SDimitry Andric             pass.getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()),
1410b57cec5SDimitry Andric         IPA(LIS, mf.getNumBlockIDs()) {}
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   void addToMergeableSpills(MachineInstr &Spill, int StackSlot,
1440b57cec5SDimitry Andric                             unsigned Original);
1450b57cec5SDimitry Andric   bool rmFromMergeableSpills(MachineInstr &Spill, int StackSlot);
1460b57cec5SDimitry Andric   void hoistAllSpills();
147e8d8bef9SDimitry Andric   void LRE_DidCloneVirtReg(Register, Register) override;
1480b57cec5SDimitry Andric };
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric class InlineSpiller : public Spiller {
1510b57cec5SDimitry Andric   MachineFunction &MF;
1520b57cec5SDimitry Andric   LiveIntervals &LIS;
1530b57cec5SDimitry Andric   LiveStacks &LSS;
1540b57cec5SDimitry Andric   MachineDominatorTree &MDT;
1550b57cec5SDimitry Andric   VirtRegMap &VRM;
1560b57cec5SDimitry Andric   MachineRegisterInfo &MRI;
1570b57cec5SDimitry Andric   const TargetInstrInfo &TII;
1580b57cec5SDimitry Andric   const TargetRegisterInfo &TRI;
1590b57cec5SDimitry Andric   const MachineBlockFrequencyInfo &MBFI;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   // Variables that are valid during spill(), but used by multiple methods.
16206c3fb27SDimitry Andric   LiveRangeEdit *Edit = nullptr;
16306c3fb27SDimitry Andric   LiveInterval *StackInt = nullptr;
1640b57cec5SDimitry Andric   int StackSlot;
165fe6060f1SDimitry Andric   Register Original;
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   // All registers to spill to StackSlot, including the main register.
1685ffd83dbSDimitry Andric   SmallVector<Register, 8> RegsToSpill;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   // All COPY instructions to/from snippets.
1710b57cec5SDimitry Andric   // They are ignored since both operands refer to the same stack slot.
17206c3fb27SDimitry Andric   // For bundled copies, this will only include the first header copy.
1730b57cec5SDimitry Andric   SmallPtrSet<MachineInstr*, 8> SnippetCopies;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   // Values that failed to remat at some point.
1760b57cec5SDimitry Andric   SmallPtrSet<VNInfo*, 8> UsedValues;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   // Dead defs generated during spilling.
1790b57cec5SDimitry Andric   SmallVector<MachineInstr*, 8> DeadDefs;
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   // Object records spills information and does the hoisting.
1820b57cec5SDimitry Andric   HoistSpillHelper HSpiller;
1830b57cec5SDimitry Andric 
184fe6060f1SDimitry Andric   // Live range weight calculator.
185fe6060f1SDimitry Andric   VirtRegAuxInfo &VRAI;
186fe6060f1SDimitry Andric 
1870b57cec5SDimitry Andric   ~InlineSpiller() override = default;
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric public:
190fe6060f1SDimitry Andric   InlineSpiller(MachineFunctionPass &Pass, MachineFunction &MF, VirtRegMap &VRM,
191fe6060f1SDimitry Andric                 VirtRegAuxInfo &VRAI)
192*0fca6ea1SDimitry Andric       : MF(MF), LIS(Pass.getAnalysis<LiveIntervalsWrapperPass>().getLIS()),
193fe6060f1SDimitry Andric         LSS(Pass.getAnalysis<LiveStacks>()),
194*0fca6ea1SDimitry Andric         MDT(Pass.getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree()),
195*0fca6ea1SDimitry Andric         VRM(VRM), MRI(MF.getRegInfo()), TII(*MF.getSubtarget().getInstrInfo()),
196fe6060f1SDimitry Andric         TRI(*MF.getSubtarget().getRegisterInfo()),
197*0fca6ea1SDimitry Andric         MBFI(
198*0fca6ea1SDimitry Andric             Pass.getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI()),
199fe6060f1SDimitry Andric         HSpiller(Pass, MF, VRM), VRAI(VRAI) {}
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   void spill(LiveRangeEdit &) override;
2020b57cec5SDimitry Andric   void postOptimization() override;
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric private:
2050b57cec5SDimitry Andric   bool isSnippet(const LiveInterval &SnipLI);
2060b57cec5SDimitry Andric   void collectRegsToSpill();
2070b57cec5SDimitry Andric 
2085ffd83dbSDimitry Andric   bool isRegToSpill(Register Reg) { return is_contained(RegsToSpill, Reg); }
2090b57cec5SDimitry Andric 
2105ffd83dbSDimitry Andric   bool isSibling(Register Reg);
2110b57cec5SDimitry Andric   bool hoistSpillInsideBB(LiveInterval &SpillLI, MachineInstr &CopyMI);
2120b57cec5SDimitry Andric   void eliminateRedundantSpills(LiveInterval &LI, VNInfo *VNI);
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   void markValueUsed(LiveInterval*, VNInfo*);
2155ffd83dbSDimitry Andric   bool canGuaranteeAssignmentAfterRemat(Register VReg, MachineInstr &MI);
2160b57cec5SDimitry Andric   bool reMaterializeFor(LiveInterval &, MachineInstr &MI);
2170b57cec5SDimitry Andric   void reMaterializeAll();
2180b57cec5SDimitry Andric 
2195ffd83dbSDimitry Andric   bool coalesceStackAccess(MachineInstr *MI, Register Reg);
2200b57cec5SDimitry Andric   bool foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>>,
2210b57cec5SDimitry Andric                          MachineInstr *LoadMI = nullptr);
2225ffd83dbSDimitry Andric   void insertReload(Register VReg, SlotIndex, MachineBasicBlock::iterator MI);
2235ffd83dbSDimitry Andric   void insertSpill(Register VReg, bool isKill, MachineBasicBlock::iterator MI);
2240b57cec5SDimitry Andric 
2255ffd83dbSDimitry Andric   void spillAroundUses(Register Reg);
2260b57cec5SDimitry Andric   void spillAll();
2270b57cec5SDimitry Andric };
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric } // end anonymous namespace
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric Spiller::~Spiller() = default;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric void Spiller::anchor() {}
2340b57cec5SDimitry Andric 
235fe6060f1SDimitry Andric Spiller *llvm::createInlineSpiller(MachineFunctionPass &Pass,
236fe6060f1SDimitry Andric                                    MachineFunction &MF, VirtRegMap &VRM,
237fe6060f1SDimitry Andric                                    VirtRegAuxInfo &VRAI) {
238fe6060f1SDimitry Andric   return new InlineSpiller(Pass, MF, VRM, VRAI);
2390b57cec5SDimitry Andric }
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2420b57cec5SDimitry Andric //                                Snippets
2430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric // When spilling a virtual register, we also spill any snippets it is connected
2460b57cec5SDimitry Andric // to. The snippets are small live ranges that only have a single real use,
2470b57cec5SDimitry Andric // leftovers from live range splitting. Spilling them enables memory operand
2480b57cec5SDimitry Andric // folding or tightens the live range around the single use.
2490b57cec5SDimitry Andric //
2500b57cec5SDimitry Andric // This minimizes register pressure and maximizes the store-to-load distance for
2510b57cec5SDimitry Andric // spill slots which can be important in tight loops.
2520b57cec5SDimitry Andric 
2535f757f3fSDimitry Andric /// isFullCopyOf - If MI is a COPY to or from Reg, return the other register,
2545f757f3fSDimitry Andric /// otherwise return 0.
2555f757f3fSDimitry Andric static Register isCopyOf(const MachineInstr &MI, Register Reg,
2565f757f3fSDimitry Andric                          const TargetInstrInfo &TII) {
2575f757f3fSDimitry Andric   if (!TII.isCopyInstr(MI))
2585ffd83dbSDimitry Andric     return Register();
25906c3fb27SDimitry Andric 
26006c3fb27SDimitry Andric   const MachineOperand &DstOp = MI.getOperand(0);
26106c3fb27SDimitry Andric   const MachineOperand &SrcOp = MI.getOperand(1);
26206c3fb27SDimitry Andric 
26306c3fb27SDimitry Andric   // TODO: Probably only worth allowing subreg copies with undef dests.
26406c3fb27SDimitry Andric   if (DstOp.getSubReg() != SrcOp.getSubReg())
26506c3fb27SDimitry Andric     return Register();
26606c3fb27SDimitry Andric   if (DstOp.getReg() == Reg)
26706c3fb27SDimitry Andric     return SrcOp.getReg();
26806c3fb27SDimitry Andric   if (SrcOp.getReg() == Reg)
26906c3fb27SDimitry Andric     return DstOp.getReg();
27006c3fb27SDimitry Andric   return Register();
27106c3fb27SDimitry Andric }
27206c3fb27SDimitry Andric 
27306c3fb27SDimitry Andric /// Check for a copy bundle as formed by SplitKit.
2745f757f3fSDimitry Andric static Register isCopyOfBundle(const MachineInstr &FirstMI, Register Reg,
2755f757f3fSDimitry Andric                                const TargetInstrInfo &TII) {
27606c3fb27SDimitry Andric   if (!FirstMI.isBundled())
2775f757f3fSDimitry Andric     return isCopyOf(FirstMI, Reg, TII);
27806c3fb27SDimitry Andric 
27906c3fb27SDimitry Andric   assert(!FirstMI.isBundledWithPred() && FirstMI.isBundledWithSucc() &&
28006c3fb27SDimitry Andric          "expected to see first instruction in bundle");
28106c3fb27SDimitry Andric 
28206c3fb27SDimitry Andric   Register SnipReg;
28306c3fb27SDimitry Andric   MachineBasicBlock::const_instr_iterator I = FirstMI.getIterator();
28406c3fb27SDimitry Andric   while (I->isBundledWithSucc()) {
28506c3fb27SDimitry Andric     const MachineInstr &MI = *I;
2865f757f3fSDimitry Andric     auto CopyInst = TII.isCopyInstr(MI);
2875f757f3fSDimitry Andric     if (!CopyInst)
28806c3fb27SDimitry Andric       return Register();
28906c3fb27SDimitry Andric 
2905f757f3fSDimitry Andric     const MachineOperand &DstOp = *CopyInst->Destination;
2915f757f3fSDimitry Andric     const MachineOperand &SrcOp = *CopyInst->Source;
29206c3fb27SDimitry Andric     if (DstOp.getReg() == Reg) {
29306c3fb27SDimitry Andric       if (!SnipReg)
29406c3fb27SDimitry Andric         SnipReg = SrcOp.getReg();
29506c3fb27SDimitry Andric       else if (SnipReg != SrcOp.getReg())
29606c3fb27SDimitry Andric         return Register();
29706c3fb27SDimitry Andric     } else if (SrcOp.getReg() == Reg) {
29806c3fb27SDimitry Andric       if (!SnipReg)
29906c3fb27SDimitry Andric         SnipReg = DstOp.getReg();
30006c3fb27SDimitry Andric       else if (SnipReg != DstOp.getReg())
30106c3fb27SDimitry Andric         return Register();
30206c3fb27SDimitry Andric     }
30306c3fb27SDimitry Andric 
30406c3fb27SDimitry Andric     ++I;
30506c3fb27SDimitry Andric   }
30606c3fb27SDimitry Andric 
3075ffd83dbSDimitry Andric   return Register();
3080b57cec5SDimitry Andric }
3090b57cec5SDimitry Andric 
310e8d8bef9SDimitry Andric static void getVDefInterval(const MachineInstr &MI, LiveIntervals &LIS) {
31106c3fb27SDimitry Andric   for (const MachineOperand &MO : MI.all_defs())
31206c3fb27SDimitry Andric     if (MO.getReg().isVirtual())
313e8d8bef9SDimitry Andric       LIS.getInterval(MO.getReg());
314e8d8bef9SDimitry Andric }
315e8d8bef9SDimitry Andric 
3160b57cec5SDimitry Andric /// isSnippet - Identify if a live interval is a snippet that should be spilled.
3170b57cec5SDimitry Andric /// It is assumed that SnipLI is a virtual register with the same original as
3180b57cec5SDimitry Andric /// Edit->getReg().
3190b57cec5SDimitry Andric bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) {
3205ffd83dbSDimitry Andric   Register Reg = Edit->getReg();
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   // A snippet is a tiny live range with only a single instruction using it
323bdd1243dSDimitry Andric   // besides copies to/from Reg or spills/fills.
324bdd1243dSDimitry Andric   // Exception is done for statepoint instructions which will fold fills
325bdd1243dSDimitry Andric   // into their operands.
326bdd1243dSDimitry Andric   // We accept:
3270b57cec5SDimitry Andric   //
3280b57cec5SDimitry Andric   //   %snip = COPY %Reg / FILL fi#
3290b57cec5SDimitry Andric   //   %snip = USE %snip
330bdd1243dSDimitry Andric   //   %snip = STATEPOINT %snip in var arg area
3310b57cec5SDimitry Andric   //   %Reg = COPY %snip / SPILL %snip, fi#
3320b57cec5SDimitry Andric   //
333bdd1243dSDimitry Andric   if (!LIS.intervalIsInOneMBB(SnipLI))
334bdd1243dSDimitry Andric     return false;
335bdd1243dSDimitry Andric 
336bdd1243dSDimitry Andric   // Number of defs should not exceed 2 not accounting defs coming from
337bdd1243dSDimitry Andric   // statepoint instructions.
338bdd1243dSDimitry Andric   unsigned NumValNums = SnipLI.getNumValNums();
339bdd1243dSDimitry Andric   for (auto *VNI : SnipLI.vnis()) {
340bdd1243dSDimitry Andric     MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
341bdd1243dSDimitry Andric     if (MI->getOpcode() == TargetOpcode::STATEPOINT)
342bdd1243dSDimitry Andric       --NumValNums;
343bdd1243dSDimitry Andric   }
344bdd1243dSDimitry Andric   if (NumValNums > 2)
3450b57cec5SDimitry Andric     return false;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   MachineInstr *UseMI = nullptr;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric   // Check that all uses satisfy our criteria.
35006c3fb27SDimitry Andric   for (MachineRegisterInfo::reg_bundle_nodbg_iterator
35106c3fb27SDimitry Andric            RI = MRI.reg_bundle_nodbg_begin(SnipLI.reg()),
35206c3fb27SDimitry Andric            E = MRI.reg_bundle_nodbg_end();
353e8d8bef9SDimitry Andric        RI != E;) {
3540b57cec5SDimitry Andric     MachineInstr &MI = *RI++;
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric     // Allow copies to/from Reg.
3575f757f3fSDimitry Andric     if (isCopyOfBundle(MI, Reg, TII))
3580b57cec5SDimitry Andric       continue;
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric     // Allow stack slot loads.
3610b57cec5SDimitry Andric     int FI;
362e8d8bef9SDimitry Andric     if (SnipLI.reg() == TII.isLoadFromStackSlot(MI, FI) && FI == StackSlot)
3630b57cec5SDimitry Andric       continue;
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric     // Allow stack slot stores.
366e8d8bef9SDimitry Andric     if (SnipLI.reg() == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot)
3670b57cec5SDimitry Andric       continue;
3680b57cec5SDimitry Andric 
369bdd1243dSDimitry Andric     if (StatepointOpers::isFoldableReg(&MI, SnipLI.reg()))
370bdd1243dSDimitry Andric       continue;
371bdd1243dSDimitry Andric 
3720b57cec5SDimitry Andric     // Allow a single additional instruction.
3730b57cec5SDimitry Andric     if (UseMI && &MI != UseMI)
3740b57cec5SDimitry Andric       return false;
3750b57cec5SDimitry Andric     UseMI = &MI;
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric   return true;
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric /// collectRegsToSpill - Collect live range snippets that only have a single
3810b57cec5SDimitry Andric /// real use.
3820b57cec5SDimitry Andric void InlineSpiller::collectRegsToSpill() {
3835ffd83dbSDimitry Andric   Register Reg = Edit->getReg();
3840b57cec5SDimitry Andric 
3850b57cec5SDimitry Andric   // Main register always spills.
3860b57cec5SDimitry Andric   RegsToSpill.assign(1, Reg);
3870b57cec5SDimitry Andric   SnippetCopies.clear();
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   // Snippets all have the same original, so there can't be any for an original
3900b57cec5SDimitry Andric   // register.
3910b57cec5SDimitry Andric   if (Original == Reg)
3920b57cec5SDimitry Andric     return;
3930b57cec5SDimitry Andric 
39406c3fb27SDimitry Andric   for (MachineInstr &MI : llvm::make_early_inc_range(MRI.reg_bundles(Reg))) {
3955f757f3fSDimitry Andric     Register SnipReg = isCopyOfBundle(MI, Reg, TII);
3960b57cec5SDimitry Andric     if (!isSibling(SnipReg))
3970b57cec5SDimitry Andric       continue;
3980b57cec5SDimitry Andric     LiveInterval &SnipLI = LIS.getInterval(SnipReg);
3990b57cec5SDimitry Andric     if (!isSnippet(SnipLI))
4000b57cec5SDimitry Andric       continue;
4010b57cec5SDimitry Andric     SnippetCopies.insert(&MI);
4020b57cec5SDimitry Andric     if (isRegToSpill(SnipReg))
4030b57cec5SDimitry Andric       continue;
4040b57cec5SDimitry Andric     RegsToSpill.push_back(SnipReg);
4050b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\talso spill snippet " << SnipLI << '\n');
4060b57cec5SDimitry Andric     ++NumSnippets;
4070b57cec5SDimitry Andric   }
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric 
4105ffd83dbSDimitry Andric bool InlineSpiller::isSibling(Register Reg) {
4115ffd83dbSDimitry Andric   return Reg.isVirtual() && VRM.getOriginal(Reg) == Original;
4120b57cec5SDimitry Andric }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric /// It is beneficial to spill to earlier place in the same BB in case
4150b57cec5SDimitry Andric /// as follows:
4160b57cec5SDimitry Andric /// There is an alternative def earlier in the same MBB.
4170b57cec5SDimitry Andric /// Hoist the spill as far as possible in SpillMBB. This can ease
4180b57cec5SDimitry Andric /// register pressure:
4190b57cec5SDimitry Andric ///
4200b57cec5SDimitry Andric ///   x = def
4210b57cec5SDimitry Andric ///   y = use x
4220b57cec5SDimitry Andric ///   s = copy x
4230b57cec5SDimitry Andric ///
4240b57cec5SDimitry Andric /// Hoisting the spill of s to immediately after the def removes the
4250b57cec5SDimitry Andric /// interference between x and y:
4260b57cec5SDimitry Andric ///
4270b57cec5SDimitry Andric ///   x = def
4280b57cec5SDimitry Andric ///   spill x
4290b57cec5SDimitry Andric ///   y = use killed x
4300b57cec5SDimitry Andric ///
4310b57cec5SDimitry Andric /// This hoist only helps when the copy kills its source.
4320b57cec5SDimitry Andric ///
4330b57cec5SDimitry Andric bool InlineSpiller::hoistSpillInsideBB(LiveInterval &SpillLI,
4340b57cec5SDimitry Andric                                        MachineInstr &CopyMI) {
4350b57cec5SDimitry Andric   SlotIndex Idx = LIS.getInstructionIndex(CopyMI);
4360b57cec5SDimitry Andric #ifndef NDEBUG
4370b57cec5SDimitry Andric   VNInfo *VNI = SpillLI.getVNInfoAt(Idx.getRegSlot());
4380b57cec5SDimitry Andric   assert(VNI && VNI->def == Idx.getRegSlot() && "Not defined by copy");
4390b57cec5SDimitry Andric #endif
4400b57cec5SDimitry Andric 
4418bcb0991SDimitry Andric   Register SrcReg = CopyMI.getOperand(1).getReg();
4420b57cec5SDimitry Andric   LiveInterval &SrcLI = LIS.getInterval(SrcReg);
4430b57cec5SDimitry Andric   VNInfo *SrcVNI = SrcLI.getVNInfoAt(Idx);
4440b57cec5SDimitry Andric   LiveQueryResult SrcQ = SrcLI.Query(Idx);
4450b57cec5SDimitry Andric   MachineBasicBlock *DefMBB = LIS.getMBBFromIndex(SrcVNI->def);
4460b57cec5SDimitry Andric   if (DefMBB != CopyMI.getParent() || !SrcQ.isKill())
4470b57cec5SDimitry Andric     return false;
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   // Conservatively extend the stack slot range to the range of the original
4500b57cec5SDimitry Andric   // value. We may be able to do better with stack slot coloring by being more
4510b57cec5SDimitry Andric   // careful here.
4520b57cec5SDimitry Andric   assert(StackInt && "No stack slot assigned yet.");
4530b57cec5SDimitry Andric   LiveInterval &OrigLI = LIS.getInterval(Original);
4540b57cec5SDimitry Andric   VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx);
4550b57cec5SDimitry Andric   StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
4560b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tmerged orig valno " << OrigVNI->id << ": "
4570b57cec5SDimitry Andric                     << *StackInt << '\n');
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   // We are going to spill SrcVNI immediately after its def, so clear out
4600b57cec5SDimitry Andric   // any later spills of the same value.
4610b57cec5SDimitry Andric   eliminateRedundantSpills(SrcLI, SrcVNI);
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   MachineBasicBlock *MBB = LIS.getMBBFromIndex(SrcVNI->def);
4640b57cec5SDimitry Andric   MachineBasicBlock::iterator MII;
4650b57cec5SDimitry Andric   if (SrcVNI->isPHIDef())
4665f757f3fSDimitry Andric     MII = MBB->SkipPHIsLabelsAndDebug(MBB->begin(), SrcReg);
4670b57cec5SDimitry Andric   else {
4680b57cec5SDimitry Andric     MachineInstr *DefMI = LIS.getInstructionFromIndex(SrcVNI->def);
4690b57cec5SDimitry Andric     assert(DefMI && "Defining instruction disappeared");
4700b57cec5SDimitry Andric     MII = DefMI;
4710b57cec5SDimitry Andric     ++MII;
4720b57cec5SDimitry Andric   }
473e8d8bef9SDimitry Andric   MachineInstrSpan MIS(MII, MBB);
4740b57cec5SDimitry Andric   // Insert spill without kill flag immediately after def.
4750b57cec5SDimitry Andric   TII.storeRegToStackSlot(*MBB, MII, SrcReg, false, StackSlot,
476bdd1243dSDimitry Andric                           MRI.getRegClass(SrcReg), &TRI, Register());
477e8d8bef9SDimitry Andric   LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
478e8d8bef9SDimitry Andric   for (const MachineInstr &MI : make_range(MIS.begin(), MII))
479e8d8bef9SDimitry Andric     getVDefInterval(MI, LIS);
4800b57cec5SDimitry Andric   --MII; // Point to store instruction.
4810b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\thoisted: " << SrcVNI->def << '\t' << *MII);
4820b57cec5SDimitry Andric 
483e8d8bef9SDimitry Andric   // If there is only 1 store instruction is required for spill, add it
484e8d8bef9SDimitry Andric   // to mergeable list. In X86 AMX, 2 intructions are required to store.
485e8d8bef9SDimitry Andric   // We disable the merge for this case.
486e8d8bef9SDimitry Andric   if (MIS.begin() == MII)
4870b57cec5SDimitry Andric     HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
4880b57cec5SDimitry Andric   ++NumSpills;
4890b57cec5SDimitry Andric   return true;
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric /// eliminateRedundantSpills - SLI:VNI is known to be on the stack. Remove any
4930b57cec5SDimitry Andric /// redundant spills of this value in SLI.reg and sibling copies.
4940b57cec5SDimitry Andric void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) {
4950b57cec5SDimitry Andric   assert(VNI && "Missing value");
4960b57cec5SDimitry Andric   SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
4970b57cec5SDimitry Andric   WorkList.push_back(std::make_pair(&SLI, VNI));
4980b57cec5SDimitry Andric   assert(StackInt && "No stack slot assigned yet.");
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric   do {
5010b57cec5SDimitry Andric     LiveInterval *LI;
5020b57cec5SDimitry Andric     std::tie(LI, VNI) = WorkList.pop_back_val();
503e8d8bef9SDimitry Andric     Register Reg = LI->reg();
5040b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Checking redundant spills for " << VNI->id << '@'
5050b57cec5SDimitry Andric                       << VNI->def << " in " << *LI << '\n');
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric     // Regs to spill are taken care of.
5080b57cec5SDimitry Andric     if (isRegToSpill(Reg))
5090b57cec5SDimitry Andric       continue;
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric     // Add all of VNI's live range to StackInt.
5120b57cec5SDimitry Andric     StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
5130b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Merged to stack int: " << *StackInt << '\n');
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric     // Find all spills and copies of VNI.
516349cc55cSDimitry Andric     for (MachineInstr &MI :
51706c3fb27SDimitry Andric          llvm::make_early_inc_range(MRI.use_nodbg_bundles(Reg))) {
5185f757f3fSDimitry Andric       if (!MI.mayStore() && !TII.isCopyInstr(MI))
5190b57cec5SDimitry Andric         continue;
5200b57cec5SDimitry Andric       SlotIndex Idx = LIS.getInstructionIndex(MI);
5210b57cec5SDimitry Andric       if (LI->getVNInfoAt(Idx) != VNI)
5220b57cec5SDimitry Andric         continue;
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric       // Follow sibling copies down the dominator tree.
5255f757f3fSDimitry Andric       if (Register DstReg = isCopyOfBundle(MI, Reg, TII)) {
5260b57cec5SDimitry Andric         if (isSibling(DstReg)) {
5270b57cec5SDimitry Andric           LiveInterval &DstLI = LIS.getInterval(DstReg);
5280b57cec5SDimitry Andric           VNInfo *DstVNI = DstLI.getVNInfoAt(Idx.getRegSlot());
5290b57cec5SDimitry Andric           assert(DstVNI && "Missing defined value");
5300b57cec5SDimitry Andric           assert(DstVNI->def == Idx.getRegSlot() && "Wrong copy def slot");
53106c3fb27SDimitry Andric 
5320b57cec5SDimitry Andric           WorkList.push_back(std::make_pair(&DstLI, DstVNI));
5330b57cec5SDimitry Andric         }
5340b57cec5SDimitry Andric         continue;
5350b57cec5SDimitry Andric       }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric       // Erase spills.
5380b57cec5SDimitry Andric       int FI;
5390b57cec5SDimitry Andric       if (Reg == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot) {
5400b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Redundant spill " << Idx << '\t' << MI);
5410b57cec5SDimitry Andric         // eliminateDeadDefs won't normally remove stores, so switch opcode.
5420b57cec5SDimitry Andric         MI.setDesc(TII.get(TargetOpcode::KILL));
5430b57cec5SDimitry Andric         DeadDefs.push_back(&MI);
5440b57cec5SDimitry Andric         ++NumSpillsRemoved;
5450b57cec5SDimitry Andric         if (HSpiller.rmFromMergeableSpills(MI, StackSlot))
5460b57cec5SDimitry Andric           --NumSpills;
5470b57cec5SDimitry Andric       }
5480b57cec5SDimitry Andric     }
5490b57cec5SDimitry Andric   } while (!WorkList.empty());
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric 
5520b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5530b57cec5SDimitry Andric //                            Rematerialization
5540b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5550b57cec5SDimitry Andric 
5560b57cec5SDimitry Andric /// markValueUsed - Remember that VNI failed to rematerialize, so its defining
5570b57cec5SDimitry Andric /// instruction cannot be eliminated. See through snippet copies
5580b57cec5SDimitry Andric void InlineSpiller::markValueUsed(LiveInterval *LI, VNInfo *VNI) {
5590b57cec5SDimitry Andric   SmallVector<std::pair<LiveInterval*, VNInfo*>, 8> WorkList;
5600b57cec5SDimitry Andric   WorkList.push_back(std::make_pair(LI, VNI));
5610b57cec5SDimitry Andric   do {
5620b57cec5SDimitry Andric     std::tie(LI, VNI) = WorkList.pop_back_val();
5630b57cec5SDimitry Andric     if (!UsedValues.insert(VNI).second)
5640b57cec5SDimitry Andric       continue;
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric     if (VNI->isPHIDef()) {
5670b57cec5SDimitry Andric       MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
5680b57cec5SDimitry Andric       for (MachineBasicBlock *P : MBB->predecessors()) {
5690b57cec5SDimitry Andric         VNInfo *PVNI = LI->getVNInfoBefore(LIS.getMBBEndIdx(P));
5700b57cec5SDimitry Andric         if (PVNI)
5710b57cec5SDimitry Andric           WorkList.push_back(std::make_pair(LI, PVNI));
5720b57cec5SDimitry Andric       }
5730b57cec5SDimitry Andric       continue;
5740b57cec5SDimitry Andric     }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric     // Follow snippet copies.
5770b57cec5SDimitry Andric     MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
5780b57cec5SDimitry Andric     if (!SnippetCopies.count(MI))
5790b57cec5SDimitry Andric       continue;
5800b57cec5SDimitry Andric     LiveInterval &SnipLI = LIS.getInterval(MI->getOperand(1).getReg());
581e8d8bef9SDimitry Andric     assert(isRegToSpill(SnipLI.reg()) && "Unexpected register in copy");
5820b57cec5SDimitry Andric     VNInfo *SnipVNI = SnipLI.getVNInfoAt(VNI->def.getRegSlot(true));
5830b57cec5SDimitry Andric     assert(SnipVNI && "Snippet undefined before copy");
5840b57cec5SDimitry Andric     WorkList.push_back(std::make_pair(&SnipLI, SnipVNI));
5850b57cec5SDimitry Andric   } while (!WorkList.empty());
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric 
5885ffd83dbSDimitry Andric bool InlineSpiller::canGuaranteeAssignmentAfterRemat(Register VReg,
5890b57cec5SDimitry Andric                                                      MachineInstr &MI) {
5900b57cec5SDimitry Andric   if (!RestrictStatepointRemat)
5910b57cec5SDimitry Andric     return true;
5920b57cec5SDimitry Andric   // Here's a quick explanation of the problem we're trying to handle here:
5930b57cec5SDimitry Andric   // * There are some pseudo instructions with more vreg uses than there are
5940b57cec5SDimitry Andric   //   physical registers on the machine.
5950b57cec5SDimitry Andric   // * This is normally handled by spilling the vreg, and folding the reload
5960b57cec5SDimitry Andric   //   into the user instruction.  (Thus decreasing the number of used vregs
5970b57cec5SDimitry Andric   //   until the remainder can be assigned to physregs.)
5980b57cec5SDimitry Andric   // * However, since we may try to spill vregs in any order, we can end up
5990b57cec5SDimitry Andric   //   trying to spill each operand to the instruction, and then rematting it
6000b57cec5SDimitry Andric   //   instead.  When that happens, the new live intervals (for the remats) are
6010b57cec5SDimitry Andric   //   expected to be trivially assignable (i.e. RS_Done).  However, since we
6020b57cec5SDimitry Andric   //   may have more remats than physregs, we're guaranteed to fail to assign
6030b57cec5SDimitry Andric   //   one.
6040b57cec5SDimitry Andric   // At the moment, we only handle this for STATEPOINTs since they're the only
605480093f4SDimitry Andric   // pseudo op where we've seen this.  If we start seeing other instructions
6060b57cec5SDimitry Andric   // with the same problem, we need to revisit this.
6075ffd83dbSDimitry Andric   if (MI.getOpcode() != TargetOpcode::STATEPOINT)
6085ffd83dbSDimitry Andric     return true;
6095ffd83dbSDimitry Andric   // For STATEPOINTs we allow re-materialization for fixed arguments only hoping
6105ffd83dbSDimitry Andric   // that number of physical registers is enough to cover all fixed arguments.
6115ffd83dbSDimitry Andric   // If it is not true we need to revisit it.
6125ffd83dbSDimitry Andric   for (unsigned Idx = StatepointOpers(&MI).getVarIdx(),
6135ffd83dbSDimitry Andric                 EndIdx = MI.getNumOperands();
6145ffd83dbSDimitry Andric        Idx < EndIdx; ++Idx) {
6155ffd83dbSDimitry Andric     MachineOperand &MO = MI.getOperand(Idx);
6165ffd83dbSDimitry Andric     if (MO.isReg() && MO.getReg() == VReg)
6175ffd83dbSDimitry Andric       return false;
6185ffd83dbSDimitry Andric   }
6195ffd83dbSDimitry Andric   return true;
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
6220b57cec5SDimitry Andric /// reMaterializeFor - Attempt to rematerialize before MI instead of reloading.
6230b57cec5SDimitry Andric bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg, MachineInstr &MI) {
6240b57cec5SDimitry Andric   // Analyze instruction
6250b57cec5SDimitry Andric   SmallVector<std::pair<MachineInstr *, unsigned>, 8> Ops;
626e8d8bef9SDimitry Andric   VirtRegInfo RI = AnalyzeVirtRegInBundle(MI, VirtReg.reg(), &Ops);
6270b57cec5SDimitry Andric 
6280b57cec5SDimitry Andric   if (!RI.Reads)
6290b57cec5SDimitry Andric     return false;
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric   SlotIndex UseIdx = LIS.getInstructionIndex(MI).getRegSlot(true);
6320b57cec5SDimitry Andric   VNInfo *ParentVNI = VirtReg.getVNInfoAt(UseIdx.getBaseIndex());
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric   if (!ParentVNI) {
6350b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tadding <undef> flags: ");
63606c3fb27SDimitry Andric     for (MachineOperand &MO : MI.all_uses())
63706c3fb27SDimitry Andric       if (MO.getReg() == VirtReg.reg())
6380b57cec5SDimitry Andric         MO.setIsUndef();
6390b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << UseIdx << '\t' << MI);
6400b57cec5SDimitry Andric     return true;
6410b57cec5SDimitry Andric   }
6420b57cec5SDimitry Andric 
6430b57cec5SDimitry Andric   if (SnippetCopies.count(&MI))
6440b57cec5SDimitry Andric     return false;
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric   LiveInterval &OrigLI = LIS.getInterval(Original);
6470b57cec5SDimitry Andric   VNInfo *OrigVNI = OrigLI.getVNInfoAt(UseIdx);
6480b57cec5SDimitry Andric   LiveRangeEdit::Remat RM(ParentVNI);
6490b57cec5SDimitry Andric   RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->def);
6500b57cec5SDimitry Andric 
6510b57cec5SDimitry Andric   if (!Edit->canRematerializeAt(RM, OrigVNI, UseIdx, false)) {
6520b57cec5SDimitry Andric     markValueUsed(&VirtReg, ParentVNI);
6530b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << MI);
6540b57cec5SDimitry Andric     return false;
6550b57cec5SDimitry Andric   }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   // If the instruction also writes VirtReg.reg, it had better not require the
6580b57cec5SDimitry Andric   // same register for uses and defs.
6590b57cec5SDimitry Andric   if (RI.Tied) {
6600b57cec5SDimitry Andric     markValueUsed(&VirtReg, ParentVNI);
6610b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tcannot remat tied reg: " << UseIdx << '\t' << MI);
6620b57cec5SDimitry Andric     return false;
6630b57cec5SDimitry Andric   }
6640b57cec5SDimitry Andric 
6650b57cec5SDimitry Andric   // Before rematerializing into a register for a single instruction, try to
6660b57cec5SDimitry Andric   // fold a load into the instruction. That avoids allocating a new register.
6670b57cec5SDimitry Andric   if (RM.OrigMI->canFoldAsLoad() &&
6680b57cec5SDimitry Andric       foldMemoryOperand(Ops, RM.OrigMI)) {
6690b57cec5SDimitry Andric     Edit->markRematerialized(RM.ParentVNI);
6700b57cec5SDimitry Andric     ++NumFoldedLoads;
6710b57cec5SDimitry Andric     return true;
6720b57cec5SDimitry Andric   }
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   // If we can't guarantee that we'll be able to actually assign the new vreg,
6750b57cec5SDimitry Andric   // we can't remat.
676e8d8bef9SDimitry Andric   if (!canGuaranteeAssignmentAfterRemat(VirtReg.reg(), MI)) {
6770b57cec5SDimitry Andric     markValueUsed(&VirtReg, ParentVNI);
6780b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << MI);
6790b57cec5SDimitry Andric     return false;
6800b57cec5SDimitry Andric   }
6810b57cec5SDimitry Andric 
6820b57cec5SDimitry Andric   // Allocate a new register for the remat.
6835ffd83dbSDimitry Andric   Register NewVReg = Edit->createFrom(Original);
6840b57cec5SDimitry Andric 
6850b57cec5SDimitry Andric   // Finally we can rematerialize OrigMI before MI.
6860b57cec5SDimitry Andric   SlotIndex DefIdx =
6870b57cec5SDimitry Andric       Edit->rematerializeAt(*MI.getParent(), MI, NewVReg, RM, TRI);
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   // We take the DebugLoc from MI, since OrigMI may be attributed to a
6900b57cec5SDimitry Andric   // different source location.
6910b57cec5SDimitry Andric   auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
6920b57cec5SDimitry Andric   NewMI->setDebugLoc(MI.getDebugLoc());
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric   (void)DefIdx;
6950b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\tremat:  " << DefIdx << '\t'
6960b57cec5SDimitry Andric                     << *LIS.getInstructionFromIndex(DefIdx));
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   // Replace operands
6990b57cec5SDimitry Andric   for (const auto &OpPair : Ops) {
7000b57cec5SDimitry Andric     MachineOperand &MO = OpPair.first->getOperand(OpPair.second);
701e8d8bef9SDimitry Andric     if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg()) {
7020b57cec5SDimitry Andric       MO.setReg(NewVReg);
7030b57cec5SDimitry Andric       MO.setIsKill();
7040b57cec5SDimitry Andric     }
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\t        " << UseIdx << '\t' << MI << '\n');
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric   ++NumRemats;
7090b57cec5SDimitry Andric   return true;
7100b57cec5SDimitry Andric }
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric /// reMaterializeAll - Try to rematerialize as many uses as possible,
7130b57cec5SDimitry Andric /// and trim the live ranges after.
7140b57cec5SDimitry Andric void InlineSpiller::reMaterializeAll() {
715fcaf7f86SDimitry Andric   if (!Edit->anyRematerializable())
7160b57cec5SDimitry Andric     return;
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   UsedValues.clear();
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   // Try to remat before all uses of snippets.
7210b57cec5SDimitry Andric   bool anyRemat = false;
7225ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill) {
7230b57cec5SDimitry Andric     LiveInterval &LI = LIS.getInterval(Reg);
724349cc55cSDimitry Andric     for (MachineInstr &MI : llvm::make_early_inc_range(MRI.reg_bundles(Reg))) {
7250b57cec5SDimitry Andric       // Debug values are not allowed to affect codegen.
7260b57cec5SDimitry Andric       if (MI.isDebugValue())
7270b57cec5SDimitry Andric         continue;
7280b57cec5SDimitry Andric 
7290b57cec5SDimitry Andric       assert(!MI.isDebugInstr() && "Did not expect to find a use in debug "
7300b57cec5SDimitry Andric              "instruction that isn't a DBG_VALUE");
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric       anyRemat |= reMaterializeFor(LI, MI);
7330b57cec5SDimitry Andric     }
7340b57cec5SDimitry Andric   }
7350b57cec5SDimitry Andric   if (!anyRemat)
7360b57cec5SDimitry Andric     return;
7370b57cec5SDimitry Andric 
7380b57cec5SDimitry Andric   // Remove any values that were completely rematted.
7395ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill) {
7400b57cec5SDimitry Andric     LiveInterval &LI = LIS.getInterval(Reg);
74181ad6265SDimitry Andric     for (VNInfo *VNI : LI.vnis()) {
7420b57cec5SDimitry Andric       if (VNI->isUnused() || VNI->isPHIDef() || UsedValues.count(VNI))
7430b57cec5SDimitry Andric         continue;
7440b57cec5SDimitry Andric       MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
7450b57cec5SDimitry Andric       MI->addRegisterDead(Reg, &TRI);
7460b57cec5SDimitry Andric       if (!MI->allDefsAreDead())
7470b57cec5SDimitry Andric         continue;
7480b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "All defs dead: " << *MI);
7490b57cec5SDimitry Andric       DeadDefs.push_back(MI);
7505f757f3fSDimitry Andric       // If MI is a bundle header, also try removing copies inside the bundle,
7515f757f3fSDimitry Andric       // otherwise the verifier would complain "live range continues after dead
7525f757f3fSDimitry Andric       // def flag".
7535f757f3fSDimitry Andric       if (MI->isBundledWithSucc() && !MI->isBundledWithPred()) {
7545f757f3fSDimitry Andric         MachineBasicBlock::instr_iterator BeginIt = MI->getIterator(),
7555f757f3fSDimitry Andric                                           EndIt = MI->getParent()->instr_end();
7565f757f3fSDimitry Andric         ++BeginIt; // Skip MI that was already handled.
7575f757f3fSDimitry Andric 
7585f757f3fSDimitry Andric         bool OnlyDeadCopies = true;
7595f757f3fSDimitry Andric         for (MachineBasicBlock::instr_iterator It = BeginIt;
7605f757f3fSDimitry Andric              It != EndIt && It->isBundledWithPred(); ++It) {
7615f757f3fSDimitry Andric 
7625f757f3fSDimitry Andric           auto DestSrc = TII.isCopyInstr(*It);
7635f757f3fSDimitry Andric           bool IsCopyToDeadReg =
7645f757f3fSDimitry Andric               DestSrc && DestSrc->Destination->getReg() == Reg;
7655f757f3fSDimitry Andric           if (!IsCopyToDeadReg) {
7665f757f3fSDimitry Andric             OnlyDeadCopies = false;
7675f757f3fSDimitry Andric             break;
7685f757f3fSDimitry Andric           }
7695f757f3fSDimitry Andric         }
7705f757f3fSDimitry Andric         if (OnlyDeadCopies) {
7715f757f3fSDimitry Andric           for (MachineBasicBlock::instr_iterator It = BeginIt;
7725f757f3fSDimitry Andric                It != EndIt && It->isBundledWithPred(); ++It) {
7735f757f3fSDimitry Andric             It->addRegisterDead(Reg, &TRI);
7745f757f3fSDimitry Andric             LLVM_DEBUG(dbgs() << "All defs dead: " << *It);
7755f757f3fSDimitry Andric             DeadDefs.push_back(&*It);
7765f757f3fSDimitry Andric           }
7775f757f3fSDimitry Andric         }
7785f757f3fSDimitry Andric       }
7790b57cec5SDimitry Andric     }
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   // Eliminate dead code after remat. Note that some snippet copies may be
7830b57cec5SDimitry Andric   // deleted here.
7840b57cec5SDimitry Andric   if (DeadDefs.empty())
7850b57cec5SDimitry Andric     return;
7860b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Remat created " << DeadDefs.size() << " dead defs.\n");
787fcaf7f86SDimitry Andric   Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   // LiveRangeEdit::eliminateDeadDef is used to remove dead define instructions
7900b57cec5SDimitry Andric   // after rematerialization.  To remove a VNI for a vreg from its LiveInterval,
7910b57cec5SDimitry Andric   // LiveIntervals::removeVRegDefAt is used. However, after non-PHI VNIs are all
7920b57cec5SDimitry Andric   // removed, PHI VNI are still left in the LiveInterval.
7930b57cec5SDimitry Andric   // So to get rid of unused reg, we need to check whether it has non-dbg
7940b57cec5SDimitry Andric   // reference instead of whether it has non-empty interval.
7950b57cec5SDimitry Andric   unsigned ResultPos = 0;
7965ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill) {
7970b57cec5SDimitry Andric     if (MRI.reg_nodbg_empty(Reg)) {
7980b57cec5SDimitry Andric       Edit->eraseVirtReg(Reg);
7990b57cec5SDimitry Andric       continue;
8000b57cec5SDimitry Andric     }
8010b57cec5SDimitry Andric 
8020b57cec5SDimitry Andric     assert(LIS.hasInterval(Reg) &&
8030b57cec5SDimitry Andric            (!LIS.getInterval(Reg).empty() || !MRI.reg_nodbg_empty(Reg)) &&
8040b57cec5SDimitry Andric            "Empty and not used live-range?!");
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric     RegsToSpill[ResultPos++] = Reg;
8070b57cec5SDimitry Andric   }
8080b57cec5SDimitry Andric   RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
8090b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << RegsToSpill.size()
8100b57cec5SDimitry Andric                     << " registers to spill after remat.\n");
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8140b57cec5SDimitry Andric //                                 Spilling
8150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric /// If MI is a load or store of StackSlot, it can be removed.
8185ffd83dbSDimitry Andric bool InlineSpiller::coalesceStackAccess(MachineInstr *MI, Register Reg) {
8190b57cec5SDimitry Andric   int FI = 0;
8205ffd83dbSDimitry Andric   Register InstrReg = TII.isLoadFromStackSlot(*MI, FI);
8210b57cec5SDimitry Andric   bool IsLoad = InstrReg;
8220b57cec5SDimitry Andric   if (!IsLoad)
8230b57cec5SDimitry Andric     InstrReg = TII.isStoreToStackSlot(*MI, FI);
8240b57cec5SDimitry Andric 
8250b57cec5SDimitry Andric   // We have a stack access. Is it the right register and slot?
8260b57cec5SDimitry Andric   if (InstrReg != Reg || FI != StackSlot)
8270b57cec5SDimitry Andric     return false;
8280b57cec5SDimitry Andric 
8290b57cec5SDimitry Andric   if (!IsLoad)
8300b57cec5SDimitry Andric     HSpiller.rmFromMergeableSpills(*MI, StackSlot);
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Coalescing stack access: " << *MI);
8330b57cec5SDimitry Andric   LIS.RemoveMachineInstrFromMaps(*MI);
8340b57cec5SDimitry Andric   MI->eraseFromParent();
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric   if (IsLoad) {
8370b57cec5SDimitry Andric     ++NumReloadsRemoved;
8380b57cec5SDimitry Andric     --NumReloads;
8390b57cec5SDimitry Andric   } else {
8400b57cec5SDimitry Andric     ++NumSpillsRemoved;
8410b57cec5SDimitry Andric     --NumSpills;
8420b57cec5SDimitry Andric   }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric   return true;
8450b57cec5SDimitry Andric }
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
8480b57cec5SDimitry Andric LLVM_DUMP_METHOD
8490b57cec5SDimitry Andric // Dump the range of instructions from B to E with their slot indexes.
8500b57cec5SDimitry Andric static void dumpMachineInstrRangeWithSlotIndex(MachineBasicBlock::iterator B,
8510b57cec5SDimitry Andric                                                MachineBasicBlock::iterator E,
8520b57cec5SDimitry Andric                                                LiveIntervals const &LIS,
8530b57cec5SDimitry Andric                                                const char *const header,
8545ffd83dbSDimitry Andric                                                Register VReg = Register()) {
8550b57cec5SDimitry Andric   char NextLine = '\n';
8560b57cec5SDimitry Andric   char SlotIndent = '\t';
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   if (std::next(B) == E) {
8590b57cec5SDimitry Andric     NextLine = ' ';
8600b57cec5SDimitry Andric     SlotIndent = ' ';
8610b57cec5SDimitry Andric   }
8620b57cec5SDimitry Andric 
8630b57cec5SDimitry Andric   dbgs() << '\t' << header << ": " << NextLine;
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric   for (MachineBasicBlock::iterator I = B; I != E; ++I) {
8660b57cec5SDimitry Andric     SlotIndex Idx = LIS.getInstructionIndex(*I).getRegSlot();
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric     // If a register was passed in and this instruction has it as a
8690b57cec5SDimitry Andric     // destination that is marked as an early clobber, print the
8700b57cec5SDimitry Andric     // early-clobber slot index.
8710b57cec5SDimitry Andric     if (VReg) {
872*0fca6ea1SDimitry Andric       MachineOperand *MO = I->findRegisterDefOperand(VReg, /*TRI=*/nullptr);
8730b57cec5SDimitry Andric       if (MO && MO->isEarlyClobber())
8740b57cec5SDimitry Andric         Idx = Idx.getRegSlot(true);
8750b57cec5SDimitry Andric     }
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     dbgs() << SlotIndent << Idx << '\t' << *I;
8780b57cec5SDimitry Andric   }
8790b57cec5SDimitry Andric }
8800b57cec5SDimitry Andric #endif
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric /// foldMemoryOperand - Try folding stack slot references in Ops into their
8830b57cec5SDimitry Andric /// instructions.
8840b57cec5SDimitry Andric ///
885480093f4SDimitry Andric /// @param Ops    Operand indices from AnalyzeVirtRegInBundle().
8860b57cec5SDimitry Andric /// @param LoadMI Load instruction to use instead of stack slot when non-null.
8870b57cec5SDimitry Andric /// @return       True on success.
8880b57cec5SDimitry Andric bool InlineSpiller::
8890b57cec5SDimitry Andric foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
8900b57cec5SDimitry Andric                   MachineInstr *LoadMI) {
8910b57cec5SDimitry Andric   if (Ops.empty())
8920b57cec5SDimitry Andric     return false;
8930b57cec5SDimitry Andric   // Don't attempt folding in bundles.
8940b57cec5SDimitry Andric   MachineInstr *MI = Ops.front().first;
8950b57cec5SDimitry Andric   if (Ops.back().first != MI || MI->isBundled())
8960b57cec5SDimitry Andric     return false;
8970b57cec5SDimitry Andric 
8985f757f3fSDimitry Andric   bool WasCopy = TII.isCopyInstr(*MI).has_value();
8995ffd83dbSDimitry Andric   Register ImpReg;
9000b57cec5SDimitry Andric 
901e8d8bef9SDimitry Andric   // TII::foldMemoryOperand will do what we need here for statepoint
902e8d8bef9SDimitry Andric   // (fold load into use and remove corresponding def). We will replace
903e8d8bef9SDimitry Andric   // uses of removed def with loads (spillAroundUses).
904e8d8bef9SDimitry Andric   // For that to work we need to untie def and use to pass it through
905e8d8bef9SDimitry Andric   // foldMemoryOperand and signal foldPatchpoint that it is allowed to
906e8d8bef9SDimitry Andric   // fold them.
907e8d8bef9SDimitry Andric   bool UntieRegs = MI->getOpcode() == TargetOpcode::STATEPOINT;
908e8d8bef9SDimitry Andric 
9090b57cec5SDimitry Andric   // Spill subregs if the target allows it.
9100b57cec5SDimitry Andric   // We always want to spill subregs for stackmap/patchpoint pseudos.
9110b57cec5SDimitry Andric   bool SpillSubRegs = TII.isSubregFoldable() ||
9120b57cec5SDimitry Andric                       MI->getOpcode() == TargetOpcode::STATEPOINT ||
9130b57cec5SDimitry Andric                       MI->getOpcode() == TargetOpcode::PATCHPOINT ||
9140b57cec5SDimitry Andric                       MI->getOpcode() == TargetOpcode::STACKMAP;
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   // TargetInstrInfo::foldMemoryOperand only expects explicit, non-tied
9170b57cec5SDimitry Andric   // operands.
9180b57cec5SDimitry Andric   SmallVector<unsigned, 8> FoldOps;
9190b57cec5SDimitry Andric   for (const auto &OpPair : Ops) {
9200b57cec5SDimitry Andric     unsigned Idx = OpPair.second;
9210b57cec5SDimitry Andric     assert(MI == OpPair.first && "Instruction conflict during operand folding");
9220b57cec5SDimitry Andric     MachineOperand &MO = MI->getOperand(Idx);
92381ad6265SDimitry Andric 
92481ad6265SDimitry Andric     // No point restoring an undef read, and we'll produce an invalid live
92581ad6265SDimitry Andric     // interval.
92681ad6265SDimitry Andric     // TODO: Is this really the correct way to handle undef tied uses?
92781ad6265SDimitry Andric     if (MO.isUse() && !MO.readsReg() && !MO.isTied())
92881ad6265SDimitry Andric       continue;
92981ad6265SDimitry Andric 
9300b57cec5SDimitry Andric     if (MO.isImplicit()) {
9310b57cec5SDimitry Andric       ImpReg = MO.getReg();
9320b57cec5SDimitry Andric       continue;
9330b57cec5SDimitry Andric     }
9340b57cec5SDimitry Andric 
9350b57cec5SDimitry Andric     if (!SpillSubRegs && MO.getSubReg())
9360b57cec5SDimitry Andric       return false;
9370b57cec5SDimitry Andric     // We cannot fold a load instruction into a def.
9380b57cec5SDimitry Andric     if (LoadMI && MO.isDef())
9390b57cec5SDimitry Andric       return false;
9400b57cec5SDimitry Andric     // Tied use operands should not be passed to foldMemoryOperand.
941e8d8bef9SDimitry Andric     if (UntieRegs || !MI->isRegTiedToDefOperand(Idx))
9420b57cec5SDimitry Andric       FoldOps.push_back(Idx);
9430b57cec5SDimitry Andric   }
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric   // If we only have implicit uses, we won't be able to fold that.
9460b57cec5SDimitry Andric   // Moreover, TargetInstrInfo::foldMemoryOperand will assert if we try!
9470b57cec5SDimitry Andric   if (FoldOps.empty())
9480b57cec5SDimitry Andric     return false;
9490b57cec5SDimitry Andric 
9500b57cec5SDimitry Andric   MachineInstrSpan MIS(MI, MI->getParent());
9510b57cec5SDimitry Andric 
952e8d8bef9SDimitry Andric   SmallVector<std::pair<unsigned, unsigned> > TiedOps;
953e8d8bef9SDimitry Andric   if (UntieRegs)
954e8d8bef9SDimitry Andric     for (unsigned Idx : FoldOps) {
955e8d8bef9SDimitry Andric       MachineOperand &MO = MI->getOperand(Idx);
956e8d8bef9SDimitry Andric       if (!MO.isTied())
957e8d8bef9SDimitry Andric         continue;
958e8d8bef9SDimitry Andric       unsigned Tied = MI->findTiedOperandIdx(Idx);
959e8d8bef9SDimitry Andric       if (MO.isUse())
960e8d8bef9SDimitry Andric         TiedOps.emplace_back(Tied, Idx);
961e8d8bef9SDimitry Andric       else {
962e8d8bef9SDimitry Andric         assert(MO.isDef() && "Tied to not use and def?");
963e8d8bef9SDimitry Andric         TiedOps.emplace_back(Idx, Tied);
964e8d8bef9SDimitry Andric       }
965e8d8bef9SDimitry Andric       MI->untieRegOperand(Idx);
966e8d8bef9SDimitry Andric     }
967e8d8bef9SDimitry Andric 
9680b57cec5SDimitry Andric   MachineInstr *FoldMI =
9690b57cec5SDimitry Andric       LoadMI ? TII.foldMemoryOperand(*MI, FoldOps, *LoadMI, &LIS)
9700b57cec5SDimitry Andric              : TII.foldMemoryOperand(*MI, FoldOps, StackSlot, &LIS, &VRM);
971e8d8bef9SDimitry Andric   if (!FoldMI) {
972e8d8bef9SDimitry Andric     // Re-tie operands.
973e8d8bef9SDimitry Andric     for (auto Tied : TiedOps)
974e8d8bef9SDimitry Andric       MI->tieOperands(Tied.first, Tied.second);
9750b57cec5SDimitry Andric     return false;
976e8d8bef9SDimitry Andric   }
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric   // Remove LIS for any dead defs in the original MI not in FoldMI.
9790b57cec5SDimitry Andric   for (MIBundleOperands MO(*MI); MO.isValid(); ++MO) {
9800b57cec5SDimitry Andric     if (!MO->isReg())
9810b57cec5SDimitry Andric       continue;
9828bcb0991SDimitry Andric     Register Reg = MO->getReg();
983bdd1243dSDimitry Andric     if (!Reg || Reg.isVirtual() || MRI.isReserved(Reg)) {
9840b57cec5SDimitry Andric       continue;
9850b57cec5SDimitry Andric     }
9860b57cec5SDimitry Andric     // Skip non-Defs, including undef uses and internal reads.
9870b57cec5SDimitry Andric     if (MO->isUse())
9880b57cec5SDimitry Andric       continue;
989480093f4SDimitry Andric     PhysRegInfo RI = AnalyzePhysRegInBundle(*FoldMI, Reg, &TRI);
9900b57cec5SDimitry Andric     if (RI.FullyDefined)
9910b57cec5SDimitry Andric       continue;
9920b57cec5SDimitry Andric     // FoldMI does not define this physreg. Remove the LI segment.
9930b57cec5SDimitry Andric     assert(MO->isDead() && "Cannot fold physreg def");
9940b57cec5SDimitry Andric     SlotIndex Idx = LIS.getInstructionIndex(*MI).getRegSlot();
995e8d8bef9SDimitry Andric     LIS.removePhysRegDefAt(Reg.asMCReg(), Idx);
9960b57cec5SDimitry Andric   }
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   int FI;
9990b57cec5SDimitry Andric   if (TII.isStoreToStackSlot(*MI, FI) &&
10000b57cec5SDimitry Andric       HSpiller.rmFromMergeableSpills(*MI, FI))
10010b57cec5SDimitry Andric     --NumSpills;
10020b57cec5SDimitry Andric   LIS.ReplaceMachineInstrInMaps(*MI, *FoldMI);
10035ffd83dbSDimitry Andric   // Update the call site info.
10045ffd83dbSDimitry Andric   if (MI->isCandidateForCallSiteEntry())
10058bcb0991SDimitry Andric     MI->getMF()->moveCallSiteInfo(MI, FoldMI);
1006349cc55cSDimitry Andric 
1007349cc55cSDimitry Andric   // If we've folded a store into an instruction labelled with debug-info,
1008349cc55cSDimitry Andric   // record a substitution from the old operand to the memory operand. Handle
1009349cc55cSDimitry Andric   // the simple common case where operand 0 is the one being folded, plus when
1010349cc55cSDimitry Andric   // the destination operand is also a tied def. More values could be
1011349cc55cSDimitry Andric   // substituted / preserved with more analysis.
1012349cc55cSDimitry Andric   if (MI->peekDebugInstrNum() && Ops[0].second == 0) {
1013349cc55cSDimitry Andric     // Helper lambda.
1014349cc55cSDimitry Andric     auto MakeSubstitution = [this,FoldMI,MI,&Ops]() {
1015349cc55cSDimitry Andric       // Substitute old operand zero to the new instructions memory operand.
1016349cc55cSDimitry Andric       unsigned OldOperandNum = Ops[0].second;
1017349cc55cSDimitry Andric       unsigned NewNum = FoldMI->getDebugInstrNum();
1018349cc55cSDimitry Andric       unsigned OldNum = MI->getDebugInstrNum();
1019349cc55cSDimitry Andric       MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
1020349cc55cSDimitry Andric                          {NewNum, MachineFunction::DebugOperandMemNumber});
1021349cc55cSDimitry Andric     };
1022349cc55cSDimitry Andric 
1023349cc55cSDimitry Andric     const MachineOperand &Op0 = MI->getOperand(Ops[0].second);
1024349cc55cSDimitry Andric     if (Ops.size() == 1 && Op0.isDef()) {
1025349cc55cSDimitry Andric       MakeSubstitution();
1026349cc55cSDimitry Andric     } else if (Ops.size() == 2 && Op0.isDef() && MI->getOperand(1).isTied() &&
1027349cc55cSDimitry Andric                Op0.getReg() == MI->getOperand(1).getReg()) {
1028349cc55cSDimitry Andric       MakeSubstitution();
1029349cc55cSDimitry Andric     }
1030349cc55cSDimitry Andric   } else if (MI->peekDebugInstrNum()) {
1031349cc55cSDimitry Andric     // This is a debug-labelled instruction, but the operand being folded isn't
1032349cc55cSDimitry Andric     // at operand zero. Most likely this means it's a load being folded in.
1033349cc55cSDimitry Andric     // Substitute any register defs from operand zero up to the one being
1034349cc55cSDimitry Andric     // folded -- past that point, we don't know what the new operand indexes
1035349cc55cSDimitry Andric     // will be.
1036349cc55cSDimitry Andric     MF.substituteDebugValuesForInst(*MI, *FoldMI, Ops[0].second);
1037349cc55cSDimitry Andric   }
1038349cc55cSDimitry Andric 
10390b57cec5SDimitry Andric   MI->eraseFromParent();
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   // Insert any new instructions other than FoldMI into the LIS maps.
10420b57cec5SDimitry Andric   assert(!MIS.empty() && "Unexpected empty span of instructions!");
10430b57cec5SDimitry Andric   for (MachineInstr &MI : MIS)
10440b57cec5SDimitry Andric     if (&MI != FoldMI)
10450b57cec5SDimitry Andric       LIS.InsertMachineInstrInMaps(MI);
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   // TII.foldMemoryOperand may have left some implicit operands on the
10480b57cec5SDimitry Andric   // instruction.  Strip them.
10490b57cec5SDimitry Andric   if (ImpReg)
10500b57cec5SDimitry Andric     for (unsigned i = FoldMI->getNumOperands(); i; --i) {
10510b57cec5SDimitry Andric       MachineOperand &MO = FoldMI->getOperand(i - 1);
10520b57cec5SDimitry Andric       if (!MO.isReg() || !MO.isImplicit())
10530b57cec5SDimitry Andric         break;
10540b57cec5SDimitry Andric       if (MO.getReg() == ImpReg)
105581ad6265SDimitry Andric         FoldMI->removeOperand(i - 1);
10560b57cec5SDimitry Andric     }
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric   LLVM_DEBUG(dumpMachineInstrRangeWithSlotIndex(MIS.begin(), MIS.end(), LIS,
10590b57cec5SDimitry Andric                                                 "folded"));
10600b57cec5SDimitry Andric 
10610b57cec5SDimitry Andric   if (!WasCopy)
10620b57cec5SDimitry Andric     ++NumFolded;
10630b57cec5SDimitry Andric   else if (Ops.front().second == 0) {
10640b57cec5SDimitry Andric     ++NumSpills;
1065e8d8bef9SDimitry Andric     // If there is only 1 store instruction is required for spill, add it
1066e8d8bef9SDimitry Andric     // to mergeable list. In X86 AMX, 2 intructions are required to store.
1067e8d8bef9SDimitry Andric     // We disable the merge for this case.
1068e8d8bef9SDimitry Andric     if (std::distance(MIS.begin(), MIS.end()) <= 1)
10690b57cec5SDimitry Andric       HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
10700b57cec5SDimitry Andric   } else
10710b57cec5SDimitry Andric     ++NumReloads;
10720b57cec5SDimitry Andric   return true;
10730b57cec5SDimitry Andric }
10740b57cec5SDimitry Andric 
10755ffd83dbSDimitry Andric void InlineSpiller::insertReload(Register NewVReg,
10760b57cec5SDimitry Andric                                  SlotIndex Idx,
10770b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MI) {
10780b57cec5SDimitry Andric   MachineBasicBlock &MBB = *MI->getParent();
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric   MachineInstrSpan MIS(MI, &MBB);
10810b57cec5SDimitry Andric   TII.loadRegFromStackSlot(MBB, MI, NewVReg, StackSlot,
1082bdd1243dSDimitry Andric                            MRI.getRegClass(NewVReg), &TRI, Register());
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric   LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MI);
10850b57cec5SDimitry Andric 
10860b57cec5SDimitry Andric   LLVM_DEBUG(dumpMachineInstrRangeWithSlotIndex(MIS.begin(), MI, LIS, "reload",
10870b57cec5SDimitry Andric                                                 NewVReg));
10880b57cec5SDimitry Andric   ++NumReloads;
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric /// Check if \p Def fully defines a VReg with an undefined value.
10920b57cec5SDimitry Andric /// If that's the case, that means the value of VReg is actually
10930b57cec5SDimitry Andric /// not relevant.
10945ffd83dbSDimitry Andric static bool isRealSpill(const MachineInstr &Def) {
10950b57cec5SDimitry Andric   if (!Def.isImplicitDef())
10965ffd83dbSDimitry Andric     return true;
10975f757f3fSDimitry Andric 
10980b57cec5SDimitry Andric   // We can say that the VReg defined by Def is undef, only if it is
10990b57cec5SDimitry Andric   // fully defined by Def. Otherwise, some of the lanes may not be
11000b57cec5SDimitry Andric   // undef and the value of the VReg matters.
11015ffd83dbSDimitry Andric   return Def.getOperand(0).getSubReg();
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric /// insertSpill - Insert a spill of NewVReg after MI.
11055ffd83dbSDimitry Andric void InlineSpiller::insertSpill(Register NewVReg, bool isKill,
11060b57cec5SDimitry Andric                                  MachineBasicBlock::iterator MI) {
11075ffd83dbSDimitry Andric   // Spill are not terminators, so inserting spills after terminators will
11085ffd83dbSDimitry Andric   // violate invariants in MachineVerifier.
11095ffd83dbSDimitry Andric   assert(!MI->isTerminator() && "Inserting a spill after a terminator");
11100b57cec5SDimitry Andric   MachineBasicBlock &MBB = *MI->getParent();
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric   MachineInstrSpan MIS(MI, &MBB);
11135ffd83dbSDimitry Andric   MachineBasicBlock::iterator SpillBefore = std::next(MI);
11145ffd83dbSDimitry Andric   bool IsRealSpill = isRealSpill(*MI);
1115e8d8bef9SDimitry Andric 
11165ffd83dbSDimitry Andric   if (IsRealSpill)
11175ffd83dbSDimitry Andric     TII.storeRegToStackSlot(MBB, SpillBefore, NewVReg, isKill, StackSlot,
1118bdd1243dSDimitry Andric                             MRI.getRegClass(NewVReg), &TRI, Register());
11195ffd83dbSDimitry Andric   else
11200b57cec5SDimitry Andric     // Don't spill undef value.
11210b57cec5SDimitry Andric     // Anything works for undef, in particular keeping the memory
11220b57cec5SDimitry Andric     // uninitialized is a viable option and it saves code size and
11230b57cec5SDimitry Andric     // run time.
11245ffd83dbSDimitry Andric     BuildMI(MBB, SpillBefore, MI->getDebugLoc(), TII.get(TargetOpcode::KILL))
11250b57cec5SDimitry Andric         .addReg(NewVReg, getKillRegState(isKill));
11260b57cec5SDimitry Andric 
11275ffd83dbSDimitry Andric   MachineBasicBlock::iterator Spill = std::next(MI);
11285ffd83dbSDimitry Andric   LIS.InsertMachineInstrRangeInMaps(Spill, MIS.end());
1129e8d8bef9SDimitry Andric   for (const MachineInstr &MI : make_range(Spill, MIS.end()))
1130e8d8bef9SDimitry Andric     getVDefInterval(MI, LIS);
11310b57cec5SDimitry Andric 
11325ffd83dbSDimitry Andric   LLVM_DEBUG(
11335ffd83dbSDimitry Andric       dumpMachineInstrRangeWithSlotIndex(Spill, MIS.end(), LIS, "spill"));
11340b57cec5SDimitry Andric   ++NumSpills;
1135e8d8bef9SDimitry Andric   // If there is only 1 store instruction is required for spill, add it
1136e8d8bef9SDimitry Andric   // to mergeable list. In X86 AMX, 2 intructions are required to store.
1137e8d8bef9SDimitry Andric   // We disable the merge for this case.
1138e8d8bef9SDimitry Andric   if (IsRealSpill && std::distance(Spill, MIS.end()) <= 1)
11395ffd83dbSDimitry Andric     HSpiller.addToMergeableSpills(*Spill, StackSlot, Original);
11400b57cec5SDimitry Andric }
11410b57cec5SDimitry Andric 
11420b57cec5SDimitry Andric /// spillAroundUses - insert spill code around each use of Reg.
11435ffd83dbSDimitry Andric void InlineSpiller::spillAroundUses(Register Reg) {
11440b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "spillAroundUses " << printReg(Reg) << '\n');
11450b57cec5SDimitry Andric   LiveInterval &OldLI = LIS.getInterval(Reg);
11460b57cec5SDimitry Andric 
11470b57cec5SDimitry Andric   // Iterate over instructions using Reg.
1148349cc55cSDimitry Andric   for (MachineInstr &MI : llvm::make_early_inc_range(MRI.reg_bundles(Reg))) {
11490b57cec5SDimitry Andric     // Debug values are not allowed to affect codegen.
1150349cc55cSDimitry Andric     if (MI.isDebugValue()) {
11510b57cec5SDimitry Andric       // Modify DBG_VALUE now that the value is in a spill slot.
1152349cc55cSDimitry Andric       MachineBasicBlock *MBB = MI.getParent();
1153349cc55cSDimitry Andric       LLVM_DEBUG(dbgs() << "Modifying debug info due to spill:\t" << MI);
1154349cc55cSDimitry Andric       buildDbgValueForSpill(*MBB, &MI, MI, StackSlot, Reg);
11550b57cec5SDimitry Andric       MBB->erase(MI);
11560b57cec5SDimitry Andric       continue;
11570b57cec5SDimitry Andric     }
11580b57cec5SDimitry Andric 
1159349cc55cSDimitry Andric     assert(!MI.isDebugInstr() && "Did not expect to find a use in debug "
11600b57cec5SDimitry Andric            "instruction that isn't a DBG_VALUE");
11610b57cec5SDimitry Andric 
11620b57cec5SDimitry Andric     // Ignore copies to/from snippets. We'll delete them.
1163349cc55cSDimitry Andric     if (SnippetCopies.count(&MI))
11640b57cec5SDimitry Andric       continue;
11650b57cec5SDimitry Andric 
11660b57cec5SDimitry Andric     // Stack slot accesses may coalesce away.
1167349cc55cSDimitry Andric     if (coalesceStackAccess(&MI, Reg))
11680b57cec5SDimitry Andric       continue;
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric     // Analyze instruction.
11710b57cec5SDimitry Andric     SmallVector<std::pair<MachineInstr*, unsigned>, 8> Ops;
1172349cc55cSDimitry Andric     VirtRegInfo RI = AnalyzeVirtRegInBundle(MI, Reg, &Ops);
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric     // Find the slot index where this instruction reads and writes OldLI.
11750b57cec5SDimitry Andric     // This is usually the def slot, except for tied early clobbers.
1176349cc55cSDimitry Andric     SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot();
11770b57cec5SDimitry Andric     if (VNInfo *VNI = OldLI.getVNInfoAt(Idx.getRegSlot(true)))
11780b57cec5SDimitry Andric       if (SlotIndex::isSameInstr(Idx, VNI->def))
11790b57cec5SDimitry Andric         Idx = VNI->def;
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric     // Check for a sibling copy.
11825f757f3fSDimitry Andric     Register SibReg = isCopyOfBundle(MI, Reg, TII);
11830b57cec5SDimitry Andric     if (SibReg && isSibling(SibReg)) {
11840b57cec5SDimitry Andric       // This may actually be a copy between snippets.
11850b57cec5SDimitry Andric       if (isRegToSpill(SibReg)) {
1186349cc55cSDimitry Andric         LLVM_DEBUG(dbgs() << "Found new snippet copy: " << MI);
1187349cc55cSDimitry Andric         SnippetCopies.insert(&MI);
11880b57cec5SDimitry Andric         continue;
11890b57cec5SDimitry Andric       }
11900b57cec5SDimitry Andric       if (RI.Writes) {
1191349cc55cSDimitry Andric         if (hoistSpillInsideBB(OldLI, MI)) {
11920b57cec5SDimitry Andric           // This COPY is now dead, the value is already in the stack slot.
1193349cc55cSDimitry Andric           MI.getOperand(0).setIsDead();
1194349cc55cSDimitry Andric           DeadDefs.push_back(&MI);
11950b57cec5SDimitry Andric           continue;
11960b57cec5SDimitry Andric         }
11970b57cec5SDimitry Andric       } else {
11980b57cec5SDimitry Andric         // This is a reload for a sib-reg copy. Drop spills downstream.
11990b57cec5SDimitry Andric         LiveInterval &SibLI = LIS.getInterval(SibReg);
12000b57cec5SDimitry Andric         eliminateRedundantSpills(SibLI, SibLI.getVNInfoAt(Idx));
12010b57cec5SDimitry Andric         // The COPY will fold to a reload below.
12020b57cec5SDimitry Andric       }
12030b57cec5SDimitry Andric     }
12040b57cec5SDimitry Andric 
12050b57cec5SDimitry Andric     // Attempt to fold memory ops.
12060b57cec5SDimitry Andric     if (foldMemoryOperand(Ops))
12070b57cec5SDimitry Andric       continue;
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric     // Create a new virtual register for spill/fill.
12100b57cec5SDimitry Andric     // FIXME: Infer regclass from instruction alone.
12115ffd83dbSDimitry Andric     Register NewVReg = Edit->createFrom(Reg);
12120b57cec5SDimitry Andric 
12130b57cec5SDimitry Andric     if (RI.Reads)
1214349cc55cSDimitry Andric       insertReload(NewVReg, Idx, &MI);
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric     // Rewrite instruction operands.
12170b57cec5SDimitry Andric     bool hasLiveDef = false;
12180b57cec5SDimitry Andric     for (const auto &OpPair : Ops) {
12190b57cec5SDimitry Andric       MachineOperand &MO = OpPair.first->getOperand(OpPair.second);
12200b57cec5SDimitry Andric       MO.setReg(NewVReg);
12210b57cec5SDimitry Andric       if (MO.isUse()) {
12220b57cec5SDimitry Andric         if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
12230b57cec5SDimitry Andric           MO.setIsKill();
12240b57cec5SDimitry Andric       } else {
12250b57cec5SDimitry Andric         if (!MO.isDead())
12260b57cec5SDimitry Andric           hasLiveDef = true;
12270b57cec5SDimitry Andric       }
12280b57cec5SDimitry Andric     }
1229349cc55cSDimitry Andric     LLVM_DEBUG(dbgs() << "\trewrite: " << Idx << '\t' << MI << '\n');
12300b57cec5SDimitry Andric 
12310b57cec5SDimitry Andric     // FIXME: Use a second vreg if instruction has no tied ops.
12320b57cec5SDimitry Andric     if (RI.Writes)
12330b57cec5SDimitry Andric       if (hasLiveDef)
1234349cc55cSDimitry Andric         insertSpill(NewVReg, true, &MI);
12350b57cec5SDimitry Andric   }
12360b57cec5SDimitry Andric }
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric /// spillAll - Spill all registers remaining after rematerialization.
12390b57cec5SDimitry Andric void InlineSpiller::spillAll() {
12400b57cec5SDimitry Andric   // Update LiveStacks now that we are committed to spilling.
12410b57cec5SDimitry Andric   if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
12420b57cec5SDimitry Andric     StackSlot = VRM.assignVirt2StackSlot(Original);
12430b57cec5SDimitry Andric     StackInt = &LSS.getOrCreateInterval(StackSlot, MRI.getRegClass(Original));
12440b57cec5SDimitry Andric     StackInt->getNextValue(SlotIndex(), LSS.getVNInfoAllocator());
12450b57cec5SDimitry Andric   } else
12460b57cec5SDimitry Andric     StackInt = &LSS.getInterval(StackSlot);
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   if (Original != Edit->getReg())
12490b57cec5SDimitry Andric     VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   assert(StackInt->getNumValNums() == 1 && "Bad stack interval values");
12525ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill)
12530b57cec5SDimitry Andric     StackInt->MergeSegmentsInAsValue(LIS.getInterval(Reg),
12540b57cec5SDimitry Andric                                      StackInt->getValNumInfo(0));
12550b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Merged spilled regs: " << *StackInt << '\n');
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric   // Spill around uses of all RegsToSpill.
12585ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill)
12590b57cec5SDimitry Andric     spillAroundUses(Reg);
12600b57cec5SDimitry Andric 
12610b57cec5SDimitry Andric   // Hoisted spills may cause dead code.
12620b57cec5SDimitry Andric   if (!DeadDefs.empty()) {
12630b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Eliminating " << DeadDefs.size() << " dead defs\n");
1264fcaf7f86SDimitry Andric     Edit->eliminateDeadDefs(DeadDefs, RegsToSpill);
12650b57cec5SDimitry Andric   }
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   // Finally delete the SnippetCopies.
12685ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill) {
1269349cc55cSDimitry Andric     for (MachineInstr &MI :
1270349cc55cSDimitry Andric          llvm::make_early_inc_range(MRI.reg_instructions(Reg))) {
12710b57cec5SDimitry Andric       assert(SnippetCopies.count(&MI) && "Remaining use wasn't a snippet copy");
12720b57cec5SDimitry Andric       // FIXME: Do this with a LiveRangeEdit callback.
127306c3fb27SDimitry Andric       LIS.getSlotIndexes()->removeSingleMachineInstrFromMaps(MI);
127406c3fb27SDimitry Andric       MI.eraseFromBundle();
12750b57cec5SDimitry Andric     }
12760b57cec5SDimitry Andric   }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric   // Delete all spilled registers.
12795ffd83dbSDimitry Andric   for (Register Reg : RegsToSpill)
12800b57cec5SDimitry Andric     Edit->eraseVirtReg(Reg);
12810b57cec5SDimitry Andric }
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric void InlineSpiller::spill(LiveRangeEdit &edit) {
12840b57cec5SDimitry Andric   ++NumSpilledRanges;
12850b57cec5SDimitry Andric   Edit = &edit;
12868bcb0991SDimitry Andric   assert(!Register::isStackSlot(edit.getReg()) &&
12878bcb0991SDimitry Andric          "Trying to spill a stack slot.");
12880b57cec5SDimitry Andric   // Share a stack slot among all descendants of Original.
12890b57cec5SDimitry Andric   Original = VRM.getOriginal(edit.getReg());
12900b57cec5SDimitry Andric   StackSlot = VRM.getStackSlot(Original);
12910b57cec5SDimitry Andric   StackInt = nullptr;
12920b57cec5SDimitry Andric 
12930b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Inline spilling "
12940b57cec5SDimitry Andric                     << TRI.getRegClassName(MRI.getRegClass(edit.getReg()))
12950b57cec5SDimitry Andric                     << ':' << edit.getParent() << "\nFrom original "
12960b57cec5SDimitry Andric                     << printReg(Original) << '\n');
12970b57cec5SDimitry Andric   assert(edit.getParent().isSpillable() &&
12980b57cec5SDimitry Andric          "Attempting to spill already spilled value.");
12990b57cec5SDimitry Andric   assert(DeadDefs.empty() && "Previous spill didn't remove dead defs");
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   collectRegsToSpill();
13020b57cec5SDimitry Andric   reMaterializeAll();
13030b57cec5SDimitry Andric 
13040b57cec5SDimitry Andric   // Remat may handle everything.
13050b57cec5SDimitry Andric   if (!RegsToSpill.empty())
13060b57cec5SDimitry Andric     spillAll();
13070b57cec5SDimitry Andric 
1308fe6060f1SDimitry Andric   Edit->calculateRegClassAndHint(MF, VRAI);
13090b57cec5SDimitry Andric }
13100b57cec5SDimitry Andric 
13110b57cec5SDimitry Andric /// Optimizations after all the reg selections and spills are done.
13120b57cec5SDimitry Andric void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric /// When a spill is inserted, add the spill to MergeableSpills map.
13150b57cec5SDimitry Andric void HoistSpillHelper::addToMergeableSpills(MachineInstr &Spill, int StackSlot,
13160b57cec5SDimitry Andric                                             unsigned Original) {
13170b57cec5SDimitry Andric   BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator();
13180b57cec5SDimitry Andric   LiveInterval &OrigLI = LIS.getInterval(Original);
13190b57cec5SDimitry Andric   // save a copy of LiveInterval in StackSlotToOrigLI because the original
13200b57cec5SDimitry Andric   // LiveInterval may be cleared after all its references are spilled.
132106c3fb27SDimitry Andric   if (!StackSlotToOrigLI.contains(StackSlot)) {
1322e8d8bef9SDimitry Andric     auto LI = std::make_unique<LiveInterval>(OrigLI.reg(), OrigLI.weight());
13230b57cec5SDimitry Andric     LI->assign(OrigLI, Allocator);
13240b57cec5SDimitry Andric     StackSlotToOrigLI[StackSlot] = std::move(LI);
13250b57cec5SDimitry Andric   }
13260b57cec5SDimitry Andric   SlotIndex Idx = LIS.getInstructionIndex(Spill);
13270b57cec5SDimitry Andric   VNInfo *OrigVNI = StackSlotToOrigLI[StackSlot]->getVNInfoAt(Idx.getRegSlot());
13280b57cec5SDimitry Andric   std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
13290b57cec5SDimitry Andric   MergeableSpills[MIdx].insert(&Spill);
13300b57cec5SDimitry Andric }
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric /// When a spill is removed, remove the spill from MergeableSpills map.
13330b57cec5SDimitry Andric /// Return true if the spill is removed successfully.
13340b57cec5SDimitry Andric bool HoistSpillHelper::rmFromMergeableSpills(MachineInstr &Spill,
13350b57cec5SDimitry Andric                                              int StackSlot) {
13360b57cec5SDimitry Andric   auto It = StackSlotToOrigLI.find(StackSlot);
13370b57cec5SDimitry Andric   if (It == StackSlotToOrigLI.end())
13380b57cec5SDimitry Andric     return false;
13390b57cec5SDimitry Andric   SlotIndex Idx = LIS.getInstructionIndex(Spill);
13400b57cec5SDimitry Andric   VNInfo *OrigVNI = It->second->getVNInfoAt(Idx.getRegSlot());
13410b57cec5SDimitry Andric   std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
13420b57cec5SDimitry Andric   return MergeableSpills[MIdx].erase(&Spill);
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric 
13450b57cec5SDimitry Andric /// Check BB to see if it is a possible target BB to place a hoisted spill,
13460b57cec5SDimitry Andric /// i.e., there should be a living sibling of OrigReg at the insert point.
13470b57cec5SDimitry Andric bool HoistSpillHelper::isSpillCandBB(LiveInterval &OrigLI, VNInfo &OrigVNI,
13485ffd83dbSDimitry Andric                                      MachineBasicBlock &BB, Register &LiveReg) {
1349fe6060f1SDimitry Andric   SlotIndex Idx = IPA.getLastInsertPoint(OrigLI, BB);
1350fe6060f1SDimitry Andric   // The original def could be after the last insert point in the root block,
1351fe6060f1SDimitry Andric   // we can't hoist to here.
1352fe6060f1SDimitry Andric   if (Idx < OrigVNI.def) {
1353fe6060f1SDimitry Andric     // TODO: We could be better here. If LI is not alive in landing pad
1354fe6060f1SDimitry Andric     // we could hoist spill after LIP.
1355fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "can't spill in root block - def after LIP\n");
1356fe6060f1SDimitry Andric     return false;
1357fe6060f1SDimitry Andric   }
1358e8d8bef9SDimitry Andric   Register OrigReg = OrigLI.reg();
13595ffd83dbSDimitry Andric   SmallSetVector<Register, 16> &Siblings = Virt2SiblingsMap[OrigReg];
13600b57cec5SDimitry Andric   assert(OrigLI.getVNInfoAt(Idx) == &OrigVNI && "Unexpected VNI");
13610b57cec5SDimitry Andric 
13625ffd83dbSDimitry Andric   for (const Register &SibReg : Siblings) {
13630b57cec5SDimitry Andric     LiveInterval &LI = LIS.getInterval(SibReg);
13640b57cec5SDimitry Andric     VNInfo *VNI = LI.getVNInfoAt(Idx);
13650b57cec5SDimitry Andric     if (VNI) {
13660b57cec5SDimitry Andric       LiveReg = SibReg;
13670b57cec5SDimitry Andric       return true;
13680b57cec5SDimitry Andric     }
13690b57cec5SDimitry Andric   }
13700b57cec5SDimitry Andric   return false;
13710b57cec5SDimitry Andric }
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric /// Remove redundant spills in the same BB. Save those redundant spills in
13740b57cec5SDimitry Andric /// SpillsToRm, and save the spill to keep and its BB in SpillBBToSpill map.
13750b57cec5SDimitry Andric void HoistSpillHelper::rmRedundantSpills(
13760b57cec5SDimitry Andric     SmallPtrSet<MachineInstr *, 16> &Spills,
13770b57cec5SDimitry Andric     SmallVectorImpl<MachineInstr *> &SpillsToRm,
13780b57cec5SDimitry Andric     DenseMap<MachineDomTreeNode *, MachineInstr *> &SpillBBToSpill) {
13790b57cec5SDimitry Andric   // For each spill saw, check SpillBBToSpill[] and see if its BB already has
13800b57cec5SDimitry Andric   // another spill inside. If a BB contains more than one spill, only keep the
13810b57cec5SDimitry Andric   // earlier spill with smaller SlotIndex.
1382fcaf7f86SDimitry Andric   for (auto *const CurrentSpill : Spills) {
13830b57cec5SDimitry Andric     MachineBasicBlock *Block = CurrentSpill->getParent();
1384*0fca6ea1SDimitry Andric     MachineDomTreeNode *Node = MDT.getNode(Block);
13850b57cec5SDimitry Andric     MachineInstr *PrevSpill = SpillBBToSpill[Node];
13860b57cec5SDimitry Andric     if (PrevSpill) {
13870b57cec5SDimitry Andric       SlotIndex PIdx = LIS.getInstructionIndex(*PrevSpill);
13880b57cec5SDimitry Andric       SlotIndex CIdx = LIS.getInstructionIndex(*CurrentSpill);
13890b57cec5SDimitry Andric       MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
13900b57cec5SDimitry Andric       MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
13910b57cec5SDimitry Andric       SpillsToRm.push_back(SpillToRm);
1392*0fca6ea1SDimitry Andric       SpillBBToSpill[MDT.getNode(Block)] = SpillToKeep;
13930b57cec5SDimitry Andric     } else {
1394*0fca6ea1SDimitry Andric       SpillBBToSpill[MDT.getNode(Block)] = CurrentSpill;
13950b57cec5SDimitry Andric     }
13960b57cec5SDimitry Andric   }
1397fcaf7f86SDimitry Andric   for (auto *const SpillToRm : SpillsToRm)
13980b57cec5SDimitry Andric     Spills.erase(SpillToRm);
13990b57cec5SDimitry Andric }
14000b57cec5SDimitry Andric 
14010b57cec5SDimitry Andric /// Starting from \p Root find a top-down traversal order of the dominator
14020b57cec5SDimitry Andric /// tree to visit all basic blocks containing the elements of \p Spills.
14030b57cec5SDimitry Andric /// Redundant spills will be found and put into \p SpillsToRm at the same
14040b57cec5SDimitry Andric /// time. \p SpillBBToSpill will be populated as part of the process and
14050b57cec5SDimitry Andric /// maps a basic block to the first store occurring in the basic block.
14060b57cec5SDimitry Andric /// \post SpillsToRm.union(Spills\@post) == Spills\@pre
14070b57cec5SDimitry Andric void HoistSpillHelper::getVisitOrders(
14080b57cec5SDimitry Andric     MachineBasicBlock *Root, SmallPtrSet<MachineInstr *, 16> &Spills,
14090b57cec5SDimitry Andric     SmallVectorImpl<MachineDomTreeNode *> &Orders,
14100b57cec5SDimitry Andric     SmallVectorImpl<MachineInstr *> &SpillsToRm,
14110b57cec5SDimitry Andric     DenseMap<MachineDomTreeNode *, unsigned> &SpillsToKeep,
14120b57cec5SDimitry Andric     DenseMap<MachineDomTreeNode *, MachineInstr *> &SpillBBToSpill) {
14130b57cec5SDimitry Andric   // The set contains all the possible BB nodes to which we may hoist
14140b57cec5SDimitry Andric   // original spills.
14150b57cec5SDimitry Andric   SmallPtrSet<MachineDomTreeNode *, 8> WorkSet;
14160b57cec5SDimitry Andric   // Save the BB nodes on the path from the first BB node containing
14170b57cec5SDimitry Andric   // non-redundant spill to the Root node.
14180b57cec5SDimitry Andric   SmallPtrSet<MachineDomTreeNode *, 8> NodesOnPath;
14190b57cec5SDimitry Andric   // All the spills to be hoisted must originate from a single def instruction
14200b57cec5SDimitry Andric   // to the OrigReg. It means the def instruction should dominate all the spills
14210b57cec5SDimitry Andric   // to be hoisted. We choose the BB where the def instruction is located as
14220b57cec5SDimitry Andric   // the Root.
14230b57cec5SDimitry Andric   MachineDomTreeNode *RootIDomNode = MDT[Root]->getIDom();
14240b57cec5SDimitry Andric   // For every node on the dominator tree with spill, walk up on the dominator
14250b57cec5SDimitry Andric   // tree towards the Root node until it is reached. If there is other node
14260b57cec5SDimitry Andric   // containing spill in the middle of the path, the previous spill saw will
14270b57cec5SDimitry Andric   // be redundant and the node containing it will be removed. All the nodes on
14280b57cec5SDimitry Andric   // the path starting from the first node with non-redundant spill to the Root
14290b57cec5SDimitry Andric   // node will be added to the WorkSet, which will contain all the possible
14300b57cec5SDimitry Andric   // locations where spills may be hoisted to after the loop below is done.
1431fcaf7f86SDimitry Andric   for (auto *const Spill : Spills) {
14320b57cec5SDimitry Andric     MachineBasicBlock *Block = Spill->getParent();
14330b57cec5SDimitry Andric     MachineDomTreeNode *Node = MDT[Block];
14340b57cec5SDimitry Andric     MachineInstr *SpillToRm = nullptr;
14350b57cec5SDimitry Andric     while (Node != RootIDomNode) {
14360b57cec5SDimitry Andric       // If Node dominates Block, and it already contains a spill, the spill in
14370b57cec5SDimitry Andric       // Block will be redundant.
14380b57cec5SDimitry Andric       if (Node != MDT[Block] && SpillBBToSpill[Node]) {
14390b57cec5SDimitry Andric         SpillToRm = SpillBBToSpill[MDT[Block]];
14400b57cec5SDimitry Andric         break;
14410b57cec5SDimitry Andric         /// If we see the Node already in WorkSet, the path from the Node to
14420b57cec5SDimitry Andric         /// the Root node must already be traversed by another spill.
14430b57cec5SDimitry Andric         /// Then no need to repeat.
14440b57cec5SDimitry Andric       } else if (WorkSet.count(Node)) {
14450b57cec5SDimitry Andric         break;
14460b57cec5SDimitry Andric       } else {
14470b57cec5SDimitry Andric         NodesOnPath.insert(Node);
14480b57cec5SDimitry Andric       }
14490b57cec5SDimitry Andric       Node = Node->getIDom();
14500b57cec5SDimitry Andric     }
14510b57cec5SDimitry Andric     if (SpillToRm) {
14520b57cec5SDimitry Andric       SpillsToRm.push_back(SpillToRm);
14530b57cec5SDimitry Andric     } else {
14540b57cec5SDimitry Andric       // Add a BB containing the original spills to SpillsToKeep -- i.e.,
14550b57cec5SDimitry Andric       // set the initial status before hoisting start. The value of BBs
14560b57cec5SDimitry Andric       // containing original spills is set to 0, in order to descriminate
14570b57cec5SDimitry Andric       // with BBs containing hoisted spills which will be inserted to
14580b57cec5SDimitry Andric       // SpillsToKeep later during hoisting.
14590b57cec5SDimitry Andric       SpillsToKeep[MDT[Block]] = 0;
14600b57cec5SDimitry Andric       WorkSet.insert(NodesOnPath.begin(), NodesOnPath.end());
14610b57cec5SDimitry Andric     }
14620b57cec5SDimitry Andric     NodesOnPath.clear();
14630b57cec5SDimitry Andric   }
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric   // Sort the nodes in WorkSet in top-down order and save the nodes
14660b57cec5SDimitry Andric   // in Orders. Orders will be used for hoisting in runHoistSpills.
14670b57cec5SDimitry Andric   unsigned idx = 0;
1468*0fca6ea1SDimitry Andric   Orders.push_back(MDT.getNode(Root));
14690b57cec5SDimitry Andric   do {
14700b57cec5SDimitry Andric     MachineDomTreeNode *Node = Orders[idx++];
14715ffd83dbSDimitry Andric     for (MachineDomTreeNode *Child : Node->children()) {
14720b57cec5SDimitry Andric       if (WorkSet.count(Child))
14730b57cec5SDimitry Andric         Orders.push_back(Child);
14740b57cec5SDimitry Andric     }
14750b57cec5SDimitry Andric   } while (idx != Orders.size());
14760b57cec5SDimitry Andric   assert(Orders.size() == WorkSet.size() &&
14770b57cec5SDimitry Andric          "Orders have different size with WorkSet");
14780b57cec5SDimitry Andric 
14790b57cec5SDimitry Andric #ifndef NDEBUG
14800b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "Orders size is " << Orders.size() << "\n");
14810b57cec5SDimitry Andric   SmallVector<MachineDomTreeNode *, 32>::reverse_iterator RIt = Orders.rbegin();
14820b57cec5SDimitry Andric   for (; RIt != Orders.rend(); RIt++)
14830b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "BB" << (*RIt)->getBlock()->getNumber() << ",");
14840b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "\n");
14850b57cec5SDimitry Andric #endif
14860b57cec5SDimitry Andric }
14870b57cec5SDimitry Andric 
14880b57cec5SDimitry Andric /// Try to hoist spills according to BB hotness. The spills to removed will
14890b57cec5SDimitry Andric /// be saved in \p SpillsToRm. The spills to be inserted will be saved in
14900b57cec5SDimitry Andric /// \p SpillsToIns.
14910b57cec5SDimitry Andric void HoistSpillHelper::runHoistSpills(
14920b57cec5SDimitry Andric     LiveInterval &OrigLI, VNInfo &OrigVNI,
14930b57cec5SDimitry Andric     SmallPtrSet<MachineInstr *, 16> &Spills,
14940b57cec5SDimitry Andric     SmallVectorImpl<MachineInstr *> &SpillsToRm,
14950b57cec5SDimitry Andric     DenseMap<MachineBasicBlock *, unsigned> &SpillsToIns) {
14960b57cec5SDimitry Andric   // Visit order of dominator tree nodes.
14970b57cec5SDimitry Andric   SmallVector<MachineDomTreeNode *, 32> Orders;
14980b57cec5SDimitry Andric   // SpillsToKeep contains all the nodes where spills are to be inserted
14990b57cec5SDimitry Andric   // during hoisting. If the spill to be inserted is an original spill
15000b57cec5SDimitry Andric   // (not a hoisted one), the value of the map entry is 0. If the spill
15010b57cec5SDimitry Andric   // is a hoisted spill, the value of the map entry is the VReg to be used
15020b57cec5SDimitry Andric   // as the source of the spill.
15030b57cec5SDimitry Andric   DenseMap<MachineDomTreeNode *, unsigned> SpillsToKeep;
15040b57cec5SDimitry Andric   // Map from BB to the first spill inside of it.
15050b57cec5SDimitry Andric   DenseMap<MachineDomTreeNode *, MachineInstr *> SpillBBToSpill;
15060b57cec5SDimitry Andric 
15070b57cec5SDimitry Andric   rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   MachineBasicBlock *Root = LIS.getMBBFromIndex(OrigVNI.def);
15100b57cec5SDimitry Andric   getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
15110b57cec5SDimitry Andric                  SpillBBToSpill);
15120b57cec5SDimitry Andric 
15130b57cec5SDimitry Andric   // SpillsInSubTreeMap keeps the map from a dom tree node to a pair of
15140b57cec5SDimitry Andric   // nodes set and the cost of all the spills inside those nodes.
15150b57cec5SDimitry Andric   // The nodes set are the locations where spills are to be inserted
15160b57cec5SDimitry Andric   // in the subtree of current node.
15170b57cec5SDimitry Andric   using NodesCostPair =
15180b57cec5SDimitry Andric       std::pair<SmallPtrSet<MachineDomTreeNode *, 16>, BlockFrequency>;
15190b57cec5SDimitry Andric   DenseMap<MachineDomTreeNode *, NodesCostPair> SpillsInSubTreeMap;
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric   // Iterate Orders set in reverse order, which will be a bottom-up order
15220b57cec5SDimitry Andric   // in the dominator tree. Once we visit a dom tree node, we know its
15230b57cec5SDimitry Andric   // children have already been visited and the spill locations in the
15240b57cec5SDimitry Andric   // subtrees of all the children have been determined.
15250b57cec5SDimitry Andric   SmallVector<MachineDomTreeNode *, 32>::reverse_iterator RIt = Orders.rbegin();
15260b57cec5SDimitry Andric   for (; RIt != Orders.rend(); RIt++) {
15270b57cec5SDimitry Andric     MachineBasicBlock *Block = (*RIt)->getBlock();
15280b57cec5SDimitry Andric 
15290b57cec5SDimitry Andric     // If Block contains an original spill, simply continue.
153006c3fb27SDimitry Andric     if (SpillsToKeep.contains(*RIt) && !SpillsToKeep[*RIt]) {
15310b57cec5SDimitry Andric       SpillsInSubTreeMap[*RIt].first.insert(*RIt);
15320b57cec5SDimitry Andric       // SpillsInSubTreeMap[*RIt].second contains the cost of spill.
15330b57cec5SDimitry Andric       SpillsInSubTreeMap[*RIt].second = MBFI.getBlockFreq(Block);
15340b57cec5SDimitry Andric       continue;
15350b57cec5SDimitry Andric     }
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric     // Collect spills in subtree of current node (*RIt) to
15380b57cec5SDimitry Andric     // SpillsInSubTreeMap[*RIt].first.
15395ffd83dbSDimitry Andric     for (MachineDomTreeNode *Child : (*RIt)->children()) {
154006c3fb27SDimitry Andric       if (!SpillsInSubTreeMap.contains(Child))
15410b57cec5SDimitry Andric         continue;
15420b57cec5SDimitry Andric       // The stmt "SpillsInSubTree = SpillsInSubTreeMap[*RIt].first" below
15430b57cec5SDimitry Andric       // should be placed before getting the begin and end iterators of
15440b57cec5SDimitry Andric       // SpillsInSubTreeMap[Child].first, or else the iterators may be
15450b57cec5SDimitry Andric       // invalidated when SpillsInSubTreeMap[*RIt] is seen the first time
15460b57cec5SDimitry Andric       // and the map grows and then the original buckets in the map are moved.
15470b57cec5SDimitry Andric       SmallPtrSet<MachineDomTreeNode *, 16> &SpillsInSubTree =
15480b57cec5SDimitry Andric           SpillsInSubTreeMap[*RIt].first;
15490b57cec5SDimitry Andric       BlockFrequency &SubTreeCost = SpillsInSubTreeMap[*RIt].second;
15500b57cec5SDimitry Andric       SubTreeCost += SpillsInSubTreeMap[Child].second;
15510b57cec5SDimitry Andric       auto BI = SpillsInSubTreeMap[Child].first.begin();
15520b57cec5SDimitry Andric       auto EI = SpillsInSubTreeMap[Child].first.end();
15530b57cec5SDimitry Andric       SpillsInSubTree.insert(BI, EI);
15540b57cec5SDimitry Andric       SpillsInSubTreeMap.erase(Child);
15550b57cec5SDimitry Andric     }
15560b57cec5SDimitry Andric 
15570b57cec5SDimitry Andric     SmallPtrSet<MachineDomTreeNode *, 16> &SpillsInSubTree =
15580b57cec5SDimitry Andric           SpillsInSubTreeMap[*RIt].first;
15590b57cec5SDimitry Andric     BlockFrequency &SubTreeCost = SpillsInSubTreeMap[*RIt].second;
15600b57cec5SDimitry Andric     // No spills in subtree, simply continue.
15610b57cec5SDimitry Andric     if (SpillsInSubTree.empty())
15620b57cec5SDimitry Andric       continue;
15630b57cec5SDimitry Andric 
15640b57cec5SDimitry Andric     // Check whether Block is a possible candidate to insert spill.
15655ffd83dbSDimitry Andric     Register LiveReg;
15660b57cec5SDimitry Andric     if (!isSpillCandBB(OrigLI, OrigVNI, *Block, LiveReg))
15670b57cec5SDimitry Andric       continue;
15680b57cec5SDimitry Andric 
15690b57cec5SDimitry Andric     // If there are multiple spills that could be merged, bias a little
15700b57cec5SDimitry Andric     // to hoist the spill.
15710b57cec5SDimitry Andric     BranchProbability MarginProb = (SpillsInSubTree.size() > 1)
15720b57cec5SDimitry Andric                                        ? BranchProbability(9, 10)
15730b57cec5SDimitry Andric                                        : BranchProbability(1, 1);
15740b57cec5SDimitry Andric     if (SubTreeCost > MBFI.getBlockFreq(Block) * MarginProb) {
15750b57cec5SDimitry Andric       // Hoist: Move spills to current Block.
1576fcaf7f86SDimitry Andric       for (auto *const SpillBB : SpillsInSubTree) {
15770b57cec5SDimitry Andric         // When SpillBB is a BB contains original spill, insert the spill
15780b57cec5SDimitry Andric         // to SpillsToRm.
157906c3fb27SDimitry Andric         if (SpillsToKeep.contains(SpillBB) && !SpillsToKeep[SpillBB]) {
15800b57cec5SDimitry Andric           MachineInstr *SpillToRm = SpillBBToSpill[SpillBB];
15810b57cec5SDimitry Andric           SpillsToRm.push_back(SpillToRm);
15820b57cec5SDimitry Andric         }
15830b57cec5SDimitry Andric         // SpillBB will not contain spill anymore, remove it from SpillsToKeep.
15840b57cec5SDimitry Andric         SpillsToKeep.erase(SpillBB);
15850b57cec5SDimitry Andric       }
15860b57cec5SDimitry Andric       // Current Block is the BB containing the new hoisted spill. Add it to
15870b57cec5SDimitry Andric       // SpillsToKeep. LiveReg is the source of the new spill.
15880b57cec5SDimitry Andric       SpillsToKeep[*RIt] = LiveReg;
15890b57cec5SDimitry Andric       LLVM_DEBUG({
15900b57cec5SDimitry Andric         dbgs() << "spills in BB: ";
15910b57cec5SDimitry Andric         for (const auto Rspill : SpillsInSubTree)
15920b57cec5SDimitry Andric           dbgs() << Rspill->getBlock()->getNumber() << " ";
15930b57cec5SDimitry Andric         dbgs() << "were promoted to BB" << (*RIt)->getBlock()->getNumber()
15940b57cec5SDimitry Andric                << "\n";
15950b57cec5SDimitry Andric       });
15960b57cec5SDimitry Andric       SpillsInSubTree.clear();
15970b57cec5SDimitry Andric       SpillsInSubTree.insert(*RIt);
15980b57cec5SDimitry Andric       SubTreeCost = MBFI.getBlockFreq(Block);
15990b57cec5SDimitry Andric     }
16000b57cec5SDimitry Andric   }
16010b57cec5SDimitry Andric   // For spills in SpillsToKeep with LiveReg set (i.e., not original spill),
16020b57cec5SDimitry Andric   // save them to SpillsToIns.
1603480093f4SDimitry Andric   for (const auto &Ent : SpillsToKeep) {
16040b57cec5SDimitry Andric     if (Ent.second)
16050b57cec5SDimitry Andric       SpillsToIns[Ent.first->getBlock()] = Ent.second;
16060b57cec5SDimitry Andric   }
16070b57cec5SDimitry Andric }
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric /// For spills with equal values, remove redundant spills and hoist those left
16100b57cec5SDimitry Andric /// to less hot spots.
16110b57cec5SDimitry Andric ///
16120b57cec5SDimitry Andric /// Spills with equal values will be collected into the same set in
16130b57cec5SDimitry Andric /// MergeableSpills when spill is inserted. These equal spills are originated
16140b57cec5SDimitry Andric /// from the same defining instruction and are dominated by the instruction.
16150b57cec5SDimitry Andric /// Before hoisting all the equal spills, redundant spills inside in the same
16160b57cec5SDimitry Andric /// BB are first marked to be deleted. Then starting from the spills left, walk
16170b57cec5SDimitry Andric /// up on the dominator tree towards the Root node where the define instruction
16180b57cec5SDimitry Andric /// is located, mark the dominated spills to be deleted along the way and
16190b57cec5SDimitry Andric /// collect the BB nodes on the path from non-dominated spills to the define
16200b57cec5SDimitry Andric /// instruction into a WorkSet. The nodes in WorkSet are the candidate places
16210b57cec5SDimitry Andric /// where we are considering to hoist the spills. We iterate the WorkSet in
16220b57cec5SDimitry Andric /// bottom-up order, and for each node, we will decide whether to hoist spills
16230b57cec5SDimitry Andric /// inside its subtree to that node. In this way, we can get benefit locally
16240b57cec5SDimitry Andric /// even if hoisting all the equal spills to one cold place is impossible.
16250b57cec5SDimitry Andric void HoistSpillHelper::hoistAllSpills() {
16265ffd83dbSDimitry Andric   SmallVector<Register, 4> NewVRegs;
16270b57cec5SDimitry Andric   LiveRangeEdit Edit(nullptr, NewVRegs, MF, LIS, &VRM, this);
16280b57cec5SDimitry Andric 
16290b57cec5SDimitry Andric   for (unsigned i = 0, e = MRI.getNumVirtRegs(); i != e; ++i) {
16305ffd83dbSDimitry Andric     Register Reg = Register::index2VirtReg(i);
16315ffd83dbSDimitry Andric     Register Original = VRM.getPreSplitReg(Reg);
16320b57cec5SDimitry Andric     if (!MRI.def_empty(Reg))
16330b57cec5SDimitry Andric       Virt2SiblingsMap[Original].insert(Reg);
16340b57cec5SDimitry Andric   }
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric   // Each entry in MergeableSpills contains a spill set with equal values.
16370b57cec5SDimitry Andric   for (auto &Ent : MergeableSpills) {
16380b57cec5SDimitry Andric     int Slot = Ent.first.first;
16390b57cec5SDimitry Andric     LiveInterval &OrigLI = *StackSlotToOrigLI[Slot];
16400b57cec5SDimitry Andric     VNInfo *OrigVNI = Ent.first.second;
16410b57cec5SDimitry Andric     SmallPtrSet<MachineInstr *, 16> &EqValSpills = Ent.second;
16420b57cec5SDimitry Andric     if (Ent.second.empty())
16430b57cec5SDimitry Andric       continue;
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric     LLVM_DEBUG({
16460b57cec5SDimitry Andric       dbgs() << "\nFor Slot" << Slot << " and VN" << OrigVNI->id << ":\n"
16470b57cec5SDimitry Andric              << "Equal spills in BB: ";
16480b57cec5SDimitry Andric       for (const auto spill : EqValSpills)
16490b57cec5SDimitry Andric         dbgs() << spill->getParent()->getNumber() << " ";
16500b57cec5SDimitry Andric       dbgs() << "\n";
16510b57cec5SDimitry Andric     });
16520b57cec5SDimitry Andric 
16530b57cec5SDimitry Andric     // SpillsToRm is the spill set to be removed from EqValSpills.
16540b57cec5SDimitry Andric     SmallVector<MachineInstr *, 16> SpillsToRm;
16550b57cec5SDimitry Andric     // SpillsToIns is the spill set to be newly inserted after hoisting.
16560b57cec5SDimitry Andric     DenseMap<MachineBasicBlock *, unsigned> SpillsToIns;
16570b57cec5SDimitry Andric 
16580b57cec5SDimitry Andric     runHoistSpills(OrigLI, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
16590b57cec5SDimitry Andric 
16600b57cec5SDimitry Andric     LLVM_DEBUG({
16610b57cec5SDimitry Andric       dbgs() << "Finally inserted spills in BB: ";
1662480093f4SDimitry Andric       for (const auto &Ispill : SpillsToIns)
16630b57cec5SDimitry Andric         dbgs() << Ispill.first->getNumber() << " ";
16640b57cec5SDimitry Andric       dbgs() << "\nFinally removed spills in BB: ";
16650b57cec5SDimitry Andric       for (const auto Rspill : SpillsToRm)
16660b57cec5SDimitry Andric         dbgs() << Rspill->getParent()->getNumber() << " ";
16670b57cec5SDimitry Andric       dbgs() << "\n";
16680b57cec5SDimitry Andric     });
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric     // Stack live range update.
16710b57cec5SDimitry Andric     LiveInterval &StackIntvl = LSS.getInterval(Slot);
16720b57cec5SDimitry Andric     if (!SpillsToIns.empty() || !SpillsToRm.empty())
16730b57cec5SDimitry Andric       StackIntvl.MergeValueInAsValue(OrigLI, OrigVNI,
16740b57cec5SDimitry Andric                                      StackIntvl.getValNumInfo(0));
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric     // Insert hoisted spills.
1677480093f4SDimitry Andric     for (auto const &Insert : SpillsToIns) {
16780b57cec5SDimitry Andric       MachineBasicBlock *BB = Insert.first;
16795ffd83dbSDimitry Andric       Register LiveReg = Insert.second;
1680e8d8bef9SDimitry Andric       MachineBasicBlock::iterator MII = IPA.getLastInsertPointIter(OrigLI, *BB);
1681e8d8bef9SDimitry Andric       MachineInstrSpan MIS(MII, BB);
1682e8d8bef9SDimitry Andric       TII.storeRegToStackSlot(*BB, MII, LiveReg, false, Slot,
1683bdd1243dSDimitry Andric                               MRI.getRegClass(LiveReg), &TRI, Register());
1684e8d8bef9SDimitry Andric       LIS.InsertMachineInstrRangeInMaps(MIS.begin(), MII);
1685e8d8bef9SDimitry Andric       for (const MachineInstr &MI : make_range(MIS.begin(), MII))
1686e8d8bef9SDimitry Andric         getVDefInterval(MI, LIS);
16870b57cec5SDimitry Andric       ++NumSpills;
16880b57cec5SDimitry Andric     }
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric     // Remove redundant spills or change them to dead instructions.
16910b57cec5SDimitry Andric     NumSpills -= SpillsToRm.size();
1692fcaf7f86SDimitry Andric     for (auto *const RMEnt : SpillsToRm) {
16930b57cec5SDimitry Andric       RMEnt->setDesc(TII.get(TargetOpcode::KILL));
16940b57cec5SDimitry Andric       for (unsigned i = RMEnt->getNumOperands(); i; --i) {
16950b57cec5SDimitry Andric         MachineOperand &MO = RMEnt->getOperand(i - 1);
16960b57cec5SDimitry Andric         if (MO.isReg() && MO.isImplicit() && MO.isDef() && !MO.isDead())
169781ad6265SDimitry Andric           RMEnt->removeOperand(i - 1);
16980b57cec5SDimitry Andric       }
16990b57cec5SDimitry Andric     }
1700bdd1243dSDimitry Andric     Edit.eliminateDeadDefs(SpillsToRm, std::nullopt);
17010b57cec5SDimitry Andric   }
17020b57cec5SDimitry Andric }
17030b57cec5SDimitry Andric 
17040b57cec5SDimitry Andric /// For VirtReg clone, the \p New register should have the same physreg or
17050b57cec5SDimitry Andric /// stackslot as the \p old register.
1706e8d8bef9SDimitry Andric void HoistSpillHelper::LRE_DidCloneVirtReg(Register New, Register Old) {
17070b57cec5SDimitry Andric   if (VRM.hasPhys(Old))
17080b57cec5SDimitry Andric     VRM.assignVirt2Phys(New, VRM.getPhys(Old));
17090b57cec5SDimitry Andric   else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT)
17100b57cec5SDimitry Andric     VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
17110b57cec5SDimitry Andric   else
17120b57cec5SDimitry Andric     llvm_unreachable("VReg should be assigned either physreg or stackslot");
1713e8d8bef9SDimitry Andric   if (VRM.hasShape(Old))
1714e8d8bef9SDimitry Andric     VRM.assignVirt2Shape(New, VRM.getShape(Old));
17150b57cec5SDimitry Andric }
1716