| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 1 | //===---- ReachingDefAnalysis.cpp - Reaching Def Analysis ---*- C++ -*-----===// |
| 2 | // |
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 9 | #include "llvm/ADT/SmallSet.h" |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 10 | #include "llvm/CodeGen/LivePhysRegs.h" |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 11 | #include "llvm/CodeGen/ReachingDefAnalysis.h" |
| 12 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
| 13 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
| Reid Kleckner | 1d7b413 | 2019-10-19 00:22:07 +0000 | [diff] [blame] | 14 | #include "llvm/Support/Debug.h" |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 15 | |
| 16 | using namespace llvm; |
| 17 | |
| 18 | #define DEBUG_TYPE "reaching-deps-analysis" |
| 19 | |
| 20 | char ReachingDefAnalysis::ID = 0; |
| 21 | INITIALIZE_PASS(ReachingDefAnalysis, DEBUG_TYPE, "ReachingDefAnalysis", false, |
| 22 | true) |
| 23 | |
| 24 | void ReachingDefAnalysis::enterBasicBlock( |
| 25 | const LoopTraversal::TraversedMBBInfo &TraversedMBB) { |
| 26 | |
| 27 | MachineBasicBlock *MBB = TraversedMBB.MBB; |
| Marina Yatsina | e4d63a4 | 2018-01-22 13:24:10 +0000 | [diff] [blame] | 28 | unsigned MBBNumber = MBB->getNumber(); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 29 | assert(MBBNumber < MBBReachingDefs.size() && |
| 30 | "Unexpected basic block number."); |
| 31 | MBBReachingDefs[MBBNumber].resize(NumRegUnits); |
| 32 | |
| 33 | // Reset instruction counter in each basic block. |
| 34 | CurInstr = 0; |
| 35 | |
| 36 | // Set up LiveRegs to represent registers entering MBB. |
| 37 | // Default values are 'nothing happened a long time ago'. |
| 38 | if (LiveRegs.empty()) |
| Craig Topper | 0f110a8 | 2018-03-20 20:53:21 +0000 | [diff] [blame] | 39 | LiveRegs.assign(NumRegUnits, ReachingDefDefaultVal); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 40 | |
| 41 | // This is the entry block. |
| 42 | if (MBB->pred_empty()) { |
| 43 | for (const auto &LI : MBB->liveins()) { |
| 44 | for (MCRegUnitIterator Unit(LI.PhysReg, TRI); Unit.isValid(); ++Unit) { |
| 45 | // Treat function live-ins as if they were defined just before the first |
| 46 | // instruction. Usually, function arguments are set up immediately |
| 47 | // before the call. |
| 48 | LiveRegs[*Unit] = -1; |
| 49 | MBBReachingDefs[MBBNumber][*Unit].push_back(LiveRegs[*Unit]); |
| 50 | } |
| 51 | } |
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 52 | LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << ": entry\n"); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 53 | return; |
| 54 | } |
| 55 | |
| 56 | // Try to coalesce live-out registers from predecessors. |
| 57 | for (MachineBasicBlock *pred : MBB->predecessors()) { |
| Marina Yatsina | e4d63a4 | 2018-01-22 13:24:10 +0000 | [diff] [blame] | 58 | assert(unsigned(pred->getNumber()) < MBBOutRegsInfos.size() && |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 59 | "Should have pre-allocated MBBInfos for all MBBs"); |
| 60 | const LiveRegsDefInfo &Incoming = MBBOutRegsInfos[pred->getNumber()]; |
| 61 | // Incoming is null if this is a backedge from a BB |
| 62 | // we haven't processed yet |
| 63 | if (Incoming.empty()) |
| 64 | continue; |
| 65 | |
| 66 | for (unsigned Unit = 0; Unit != NumRegUnits; ++Unit) { |
| 67 | // Use the most recent predecessor def for each register. |
| 68 | LiveRegs[Unit] = std::max(LiveRegs[Unit], Incoming[Unit]); |
| Craig Topper | 0f110a8 | 2018-03-20 20:53:21 +0000 | [diff] [blame] | 69 | if ((LiveRegs[Unit] != ReachingDefDefaultVal)) |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 70 | MBBReachingDefs[MBBNumber][Unit].push_back(LiveRegs[Unit]); |
| 71 | } |
| 72 | } |
| 73 | |
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 74 | LLVM_DEBUG(dbgs() << printMBBReference(*MBB) |
| 75 | << (!TraversedMBB.IsDone ? ": incomplete\n" |
| 76 | : ": all preds known\n")); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 77 | } |
| 78 | |
| 79 | void ReachingDefAnalysis::leaveBasicBlock( |
| 80 | const LoopTraversal::TraversedMBBInfo &TraversedMBB) { |
| 81 | assert(!LiveRegs.empty() && "Must enter basic block first."); |
| Marina Yatsina | e4d63a4 | 2018-01-22 13:24:10 +0000 | [diff] [blame] | 82 | unsigned MBBNumber = TraversedMBB.MBB->getNumber(); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 83 | assert(MBBNumber < MBBOutRegsInfos.size() && |
| 84 | "Unexpected basic block number."); |
| 85 | // Save register clearances at end of MBB - used by enterBasicBlock(). |
| 86 | MBBOutRegsInfos[MBBNumber] = LiveRegs; |
| 87 | |
| 88 | // While processing the basic block, we kept `Def` relative to the start |
| 89 | // of the basic block for convenience. However, future use of this information |
| 90 | // only cares about the clearance from the end of the block, so adjust |
| 91 | // everything to be relative to the end of the basic block. |
| 92 | for (int &OutLiveReg : MBBOutRegsInfos[MBBNumber]) |
| 93 | OutLiveReg -= CurInstr; |
| 94 | LiveRegs.clear(); |
| 95 | } |
| 96 | |
| 97 | void ReachingDefAnalysis::processDefs(MachineInstr *MI) { |
| Shiva Chen | 801bf7e | 2018-05-09 02:42:00 +0000 | [diff] [blame] | 98 | assert(!MI->isDebugInstr() && "Won't process debug instructions"); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 99 | |
| Marina Yatsina | e4d63a4 | 2018-01-22 13:24:10 +0000 | [diff] [blame] | 100 | unsigned MBBNumber = MI->getParent()->getNumber(); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 101 | assert(MBBNumber < MBBReachingDefs.size() && |
| 102 | "Unexpected basic block number."); |
| 103 | const MCInstrDesc &MCID = MI->getDesc(); |
| 104 | for (unsigned i = 0, |
| 105 | e = MI->isVariadic() ? MI->getNumOperands() : MCID.getNumDefs(); |
| 106 | i != e; ++i) { |
| 107 | MachineOperand &MO = MI->getOperand(i); |
| 108 | if (!MO.isReg() || !MO.getReg()) |
| 109 | continue; |
| 110 | if (MO.isUse()) |
| 111 | continue; |
| 112 | for (MCRegUnitIterator Unit(MO.getReg(), TRI); Unit.isValid(); ++Unit) { |
| 113 | // This instruction explicitly defines the current reg unit. |
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 114 | LLVM_DEBUG(dbgs() << printReg(MO.getReg(), TRI) << ":\t" << CurInstr |
| 115 | << '\t' << *MI); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 116 | |
| 117 | // How many instructions since this reg unit was last written? |
| 118 | LiveRegs[*Unit] = CurInstr; |
| 119 | MBBReachingDefs[MBBNumber][*Unit].push_back(CurInstr); |
| 120 | } |
| 121 | } |
| 122 | InstIds[MI] = CurInstr; |
| 123 | ++CurInstr; |
| 124 | } |
| 125 | |
| 126 | void ReachingDefAnalysis::processBasicBlock( |
| 127 | const LoopTraversal::TraversedMBBInfo &TraversedMBB) { |
| 128 | enterBasicBlock(TraversedMBB); |
| 129 | for (MachineInstr &MI : *TraversedMBB.MBB) { |
| Shiva Chen | 801bf7e | 2018-05-09 02:42:00 +0000 | [diff] [blame] | 130 | if (!MI.isDebugInstr()) |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 131 | processDefs(&MI); |
| 132 | } |
| 133 | leaveBasicBlock(TraversedMBB); |
| 134 | } |
| 135 | |
| 136 | bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) { |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 137 | MF = &mf; |
| 138 | TRI = MF->getSubtarget().getRegisterInfo(); |
| 139 | |
| 140 | LiveRegs.clear(); |
| 141 | NumRegUnits = TRI->getNumRegUnits(); |
| 142 | |
| 143 | MBBReachingDefs.resize(mf.getNumBlockIDs()); |
| 144 | |
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 145 | LLVM_DEBUG(dbgs() << "********** REACHING DEFINITION ANALYSIS **********\n"); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 146 | |
| 147 | // Initialize the MBBOutRegsInfos |
| 148 | MBBOutRegsInfos.resize(mf.getNumBlockIDs()); |
| 149 | |
| 150 | // Traverse the basic blocks. |
| 151 | LoopTraversal Traversal; |
| 152 | LoopTraversal::TraversalOrder TraversedMBBOrder = Traversal.traverse(mf); |
| 153 | for (LoopTraversal::TraversedMBBInfo TraversedMBB : TraversedMBBOrder) { |
| 154 | processBasicBlock(TraversedMBB); |
| 155 | } |
| 156 | |
| 157 | // Sorting all reaching defs found for a ceartin reg unit in a given BB. |
| 158 | for (MBBDefsInfo &MBBDefs : MBBReachingDefs) { |
| 159 | for (MBBRegUnitDefs &RegUnitDefs : MBBDefs) |
| Fangrui Song | 0cac726 | 2018-09-27 02:13:45 +0000 | [diff] [blame] | 160 | llvm::sort(RegUnitDefs); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | return false; |
| 164 | } |
| 165 | |
| 166 | void ReachingDefAnalysis::releaseMemory() { |
| 167 | // Clear the internal vectors. |
| 168 | MBBOutRegsInfos.clear(); |
| 169 | MBBReachingDefs.clear(); |
| 170 | InstIds.clear(); |
| 171 | } |
| 172 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 173 | int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, int PhysReg) const { |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 174 | assert(InstIds.count(MI) && "Unexpected machine instuction."); |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 175 | int InstId = InstIds.lookup(MI); |
| Craig Topper | 0f110a8 | 2018-03-20 20:53:21 +0000 | [diff] [blame] | 176 | int DefRes = ReachingDefDefaultVal; |
| Marina Yatsina | e4d63a4 | 2018-01-22 13:24:10 +0000 | [diff] [blame] | 177 | unsigned MBBNumber = MI->getParent()->getNumber(); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 178 | assert(MBBNumber < MBBReachingDefs.size() && |
| 179 | "Unexpected basic block number."); |
| Craig Topper | 0f110a8 | 2018-03-20 20:53:21 +0000 | [diff] [blame] | 180 | int LatestDef = ReachingDefDefaultVal; |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 181 | for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) { |
| 182 | for (int Def : MBBReachingDefs[MBBNumber][*Unit]) { |
| 183 | if (Def >= InstId) |
| 184 | break; |
| 185 | DefRes = Def; |
| 186 | } |
| 187 | LatestDef = std::max(LatestDef, DefRes); |
| 188 | } |
| 189 | return LatestDef; |
| 190 | } |
| 191 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 192 | MachineInstr* ReachingDefAnalysis::getReachingMIDef(MachineInstr *MI, |
| 193 | int PhysReg) const { |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 194 | return getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg)); |
| 195 | } |
| 196 | |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 197 | bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B, |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 198 | int PhysReg) const { |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 199 | MachineBasicBlock *ParentA = A->getParent(); |
| 200 | MachineBasicBlock *ParentB = B->getParent(); |
| 201 | if (ParentA != ParentB) |
| 202 | return false; |
| 203 | |
| 204 | return getReachingDef(A, PhysReg) == getReachingDef(B, PhysReg); |
| 205 | } |
| 206 | |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 207 | MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB, |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 208 | int InstId) const { |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 209 | assert(static_cast<size_t>(MBB->getNumber()) < MBBReachingDefs.size() && |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 210 | "Unexpected basic block number."); |
| 211 | assert(InstId < static_cast<int>(MBB->size()) && |
| 212 | "Unexpected instruction id."); |
| 213 | |
| 214 | if (InstId < 0) |
| 215 | return nullptr; |
| 216 | |
| 217 | for (auto &MI : *MBB) { |
| Sjoerd Meijer | 93b0536 | 2020-02-06 14:13:31 +0000 | [diff] [blame] | 218 | auto F = InstIds.find(&MI); |
| 219 | if (F != InstIds.end() && F->second == InstId) |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 220 | return &MI; |
| 221 | } |
| Sjoerd Meijer | 93b0536 | 2020-02-06 14:13:31 +0000 | [diff] [blame] | 222 | |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 223 | return nullptr; |
| 224 | } |
| 225 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 226 | int |
| 227 | ReachingDefAnalysis::getClearance(MachineInstr *MI, MCPhysReg PhysReg) const { |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 228 | assert(InstIds.count(MI) && "Unexpected machine instuction."); |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 229 | return InstIds.lookup(MI) - getReachingDef(MI, PhysReg); |
| Marina Yatsina | 0bf841a | 2018-01-22 10:06:50 +0000 | [diff] [blame] | 230 | } |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 231 | |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 232 | bool |
| 233 | ReachingDefAnalysis::hasLocalDefBefore(MachineInstr *MI, int PhysReg) const { |
| 234 | return getReachingDef(MI, PhysReg) >= 0; |
| 235 | } |
| 236 | |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 237 | void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, int PhysReg, |
| Sam Parker | 7ad879c | 2020-01-28 13:06:07 +0000 | [diff] [blame] | 238 | InstSet &Uses) const { |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 239 | MachineBasicBlock *MBB = Def->getParent(); |
| 240 | MachineBasicBlock::iterator MI = MachineBasicBlock::iterator(Def); |
| 241 | while (++MI != MBB->end()) { |
| Sam Parker | 0553257 | 2020-01-23 16:44:25 +0000 | [diff] [blame] | 242 | if (MI->isDebugInstr()) |
| 243 | continue; |
| 244 | |
| Sam Parker | acbc9ae | 2019-12-20 09:32:36 +0000 | [diff] [blame] | 245 | // If/when we find a new reaching def, we know that there's no more uses |
| 246 | // of 'Def'. |
| 247 | if (getReachingMIDef(&*MI, PhysReg) != Def) |
| 248 | return; |
| 249 | |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 250 | for (auto &MO : MI->operands()) { |
| 251 | if (!MO.isReg() || !MO.isUse() || MO.getReg() != PhysReg) |
| 252 | continue; |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 253 | |
| Sam Parker | 42350cd8 | 2020-01-17 13:08:24 +0000 | [diff] [blame] | 254 | Uses.insert(&*MI); |
| Sam Parker | 2816681 | 2019-11-26 10:25:04 +0000 | [diff] [blame] | 255 | if (MO.isKill()) |
| 256 | return; |
| 257 | } |
| 258 | } |
| 259 | } |
| 260 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 261 | bool |
| 262 | ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, int PhysReg, |
| Sam Parker | 7ad879c | 2020-01-28 13:06:07 +0000 | [diff] [blame] | 263 | InstSet &Uses) const { |
| Sam Parker | 42350cd8 | 2020-01-17 13:08:24 +0000 | [diff] [blame] | 264 | for (auto &MI : *MBB) { |
| Sam Parker | 0553257 | 2020-01-23 16:44:25 +0000 | [diff] [blame] | 265 | if (MI.isDebugInstr()) |
| 266 | continue; |
| Sam Parker | 42350cd8 | 2020-01-17 13:08:24 +0000 | [diff] [blame] | 267 | for (auto &MO : MI.operands()) { |
| 268 | if (!MO.isReg() || !MO.isUse() || MO.getReg() != PhysReg) |
| 269 | continue; |
| 270 | if (getReachingDef(&MI, PhysReg) >= 0) |
| 271 | return false; |
| 272 | Uses.insert(&MI); |
| 273 | } |
| 274 | } |
| 275 | return isReachingDefLiveOut(&MBB->back(), PhysReg); |
| 276 | } |
| 277 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 278 | void |
| 279 | ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, int PhysReg, |
| Sam Parker | 7ad879c | 2020-01-28 13:06:07 +0000 | [diff] [blame] | 280 | InstSet &Uses) const { |
| Sam Parker | 42350cd8 | 2020-01-17 13:08:24 +0000 | [diff] [blame] | 281 | MachineBasicBlock *MBB = MI->getParent(); |
| 282 | |
| 283 | // Collect the uses that each def touches within the block. |
| 284 | getReachingLocalUses(MI, PhysReg, Uses); |
| 285 | |
| 286 | // Handle live-out values. |
| 287 | if (auto *LiveOut = getLocalLiveOutMIDef(MI->getParent(), PhysReg)) { |
| 288 | if (LiveOut != MI) |
| 289 | return; |
| 290 | |
| 291 | SmallVector<MachineBasicBlock*, 4> ToVisit; |
| 292 | ToVisit.insert(ToVisit.begin(), MBB->successors().begin(), |
| 293 | MBB->successors().end()); |
| 294 | SmallPtrSet<MachineBasicBlock*, 4>Visited; |
| 295 | while (!ToVisit.empty()) { |
| 296 | MachineBasicBlock *MBB = ToVisit.back(); |
| 297 | ToVisit.pop_back(); |
| 298 | if (Visited.count(MBB) || !MBB->isLiveIn(PhysReg)) |
| 299 | continue; |
| 300 | if (getLiveInUses(MBB, PhysReg, Uses)) |
| 301 | ToVisit.insert(ToVisit.end(), MBB->successors().begin(), |
| 302 | MBB->successors().end()); |
| 303 | Visited.insert(MBB); |
| 304 | } |
| 305 | } |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 306 | } |
| 307 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 308 | bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, int PhysReg) const { |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 309 | MachineBasicBlock *MBB = MI->getParent(); |
| 310 | LivePhysRegs LiveRegs(*TRI); |
| 311 | LiveRegs.addLiveOuts(*MBB); |
| 312 | |
| 313 | // Yes if the register is live out of the basic block. |
| 314 | if (LiveRegs.contains(PhysReg)) |
| 315 | return true; |
| 316 | |
| 317 | // Walk backwards through the block to see if the register is live at some |
| 318 | // point. |
| 319 | for (auto Last = MBB->rbegin(), End = MBB->rend(); Last != End; ++Last) { |
| 320 | LiveRegs.stepBackward(*Last); |
| 321 | if (LiveRegs.contains(PhysReg)) |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 322 | return InstIds.lookup(&*Last) > InstIds.lookup(MI); |
| Sam Parker | cced971 | 2019-11-26 10:03:25 +0000 | [diff] [blame] | 323 | } |
| 324 | return false; |
| 325 | } |
| 326 | |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 327 | bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI, |
| 328 | int PhysReg) const { |
| 329 | MachineBasicBlock *MBB = MI->getParent(); |
| 330 | if (getReachingDef(MI, PhysReg) != getReachingDef(&MBB->back(), PhysReg)) |
| 331 | return true; |
| 332 | |
| 333 | if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg)) |
| 334 | return Def == getReachingMIDef(MI, PhysReg); |
| 335 | |
| 336 | return false; |
| 337 | } |
| 338 | |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 339 | bool |
| 340 | ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI, int PhysReg) const { |
| Sam Parker | acbc9ae | 2019-12-20 09:32:36 +0000 | [diff] [blame] | 341 | MachineBasicBlock *MBB = MI->getParent(); |
| 342 | LivePhysRegs LiveRegs(*TRI); |
| 343 | LiveRegs.addLiveOuts(*MBB); |
| 344 | if (!LiveRegs.contains(PhysReg)) |
| 345 | return false; |
| 346 | |
| 347 | MachineInstr *Last = &MBB->back(); |
| 348 | int Def = getReachingDef(MI, PhysReg); |
| 349 | if (getReachingDef(Last, PhysReg) != Def) |
| 350 | return false; |
| 351 | |
| 352 | // Finally check that the last instruction doesn't redefine the register. |
| 353 | for (auto &MO : Last->operands()) |
| 354 | if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) |
| 355 | return false; |
| 356 | |
| 357 | return true; |
| 358 | } |
| 359 | |
| 360 | MachineInstr* ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB, |
| Sam Parker | 0d1468d | 2020-01-23 13:22:13 +0000 | [diff] [blame] | 361 | int PhysReg) const { |
| Sam Parker | acbc9ae | 2019-12-20 09:32:36 +0000 | [diff] [blame] | 362 | LivePhysRegs LiveRegs(*TRI); |
| 363 | LiveRegs.addLiveOuts(*MBB); |
| 364 | if (!LiveRegs.contains(PhysReg)) |
| 365 | return nullptr; |
| 366 | |
| 367 | MachineInstr *Last = &MBB->back(); |
| 368 | int Def = getReachingDef(Last, PhysReg); |
| 369 | for (auto &MO : Last->operands()) |
| 370 | if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) |
| 371 | return Last; |
| 372 | |
| 373 | return Def < 0 ? nullptr : getInstFromId(MBB, Def); |
| 374 | } |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 375 | |
| Sam Parker | 0a8cae1 | 2020-02-06 13:53:09 +0000 | [diff] [blame] | 376 | static bool mayHaveSideEffects(MachineInstr &MI) { |
| 377 | return MI.mayLoadOrStore() || MI.mayRaiseFPException() || |
| 378 | MI.hasUnmodeledSideEffects() || MI.isTerminator() || |
| 379 | MI.isCall() || MI.isBarrier() || MI.isBranch() || MI.isReturn(); |
| 380 | } |
| 381 | |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 382 | // Can we safely move 'From' to just before 'To'? To satisfy this, 'From' must |
| 383 | // not define a register that is used by any instructions, after and including, |
| 384 | // 'To'. These instructions also must not redefine any of Froms operands. |
| 385 | template<typename Iterator> |
| 386 | bool ReachingDefAnalysis::isSafeToMove(MachineInstr *From, |
| 387 | MachineInstr *To) const { |
| 388 | if (From->getParent() != To->getParent()) |
| 389 | return false; |
| 390 | |
| 391 | SmallSet<int, 2> Defs; |
| 392 | // First check that From would compute the same value if moved. |
| 393 | for (auto &MO : From->operands()) { |
| 394 | if (!MO.isReg() || MO.isUndef() || !MO.getReg()) |
| 395 | continue; |
| 396 | if (MO.isDef()) |
| 397 | Defs.insert(MO.getReg()); |
| 398 | else if (!hasSameReachingDef(From, To, MO.getReg())) |
| 399 | return false; |
| 400 | } |
| 401 | |
| 402 | // Now walk checking that the rest of the instructions will compute the same |
| Sam Parker | 0a8cae1 | 2020-02-06 13:53:09 +0000 | [diff] [blame] | 403 | // value and that we're not overwriting anything. Don't move the instruction |
| 404 | // past any memory, control-flow or other ambigious instructions. |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 405 | for (auto I = ++Iterator(From), E = Iterator(To); I != E; ++I) { |
| Sam Parker | 0a8cae1 | 2020-02-06 13:53:09 +0000 | [diff] [blame] | 406 | if (mayHaveSideEffects(*I)) |
| 407 | return false; |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 408 | for (auto &MO : I->operands()) |
| Sam Parker | 0a8cae1 | 2020-02-06 13:53:09 +0000 | [diff] [blame] | 409 | if (MO.isReg() && MO.getReg() && Defs.count(MO.getReg())) |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 410 | return false; |
| 411 | } |
| 412 | return true; |
| 413 | } |
| 414 | |
| 415 | bool ReachingDefAnalysis::isSafeToMoveForwards(MachineInstr *From, |
| 416 | MachineInstr *To) const { |
| 417 | return isSafeToMove<MachineBasicBlock::reverse_iterator>(From, To); |
| 418 | } |
| 419 | |
| 420 | bool ReachingDefAnalysis::isSafeToMoveBackwards(MachineInstr *From, |
| 421 | MachineInstr *To) const { |
| 422 | return isSafeToMove<MachineBasicBlock::iterator>(From, To); |
| 423 | } |
| 424 | |
| 425 | bool ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, |
| 426 | InstSet &ToRemove) const { |
| 427 | SmallPtrSet<MachineInstr*, 1> Ignore; |
| 428 | SmallPtrSet<MachineInstr*, 2> Visited; |
| 429 | return isSafeToRemove(MI, Visited, ToRemove, Ignore); |
| 430 | } |
| 431 | |
| 432 | bool |
| 433 | ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &ToRemove, |
| 434 | InstSet &Ignore) const { |
| 435 | SmallPtrSet<MachineInstr*, 2> Visited; |
| 436 | return isSafeToRemove(MI, Visited, ToRemove, Ignore); |
| 437 | } |
| 438 | |
| 439 | bool |
| 440 | ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited, |
| 441 | InstSet &ToRemove, InstSet &Ignore) const { |
| 442 | if (Visited.count(MI) || Ignore.count(MI)) |
| 443 | return true; |
| Sam Parker | 0a8cae1 | 2020-02-06 13:53:09 +0000 | [diff] [blame] | 444 | else if (mayHaveSideEffects(*MI)) { |
| Sam Parker | ac30ea2 | 2020-01-29 03:26:11 -0500 | [diff] [blame] | 445 | // Unless told to ignore the instruction, don't remove anything which has |
| 446 | // side effects. |
| 447 | return false; |
| 448 | } |
| 449 | |
| 450 | Visited.insert(MI); |
| 451 | for (auto &MO : MI->operands()) { |
| 452 | if (!MO.isReg() || MO.isUse() || MO.getReg() == 0) |
| 453 | continue; |
| 454 | |
| 455 | SmallPtrSet<MachineInstr*, 4> Uses; |
| 456 | getGlobalUses(MI, MO.getReg(), Uses); |
| 457 | |
| 458 | for (auto I : Uses) { |
| 459 | if (Ignore.count(I) || ToRemove.count(I)) |
| 460 | continue; |
| 461 | if (!isSafeToRemove(I, Visited, ToRemove, Ignore)) |
| 462 | return false; |
| 463 | } |
| 464 | } |
| 465 | ToRemove.insert(MI); |
| 466 | return true; |
| 467 | } |
| 468 | |
| 469 | bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, |
| 470 | int PhysReg) const { |
| 471 | SmallPtrSet<MachineInstr*, 1> Ignore; |
| 472 | return isSafeToDefRegAt(MI, PhysReg, Ignore); |
| 473 | } |
| 474 | |
| 475 | bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, int PhysReg, |
| 476 | InstSet &Ignore) const { |
| 477 | // Check for any uses of the register after MI. |
| 478 | if (isRegUsedAfter(MI, PhysReg)) { |
| 479 | if (auto *Def = getReachingMIDef(MI, PhysReg)) { |
| 480 | SmallPtrSet<MachineInstr*, 2> Uses; |
| 481 | getReachingLocalUses(Def, PhysReg, Uses); |
| 482 | for (auto *Use : Uses) |
| 483 | if (!Ignore.count(Use)) |
| 484 | return false; |
| 485 | } else |
| 486 | return false; |
| 487 | } |
| 488 | |
| 489 | MachineBasicBlock *MBB = MI->getParent(); |
| 490 | // Check for any defs after MI. |
| 491 | if (isRegDefinedAfter(MI, PhysReg)) { |
| 492 | auto I = MachineBasicBlock::iterator(MI); |
| 493 | for (auto E = MBB->end(); I != E; ++I) { |
| 494 | if (Ignore.count(&*I)) |
| 495 | continue; |
| 496 | for (auto &MO : I->operands()) |
| 497 | if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) |
| 498 | return false; |
| 499 | } |
| 500 | } |
| 501 | return true; |
| 502 | } |