| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 1 | //===- LiveRegMatrix.cpp - Track register interference --------------------===// | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file defines the LiveRegMatrix analysis pass. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/LiveRegMatrix.h" | 
| Jakob Stoklund Olesen | 866908c | 2012-09-06 18:15:23 +0000 | [diff] [blame] | 15 | #include "RegisterCoalescer.h" | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 16 | #include "llvm/ADT/Statistic.h" | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 17 | #include "llvm/CodeGen/LiveInterval.h" | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/LiveIntervalUnion.h" | 
| Matthias Braun | f842297 | 2017-12-13 02:51:04 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/LiveIntervals.h" | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 20 | #include "llvm/CodeGen/MachineFunction.h" | 
| David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/TargetRegisterInfo.h" | 
|  | 22 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/VirtRegMap.h" | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 24 | #include "llvm/MC/LaneBitmask.h" | 
|  | 25 | #include "llvm/MC/MCRegisterInfo.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 26 | #include "llvm/Pass.h" | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 27 | #include "llvm/Support/Debug.h" | 
| Chandler Carruth | d990388 | 2015-01-14 11:23:27 +0000 | [diff] [blame] | 28 | #include "llvm/Support/raw_ostream.h" | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 29 | #include <cassert> | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 30 |  | 
|  | 31 | using namespace llvm; | 
|  | 32 |  | 
| Chandler Carruth | 1b9dde0 | 2014-04-22 02:02:50 +0000 | [diff] [blame] | 33 | #define DEBUG_TYPE "regalloc" | 
|  | 34 |  | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 35 | STATISTIC(NumAssigned   , "Number of registers assigned"); | 
|  | 36 | STATISTIC(NumUnassigned , "Number of registers unassigned"); | 
|  | 37 |  | 
|  | 38 | char LiveRegMatrix::ID = 0; | 
|  | 39 | INITIALIZE_PASS_BEGIN(LiveRegMatrix, "liveregmatrix", | 
|  | 40 | "Live Register Matrix", false, false) | 
|  | 41 | INITIALIZE_PASS_DEPENDENCY(LiveIntervals) | 
|  | 42 | INITIALIZE_PASS_DEPENDENCY(VirtRegMap) | 
|  | 43 | INITIALIZE_PASS_END(LiveRegMatrix, "liveregmatrix", | 
|  | 44 | "Live Register Matrix", false, false) | 
|  | 45 |  | 
| Eugene Zelenko | 5db84df | 2017-02-17 21:43:25 +0000 | [diff] [blame] | 46 | LiveRegMatrix::LiveRegMatrix() : MachineFunctionPass(ID) {} | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 47 |  | 
|  | 48 | void LiveRegMatrix::getAnalysisUsage(AnalysisUsage &AU) const { | 
|  | 49 | AU.setPreservesAll(); | 
|  | 50 | AU.addRequiredTransitive<LiveIntervals>(); | 
|  | 51 | AU.addRequiredTransitive<VirtRegMap>(); | 
|  | 52 | MachineFunctionPass::getAnalysisUsage(AU); | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | bool LiveRegMatrix::runOnMachineFunction(MachineFunction &MF) { | 
| Eric Christopher | fc6de42 | 2014-08-05 02:39:49 +0000 | [diff] [blame] | 56 | TRI = MF.getSubtarget().getRegisterInfo(); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 57 | LIS = &getAnalysis<LiveIntervals>(); | 
|  | 58 | VRM = &getAnalysis<VirtRegMap>(); | 
|  | 59 |  | 
|  | 60 | unsigned NumRegUnits = TRI->getNumRegUnits(); | 
|  | 61 | if (NumRegUnits != Matrix.size()) | 
|  | 62 | Queries.reset(new LiveIntervalUnion::Query[NumRegUnits]); | 
|  | 63 | Matrix.init(LIUAlloc, NumRegUnits); | 
|  | 64 |  | 
|  | 65 | // Make sure no stale queries get reused. | 
|  | 66 | invalidateVirtRegs(); | 
|  | 67 | return false; | 
|  | 68 | } | 
|  | 69 |  | 
|  | 70 | void LiveRegMatrix::releaseMemory() { | 
|  | 71 | for (unsigned i = 0, e = Matrix.size(); i != e; ++i) { | 
|  | 72 | Matrix[i].clear(); | 
| Puyan Lotfi | 12ae04b | 2014-02-06 08:42:01 +0000 | [diff] [blame] | 73 | // No need to clear Queries here, since LiveIntervalUnion::Query doesn't | 
|  | 74 | // have anything important to clear and LiveRegMatrix's runOnFunction() | 
| Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 75 | // does a std::unique_ptr::reset anyways. | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 76 | } | 
|  | 77 | } | 
|  | 78 |  | 
| Benjamin Kramer | b7d3311 | 2016-08-06 11:13:10 +0000 | [diff] [blame] | 79 | template <typename Callable> | 
|  | 80 | static bool foreachUnit(const TargetRegisterInfo *TRI, | 
|  | 81 | LiveInterval &VRegInterval, unsigned PhysReg, | 
|  | 82 | Callable Func) { | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 83 | if (VRegInterval.hasSubRanges()) { | 
|  | 84 | for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | 
|  | 85 | unsigned Unit = (*Units).first; | 
| Matthias Braun | e6a2485 | 2015-09-25 21:51:14 +0000 | [diff] [blame] | 86 | LaneBitmask Mask = (*Units).second; | 
| Matthias Braun | 09afa1e | 2014-12-11 00:59:06 +0000 | [diff] [blame] | 87 | for (LiveInterval::SubRange &S : VRegInterval.subranges()) { | 
| Krzysztof Parzyszek | ea9f8ce | 2016-12-16 19:11:56 +0000 | [diff] [blame] | 88 | if ((S.LaneMask & Mask).any()) { | 
| Matthias Braun | 09afa1e | 2014-12-11 00:59:06 +0000 | [diff] [blame] | 89 | if (Func(Unit, S)) | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 90 | return true; | 
|  | 91 | break; | 
|  | 92 | } | 
|  | 93 | } | 
|  | 94 | } | 
|  | 95 | } else { | 
|  | 96 | for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | 
|  | 97 | if (Func(*Units, VRegInterval)) | 
|  | 98 | return true; | 
|  | 99 | } | 
|  | 100 | } | 
|  | 101 | return false; | 
|  | 102 | } | 
|  | 103 |  | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 104 | void LiveRegMatrix::assign(LiveInterval &VirtReg, unsigned PhysReg) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 105 | LLVM_DEBUG(dbgs() << "assigning " << printReg(VirtReg.reg, TRI) << " to " | 
|  | 106 | << printReg(PhysReg, TRI) << ':'); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 107 | assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment"); | 
|  | 108 | VRM->assignVirt2Phys(VirtReg.reg, PhysReg); | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 109 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 110 | foreachUnit( | 
|  | 111 | TRI, VirtReg, PhysReg, [&](unsigned Unit, const LiveRange &Range) { | 
|  | 112 | LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI) << ' ' << Range); | 
|  | 113 | Matrix[Unit].unify(VirtReg, Range); | 
|  | 114 | return false; | 
|  | 115 | }); | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 116 |  | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 117 | ++NumAssigned; | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 118 | LLVM_DEBUG(dbgs() << '\n'); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
|  | 121 | void LiveRegMatrix::unassign(LiveInterval &VirtReg) { | 
|  | 122 | unsigned PhysReg = VRM->getPhys(VirtReg.reg); | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 123 | LLVM_DEBUG(dbgs() << "unassigning " << printReg(VirtReg.reg, TRI) << " from " | 
|  | 124 | << printReg(PhysReg, TRI) << ':'); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 125 | VRM->clearVirt(VirtReg.reg); | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 126 |  | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 127 | foreachUnit(TRI, VirtReg, PhysReg, | 
|  | 128 | [&](unsigned Unit, const LiveRange &Range) { | 
|  | 129 | LLVM_DEBUG(dbgs() << ' ' << printRegUnit(Unit, TRI)); | 
|  | 130 | Matrix[Unit].extract(VirtReg, Range); | 
|  | 131 | return false; | 
|  | 132 | }); | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 133 |  | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 134 | ++NumUnassigned; | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 135 | LLVM_DEBUG(dbgs() << '\n'); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 136 | } | 
|  | 137 |  | 
| Matthias Braun | 953393a | 2015-07-14 17:38:17 +0000 | [diff] [blame] | 138 | bool LiveRegMatrix::isPhysRegUsed(unsigned PhysReg) const { | 
|  | 139 | for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) { | 
|  | 140 | if (!Matrix[*Unit].empty()) | 
|  | 141 | return true; | 
|  | 142 | } | 
|  | 143 | return false; | 
|  | 144 | } | 
|  | 145 |  | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 146 | bool LiveRegMatrix::checkRegMaskInterference(LiveInterval &VirtReg, | 
|  | 147 | unsigned PhysReg) { | 
|  | 148 | // Check if the cached information is valid. | 
|  | 149 | // The same BitVector can be reused for all PhysRegs. | 
|  | 150 | // We could cache multiple VirtRegs if it becomes necessary. | 
|  | 151 | if (RegMaskVirtReg != VirtReg.reg || RegMaskTag != UserTag) { | 
|  | 152 | RegMaskVirtReg = VirtReg.reg; | 
|  | 153 | RegMaskTag = UserTag; | 
|  | 154 | RegMaskUsable.clear(); | 
|  | 155 | LIS->checkRegMaskInterference(VirtReg, RegMaskUsable); | 
|  | 156 | } | 
|  | 157 |  | 
|  | 158 | // The BitVector is indexed by PhysReg, not register unit. | 
|  | 159 | // Regmask interference is more fine grained than regunits. | 
|  | 160 | // For example, a Win64 call can clobber %ymm8 yet preserve %xmm8. | 
| Jakob Stoklund Olesen | 13dffcb | 2012-06-15 22:24:22 +0000 | [diff] [blame] | 161 | return !RegMaskUsable.empty() && (!PhysReg || !RegMaskUsable.test(PhysReg)); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 162 | } | 
|  | 163 |  | 
|  | 164 | bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg, | 
|  | 165 | unsigned PhysReg) { | 
|  | 166 | if (VirtReg.empty()) | 
|  | 167 | return false; | 
| Jakob Stoklund Olesen | 866908c | 2012-09-06 18:15:23 +0000 | [diff] [blame] | 168 | CoalescerPair CP(VirtReg.reg, PhysReg, *TRI); | 
| Matthias Braun | 587e274 | 2014-12-10 01:13:01 +0000 | [diff] [blame] | 169 |  | 
|  | 170 | bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit, | 
|  | 171 | const LiveRange &Range) { | 
|  | 172 | const LiveRange &UnitRange = LIS->getRegUnit(Unit); | 
|  | 173 | return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes()); | 
|  | 174 | }); | 
|  | 175 | return Result; | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 176 | } | 
|  | 177 |  | 
| Matthias Braun | dbcf9e2 | 2017-03-02 00:35:08 +0000 | [diff] [blame] | 178 | LiveIntervalUnion::Query &LiveRegMatrix::query(const LiveRange &LR, | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 179 | unsigned RegUnit) { | 
|  | 180 | LiveIntervalUnion::Query &Q = Queries[RegUnit]; | 
| Matthias Braun | dbcf9e2 | 2017-03-02 00:35:08 +0000 | [diff] [blame] | 181 | Q.init(UserTag, LR, Matrix[RegUnit]); | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 182 | return Q; | 
|  | 183 | } | 
|  | 184 |  | 
|  | 185 | LiveRegMatrix::InterferenceKind | 
|  | 186 | LiveRegMatrix::checkInterference(LiveInterval &VirtReg, unsigned PhysReg) { | 
|  | 187 | if (VirtReg.empty()) | 
|  | 188 | return IK_Free; | 
|  | 189 |  | 
|  | 190 | // Regmask interference is the fastest check. | 
|  | 191 | if (checkRegMaskInterference(VirtReg, PhysReg)) | 
|  | 192 | return IK_RegMask; | 
|  | 193 |  | 
|  | 194 | // Check for fixed interference. | 
|  | 195 | if (checkRegUnitInterference(VirtReg, PhysReg)) | 
|  | 196 | return IK_RegUnit; | 
|  | 197 |  | 
|  | 198 | // Check the matrix for virtual register interference. | 
| Matthias Braun | dbcf9e2 | 2017-03-02 00:35:08 +0000 | [diff] [blame] | 199 | bool Interference = foreachUnit(TRI, VirtReg, PhysReg, | 
|  | 200 | [&](unsigned Unit, const LiveRange &LR) { | 
|  | 201 | return query(LR, Unit).checkInterference(); | 
|  | 202 | }); | 
|  | 203 | if (Interference) | 
|  | 204 | return IK_VirtReg; | 
| Jakob Stoklund Olesen | c26fbbf | 2012-06-09 02:13:10 +0000 | [diff] [blame] | 205 |  | 
|  | 206 | return IK_Free; | 
|  | 207 | } | 
| Marina Yatsina | cd5bc4a | 2018-01-31 13:31:08 +0000 | [diff] [blame] | 208 |  | 
|  | 209 | bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End, | 
|  | 210 | unsigned PhysReg) { | 
|  | 211 | // Construct artificial live range containing only one segment [Start, End). | 
|  | 212 | VNInfo valno(0, Start); | 
|  | 213 | LiveRange::Segment Seg(Start, End, &valno); | 
|  | 214 | LiveRange LR; | 
|  | 215 | LR.addSegment(Seg); | 
|  | 216 |  | 
|  | 217 | // Check for interference with that segment | 
|  | 218 | for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) { | 
|  | 219 | if (query(LR, *Units).checkInterference()) | 
|  | 220 | return true; | 
|  | 221 | } | 
|  | 222 | return false; | 
|  | 223 | } |