17a7e6055SDimitry Andric //===- LiveRegMatrix.cpp - Track register interference --------------------===//
27ae0e2c9SDimitry Andric //
37ae0e2c9SDimitry Andric //                     The LLVM Compiler Infrastructure
47ae0e2c9SDimitry Andric //
57ae0e2c9SDimitry Andric // This file is distributed under the University of Illinois Open Source
67ae0e2c9SDimitry Andric // License. See LICENSE.TXT for details.
77ae0e2c9SDimitry Andric //
87ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
97ae0e2c9SDimitry Andric //
107ae0e2c9SDimitry Andric // This file defines the LiveRegMatrix analysis pass.
117ae0e2c9SDimitry Andric //
127ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
137ae0e2c9SDimitry Andric 
14db17bf38SDimitry Andric #include "llvm/CodeGen/LiveRegMatrix.h"
153861d79fSDimitry Andric #include "RegisterCoalescer.h"
167ae0e2c9SDimitry Andric #include "llvm/ADT/Statistic.h"
177a7e6055SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
187a7e6055SDimitry Andric #include "llvm/CodeGen/LiveIntervalUnion.h"
192cab237bSDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
207a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
212cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
23db17bf38SDimitry Andric #include "llvm/CodeGen/VirtRegMap.h"
247a7e6055SDimitry Andric #include "llvm/MC/LaneBitmask.h"
257a7e6055SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
26db17bf38SDimitry Andric #include "llvm/Pass.h"
277ae0e2c9SDimitry Andric #include "llvm/Support/Debug.h"
287ae0e2c9SDimitry Andric #include "llvm/Support/raw_ostream.h"
297a7e6055SDimitry Andric #include <cassert>
307ae0e2c9SDimitry Andric 
317ae0e2c9SDimitry Andric using namespace llvm;
327ae0e2c9SDimitry Andric 
3391bc56edSDimitry Andric #define DEBUG_TYPE "regalloc"
3491bc56edSDimitry Andric 
357ae0e2c9SDimitry Andric STATISTIC(NumAssigned   , "Number of registers assigned");
367ae0e2c9SDimitry Andric STATISTIC(NumUnassigned , "Number of registers unassigned");
377ae0e2c9SDimitry Andric 
387ae0e2c9SDimitry Andric char LiveRegMatrix::ID = 0;
397ae0e2c9SDimitry Andric INITIALIZE_PASS_BEGIN(LiveRegMatrix, "liveregmatrix",
407ae0e2c9SDimitry Andric                       "Live Register Matrix", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)417ae0e2c9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
427ae0e2c9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
437ae0e2c9SDimitry Andric INITIALIZE_PASS_END(LiveRegMatrix, "liveregmatrix",
447ae0e2c9SDimitry Andric                     "Live Register Matrix", false, false)
457ae0e2c9SDimitry Andric 
467a7e6055SDimitry Andric LiveRegMatrix::LiveRegMatrix() : MachineFunctionPass(ID) {}
477ae0e2c9SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const487ae0e2c9SDimitry Andric void LiveRegMatrix::getAnalysisUsage(AnalysisUsage &AU) const {
497ae0e2c9SDimitry Andric   AU.setPreservesAll();
507ae0e2c9SDimitry Andric   AU.addRequiredTransitive<LiveIntervals>();
517ae0e2c9SDimitry Andric   AU.addRequiredTransitive<VirtRegMap>();
527ae0e2c9SDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
537ae0e2c9SDimitry Andric }
547ae0e2c9SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)557ae0e2c9SDimitry Andric bool LiveRegMatrix::runOnMachineFunction(MachineFunction &MF) {
5639d628a0SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
577ae0e2c9SDimitry Andric   LIS = &getAnalysis<LiveIntervals>();
587ae0e2c9SDimitry Andric   VRM = &getAnalysis<VirtRegMap>();
597ae0e2c9SDimitry Andric 
607ae0e2c9SDimitry Andric   unsigned NumRegUnits = TRI->getNumRegUnits();
617ae0e2c9SDimitry Andric   if (NumRegUnits != Matrix.size())
627ae0e2c9SDimitry Andric     Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]);
637ae0e2c9SDimitry Andric   Matrix.init(LIUAlloc, NumRegUnits);
647ae0e2c9SDimitry Andric 
657ae0e2c9SDimitry Andric   // Make sure no stale queries get reused.
667ae0e2c9SDimitry Andric   invalidateVirtRegs();
677ae0e2c9SDimitry Andric   return false;
687ae0e2c9SDimitry Andric }
697ae0e2c9SDimitry Andric 
releaseMemory()707ae0e2c9SDimitry Andric void LiveRegMatrix::releaseMemory() {
717ae0e2c9SDimitry Andric   for (unsigned i = 0, e = Matrix.size(); i != e; ++i) {
727ae0e2c9SDimitry Andric     Matrix[i].clear();
7391bc56edSDimitry Andric     // No need to clear Queries here, since LiveIntervalUnion::Query doesn't
7491bc56edSDimitry Andric     // have anything important to clear and LiveRegMatrix's runOnFunction()
7591bc56edSDimitry Andric     // does a std::unique_ptr::reset anyways.
767ae0e2c9SDimitry Andric   }
777ae0e2c9SDimitry Andric }
787ae0e2c9SDimitry Andric 
7939d628a0SDimitry Andric template <typename Callable>
foreachUnit(const TargetRegisterInfo * TRI,LiveInterval & VRegInterval,unsigned PhysReg,Callable Func)80d88c1a5aSDimitry Andric static bool foreachUnit(const TargetRegisterInfo *TRI,
81d88c1a5aSDimitry Andric                         LiveInterval &VRegInterval, unsigned PhysReg,
82d88c1a5aSDimitry Andric                         Callable Func) {
8339d628a0SDimitry Andric   if (VRegInterval.hasSubRanges()) {
8439d628a0SDimitry Andric     for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
8539d628a0SDimitry Andric       unsigned Unit = (*Units).first;
867d523365SDimitry Andric       LaneBitmask Mask = (*Units).second;
8739d628a0SDimitry Andric       for (LiveInterval::SubRange &S : VRegInterval.subranges()) {
88d88c1a5aSDimitry Andric         if ((S.LaneMask & Mask).any()) {
8939d628a0SDimitry Andric           if (Func(Unit, S))
9039d628a0SDimitry Andric             return true;
9139d628a0SDimitry Andric           break;
9239d628a0SDimitry Andric         }
9339d628a0SDimitry Andric       }
9439d628a0SDimitry Andric     }
9539d628a0SDimitry Andric   } else {
9639d628a0SDimitry Andric     for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
9739d628a0SDimitry Andric       if (Func(*Units, VRegInterval))
9839d628a0SDimitry Andric         return true;
9939d628a0SDimitry Andric     }
10039d628a0SDimitry Andric   }
10139d628a0SDimitry Andric   return false;
10239d628a0SDimitry Andric }
10339d628a0SDimitry Andric 
assign(LiveInterval & VirtReg,unsigned PhysReg)1047ae0e2c9SDimitry Andric void LiveRegMatrix::assign(LiveInterval &VirtReg, unsigned PhysReg) {
105*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg, TRI) << " to "
106*4ba319b5SDimitry Andric                     << printReg(PhysReg, TRI) << ':');
1077ae0e2c9SDimitry Andric   assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment");
1087ae0e2c9SDimitry Andric   VRM->assignVirt2Phys(VirtReg.reg, PhysReg);
10939d628a0SDimitry Andric 
110*4ba319b5SDimitry Andric   foreachUnit(
111*4ba319b5SDimitry Andric       TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) {
112*4ba319b5SDimitry Andric         LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range);
11339d628a0SDimitry Andric         Matrix[Unit].unify(VirtReg, Range);
11439d628a0SDimitry Andric         return false;
11539d628a0SDimitry Andric       });
11639d628a0SDimitry Andric 
1177ae0e2c9SDimitry Andric   ++NumAssigned;
118*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << '\n');
1197ae0e2c9SDimitry Andric }
1207ae0e2c9SDimitry Andric 
unassign(LiveInterval & VirtReg)1217ae0e2c9SDimitry Andric void LiveRegMatrix::unassign(LiveInterval &VirtReg) {
1227ae0e2c9SDimitry Andric   unsigned PhysReg = VRM->getPhys(VirtReg.reg);
123*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg, TRI) << " from "
124*4ba319b5SDimitry Andric                     << printReg(PhysReg, TRI) << ':');
1257ae0e2c9SDimitry Andric   VRM->clearVirt(VirtReg.reg);
12639d628a0SDimitry Andric 
127*4ba319b5SDimitry Andric   foreachUnit(TRI, VirtReg, PhysReg,
128*4ba319b5SDimitry Andric               [&](unsigned Unit, const LiveRange &Range) {
129*4ba319b5SDimitry Andric                 LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI));
13039d628a0SDimitry Andric                 Matrix[Unit].extract(VirtReg, Range);
13139d628a0SDimitry Andric                 return false;
13239d628a0SDimitry Andric               });
13339d628a0SDimitry Andric 
1347ae0e2c9SDimitry Andric   ++NumUnassigned;
135*4ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << '\n');
1367ae0e2c9SDimitry Andric }
1377ae0e2c9SDimitry Andric 
isPhysRegUsed(unsigned PhysReg) const138875ed548SDimitry Andric bool LiveRegMatrix::isPhysRegUsed(unsigned PhysReg) const {
139875ed548SDimitry Andric   for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
140875ed548SDimitry Andric     if (!Matrix[*Unit].empty())
141875ed548SDimitry Andric       return true;
142875ed548SDimitry Andric   }
143875ed548SDimitry Andric   return false;
144875ed548SDimitry Andric }
145875ed548SDimitry Andric 
checkRegMaskInterference(LiveInterval & VirtReg,unsigned PhysReg)1467ae0e2c9SDimitry Andric bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg,
1477ae0e2c9SDimitry Andric                                              unsigned PhysReg) {
1487ae0e2c9SDimitry Andric   // Check if the cached information is valid.
1497ae0e2c9SDimitry Andric   // The same BitVector can be reused for all PhysRegs.
1507ae0e2c9SDimitry Andric   // We could cache multiple VirtRegs if it becomes necessary.
1517ae0e2c9SDimitry Andric   if (RegMaskVirtReg != VirtReg.reg || RegMaskTag != UserTag) {
1527ae0e2c9SDimitry Andric     RegMaskVirtReg = VirtReg.reg;
1537ae0e2c9SDimitry Andric     RegMaskTag = UserTag;
1547ae0e2c9SDimitry Andric     RegMaskUsable.clear();
1557ae0e2c9SDimitry Andric     LIS->checkRegMaskInterference(VirtReg, RegMaskUsable);
1567ae0e2c9SDimitry Andric   }
1577ae0e2c9SDimitry Andric 
1587ae0e2c9SDimitry Andric   // The BitVector is indexed by PhysReg, not register unit.
1597ae0e2c9SDimitry Andric   // Regmask interference is more fine grained than regunits.
1607ae0e2c9SDimitry Andric   // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8.
1617ae0e2c9SDimitry Andric   return !RegMaskUsable.empty() && (!PhysReg || !RegMaskUsable.test(PhysReg));
1627ae0e2c9SDimitry Andric }
1637ae0e2c9SDimitry Andric 
checkRegUnitInterference(LiveInterval & VirtReg,unsigned PhysReg)1647ae0e2c9SDimitry Andric bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
1657ae0e2c9SDimitry Andric                                              unsigned PhysReg) {
1667ae0e2c9SDimitry Andric   if (VirtReg.empty())
1677ae0e2c9SDimitry Andric     return false;
1683861d79fSDimitry Andric   CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);
16939d628a0SDimitry Andric 
17039d628a0SDimitry Andric   bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
17139d628a0SDimitry Andric                                                        const LiveRange &Range) {
17239d628a0SDimitry Andric     const LiveRange &UnitRange = LIS->getRegUnit(Unit);
17339d628a0SDimitry Andric     return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
17439d628a0SDimitry Andric   });
17539d628a0SDimitry Andric   return Result;
1767ae0e2c9SDimitry Andric }
1777ae0e2c9SDimitry Andric 
query(const LiveRange & LR,unsigned RegUnit)1787a7e6055SDimitry Andric LiveIntervalUnion::Query &LiveRegMatrix::query(const LiveRange &LR,
1797ae0e2c9SDimitry Andric                                                unsigned RegUnit) {
1807ae0e2c9SDimitry Andric   LiveIntervalUnion::Query &Q = Queries[RegUnit];
1817a7e6055SDimitry Andric   Q.init(UserTag, LR, Matrix[RegUnit]);
1827ae0e2c9SDimitry Andric   return Q;
1837ae0e2c9SDimitry Andric }
1847ae0e2c9SDimitry Andric 
1857ae0e2c9SDimitry Andric LiveRegMatrix::InterferenceKind
checkInterference(LiveInterval & VirtReg,unsigned PhysReg)1867ae0e2c9SDimitry Andric LiveRegMatrix::checkInterference(LiveInterval &VirtReg, unsigned PhysReg) {
1877ae0e2c9SDimitry Andric   if (VirtReg.empty())
1887ae0e2c9SDimitry Andric     return IK_Free;
1897ae0e2c9SDimitry Andric 
1907ae0e2c9SDimitry Andric   // Regmask interference is the fastest check.
1917ae0e2c9SDimitry Andric   if (checkRegMaskInterference(VirtReg, PhysReg))
1927ae0e2c9SDimitry Andric     return IK_RegMask;
1937ae0e2c9SDimitry Andric 
1947ae0e2c9SDimitry Andric   // Check for fixed interference.
1957ae0e2c9SDimitry Andric   if (checkRegUnitInterference(VirtReg, PhysReg))
1967ae0e2c9SDimitry Andric     return IK_RegUnit;
1977ae0e2c9SDimitry Andric 
1987ae0e2c9SDimitry Andric   // Check the matrix for virtual register interference.
1997a7e6055SDimitry Andric   bool Interference = foreachUnit(TRI, VirtReg, PhysReg,
2007a7e6055SDimitry Andric                                   [&](unsigned Unit, const LiveRange &LR) {
2017a7e6055SDimitry Andric     return query(LR, Unit).checkInterference();
2027a7e6055SDimitry Andric   });
2037a7e6055SDimitry Andric   if (Interference)
2047ae0e2c9SDimitry Andric     return IK_VirtReg;
2057ae0e2c9SDimitry Andric 
2067ae0e2c9SDimitry Andric   return IK_Free;
2077ae0e2c9SDimitry Andric }
208*4ba319b5SDimitry Andric 
checkInterference(SlotIndex Start,SlotIndex End,unsigned PhysReg)209*4ba319b5SDimitry Andric bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
210*4ba319b5SDimitry Andric                                       unsigned PhysReg) {
211*4ba319b5SDimitry Andric   // Construct artificial live range containing only one segment [Start, End).
212*4ba319b5SDimitry Andric   VNInfo valno(0, Start);
213*4ba319b5SDimitry Andric   LiveRange::Segment Seg(Start, End, &valno);
214*4ba319b5SDimitry Andric   LiveRange LR;
215*4ba319b5SDimitry Andric   LR.addSegment(Seg);
216*4ba319b5SDimitry Andric 
217*4ba319b5SDimitry Andric   // Check for interference with that segment
218*4ba319b5SDimitry Andric   for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
219*4ba319b5SDimitry Andric     if (query(LR, *Units).checkInterference())
220*4ba319b5SDimitry Andric       return true;
221*4ba319b5SDimitry Andric   }
222*4ba319b5SDimitry Andric   return false;
223*4ba319b5SDimitry Andric }
224