| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 1 | //===--- LivePhysRegs.cpp - Live Physical Register Set --------------------===// | 
|  | 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 | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 | // | 
|  | 9 | // This file implements the LivePhysRegs utility for tracking liveness of | 
|  | 10 | // physical registers across machine instructions in forward or backward order. | 
|  | 11 | // A more detailed description can be found in the corresponding header file. | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
|  | 15 | #include "llvm/CodeGen/LivePhysRegs.h" | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
|  | 17 | #include "llvm/CodeGen/MachineFunction.h" | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/MachineInstrBundle.h" | 
| Matthias Braun | 332bb5c | 2016-07-06 21:31:27 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
| Nico Weber | 432a388 | 2018-04-30 14:59:11 +0000 | [diff] [blame] | 20 | #include "llvm/Config/llvm-config.h" | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 21 | #include "llvm/Support/Debug.h" | 
| Benjamin Kramer | de9f090 | 2015-03-23 18:23:08 +0000 | [diff] [blame] | 22 | #include "llvm/Support/raw_ostream.h" | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 23 | using namespace llvm; | 
|  | 24 |  | 
|  | 25 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 26 | /// Remove all registers from the set that get clobbered by the register | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 27 | /// mask. | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 28 | /// The clobbers set will be the list of live registers clobbered | 
|  | 29 | /// by the regmask. | 
|  | 30 | void LivePhysRegs::removeRegsInMask(const MachineOperand &MO, | 
| Matthias Braun | c661387 | 2018-11-06 19:00:11 +0000 | [diff] [blame] | 31 | SmallVectorImpl<std::pair<MCPhysReg, const MachineOperand*>> *Clobbers) { | 
|  | 32 | RegisterSet::iterator LRI = LiveRegs.begin(); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 33 | while (LRI != LiveRegs.end()) { | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 34 | if (MO.clobbersPhysReg(*LRI)) { | 
|  | 35 | if (Clobbers) | 
|  | 36 | Clobbers->push_back(std::make_pair(*LRI, &MO)); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 37 | LRI = LiveRegs.erase(LRI); | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 38 | } else | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 39 | ++LRI; | 
|  | 40 | } | 
|  | 41 | } | 
|  | 42 |  | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 43 | /// Remove defined registers and regmask kills from the set. | 
|  | 44 | void LivePhysRegs::removeDefs(const MachineInstr &MI) { | 
| Duncan P. N. Exon Smith | f9ab416 | 2016-02-27 17:05:33 +0000 | [diff] [blame] | 45 | for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 46 | if (O->isReg()) { | 
| Matt Davis | 4b54e5f | 2018-03-19 16:06:40 +0000 | [diff] [blame] | 47 | if (!O->isDef() || O->isDebug()) | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 48 | continue; | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 49 | Register Reg = O->getReg(); | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 50 | if (!Register::isPhysicalRegister(Reg)) | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 51 | continue; | 
|  | 52 | removeReg(Reg); | 
|  | 53 | } else if (O->isRegMask()) | 
| Matthias Braun | 61cf1a9 | 2017-05-26 21:50:51 +0000 | [diff] [blame] | 54 | removeRegsInMask(*O); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 55 | } | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 56 | } | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 57 |  | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 58 | /// Add uses to the set. | 
|  | 59 | void LivePhysRegs::addUses(const MachineInstr &MI) { | 
| Duncan P. N. Exon Smith | f9ab416 | 2016-02-27 17:05:33 +0000 | [diff] [blame] | 60 | for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { | 
| Matt Davis | 4b54e5f | 2018-03-19 16:06:40 +0000 | [diff] [blame] | 61 | if (!O->isReg() || !O->readsReg() || O->isDebug()) | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 62 | continue; | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 63 | Register Reg = O->getReg(); | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 64 | if (!Register::isPhysicalRegister(Reg)) | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 65 | continue; | 
|  | 66 | addReg(Reg); | 
|  | 67 | } | 
|  | 68 | } | 
|  | 69 |  | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 70 | /// Simulates liveness when stepping backwards over an instruction(bundle): | 
|  | 71 | /// Remove Defs, add uses. This is the recommended way of calculating liveness. | 
|  | 72 | void LivePhysRegs::stepBackward(const MachineInstr &MI) { | 
|  | 73 | // Remove defined registers and regmask kills from the set. | 
|  | 74 | removeDefs(MI); | 
|  | 75 |  | 
|  | 76 | // Add uses to the set. | 
|  | 77 | addUses(MI); | 
|  | 78 | } | 
|  | 79 |  | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 80 | /// Simulates liveness when stepping forward over an instruction(bundle): Remove | 
|  | 81 | /// killed-uses, add defs. This is the not recommended way, because it depends | 
| Chad Rosier | a67b2d0 | 2015-09-04 12:34:55 +0000 | [diff] [blame] | 82 | /// on accurate kill flags. If possible use stepBackward() instead of this | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 83 | /// function. | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 84 | void LivePhysRegs::stepForward(const MachineInstr &MI, | 
| Matthias Braun | c661387 | 2018-11-06 19:00:11 +0000 | [diff] [blame] | 85 | SmallVectorImpl<std::pair<MCPhysReg, const MachineOperand*>> &Clobbers) { | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 86 | // Remove killed registers from the set. | 
| Duncan P. N. Exon Smith | f9ab416 | 2016-02-27 17:05:33 +0000 | [diff] [blame] | 87 | for (ConstMIBundleOperands O(MI); O.isValid(); ++O) { | 
| Matt Davis | 4b54e5f | 2018-03-19 16:06:40 +0000 | [diff] [blame] | 88 | if (O->isReg() && !O->isDebug()) { | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 89 | Register Reg = O->getReg(); | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 90 | if (!Register::isPhysicalRegister(Reg)) | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 91 | continue; | 
|  | 92 | if (O->isDef()) { | 
| Pete Cooper | 2748391 | 2015-05-06 22:51:04 +0000 | [diff] [blame] | 93 | // Note, dead defs are still recorded.  The caller should decide how to | 
|  | 94 | // handle them. | 
|  | 95 | Clobbers.push_back(std::make_pair(Reg, &*O)); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 96 | } else { | 
|  | 97 | if (!O->isKill()) | 
|  | 98 | continue; | 
|  | 99 | assert(O->isUse()); | 
|  | 100 | removeReg(Reg); | 
|  | 101 | } | 
|  | 102 | } else if (O->isRegMask()) | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 103 | removeRegsInMask(*O, &Clobbers); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 104 | } | 
|  | 105 |  | 
|  | 106 | // Add defs to the set. | 
| Pete Cooper | 2748391 | 2015-05-06 22:51:04 +0000 | [diff] [blame] | 107 | for (auto Reg : Clobbers) { | 
| Krzysztof Parzyszek | 1cf329c | 2018-04-30 19:38:47 +0000 | [diff] [blame] | 108 | // Skip dead defs and registers clobbered by regmasks. They shouldn't | 
|  | 109 | // be added to the set. | 
| Pete Cooper | 2748391 | 2015-05-06 22:51:04 +0000 | [diff] [blame] | 110 | if (Reg.second->isReg() && Reg.second->isDead()) | 
|  | 111 | continue; | 
| Krzysztof Parzyszek | 1cf329c | 2018-04-30 19:38:47 +0000 | [diff] [blame] | 112 | if (Reg.second->isRegMask() && | 
|  | 113 | MachineOperand::clobbersPhysReg(Reg.second->getRegMask(), Reg.first)) | 
|  | 114 | continue; | 
| Pete Cooper | 7605e37 | 2015-05-05 20:14:22 +0000 | [diff] [blame] | 115 | addReg(Reg.first); | 
| Pete Cooper | 2748391 | 2015-05-06 22:51:04 +0000 | [diff] [blame] | 116 | } | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 117 | } | 
|  | 118 |  | 
|  | 119 | /// Prin the currently live registers to OS. | 
|  | 120 | void LivePhysRegs::print(raw_ostream &OS) const { | 
|  | 121 | OS << "Live Registers:"; | 
|  | 122 | if (!TRI) { | 
|  | 123 | OS << " (uninitialized)\n"; | 
|  | 124 | return; | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | if (empty()) { | 
|  | 128 | OS << " (empty)\n"; | 
|  | 129 | return; | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | for (const_iterator I = begin(), E = end(); I != E; ++I) | 
| Francis Visoiu Mistrih | 9d419d3 | 2017-11-28 12:42:37 +0000 | [diff] [blame] | 133 | OS << " " << printReg(*I, TRI); | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 134 | OS << "\n"; | 
|  | 135 | } | 
|  | 136 |  | 
| Aaron Ballman | 615eb47 | 2017-10-15 14:32:27 +0000 | [diff] [blame] | 137 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | 
| Matthias Braun | 8c209aa | 2017-01-28 02:02:38 +0000 | [diff] [blame] | 138 | LLVM_DUMP_METHOD void LivePhysRegs::dump() const { | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 139 | dbgs() << "  " << *this; | 
| Juergen Ributzka | 310034e | 2013-12-14 06:52:56 +0000 | [diff] [blame] | 140 | } | 
| Matthias Braun | 8c209aa | 2017-01-28 02:02:38 +0000 | [diff] [blame] | 141 | #endif | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 142 |  | 
| Matthias Braun | 332bb5c | 2016-07-06 21:31:27 +0000 | [diff] [blame] | 143 | bool LivePhysRegs::available(const MachineRegisterInfo &MRI, | 
| Matthias Braun | c661387 | 2018-11-06 19:00:11 +0000 | [diff] [blame] | 144 | MCPhysReg Reg) const { | 
| Matthias Braun | 332bb5c | 2016-07-06 21:31:27 +0000 | [diff] [blame] | 145 | if (LiveRegs.count(Reg)) | 
|  | 146 | return false; | 
|  | 147 | if (MRI.isReserved(Reg)) | 
|  | 148 | return false; | 
|  | 149 | for (MCRegAliasIterator R(Reg, TRI, false); R.isValid(); ++R) { | 
|  | 150 | if (LiveRegs.count(*R)) | 
|  | 151 | return false; | 
|  | 152 | } | 
|  | 153 | return true; | 
|  | 154 | } | 
|  | 155 |  | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 156 | /// Add live-in registers of basic block \p MBB to \p LiveRegs. | 
| Krzysztof Parzyszek | abc0662 | 2016-10-12 22:53:41 +0000 | [diff] [blame] | 157 | void LivePhysRegs::addBlockLiveIns(const MachineBasicBlock &MBB) { | 
|  | 158 | for (const auto &LI : MBB.liveins()) { | 
| Matthias Braun | c661387 | 2018-11-06 19:00:11 +0000 | [diff] [blame] | 159 | MCPhysReg Reg = LI.PhysReg; | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 160 | LaneBitmask Mask = LI.LaneMask; | 
|  | 161 | MCSubRegIndexIterator S(Reg, TRI); | 
|  | 162 | assert(Mask.any() && "Invalid livein mask"); | 
|  | 163 | if (Mask.all() || !S.isValid()) { | 
|  | 164 | addReg(Reg); | 
| Krzysztof Parzyszek | abc0662 | 2016-10-12 22:53:41 +0000 | [diff] [blame] | 165 | continue; | 
|  | 166 | } | 
| Krzysztof Parzyszek | 91b5cf8 | 2016-12-15 14:36:06 +0000 | [diff] [blame] | 167 | for (; S.isValid(); ++S) { | 
|  | 168 | unsigned SI = S.getSubRegIndex(); | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 169 | if ((Mask & TRI->getSubRegIndexLaneMask(SI)).any()) | 
| Krzysztof Parzyszek | abc0662 | 2016-10-12 22:53:41 +0000 | [diff] [blame] | 170 | addReg(S.getSubReg()); | 
| Krzysztof Parzyszek | 91b5cf8 | 2016-12-15 14:36:06 +0000 | [diff] [blame] | 171 | } | 
| Krzysztof Parzyszek | abc0662 | 2016-10-12 22:53:41 +0000 | [diff] [blame] | 172 | } | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 173 | } | 
|  | 174 |  | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 175 | /// Adds all callee saved registers to \p LiveRegs. | 
|  | 176 | static void addCalleeSavedRegs(LivePhysRegs &LiveRegs, | 
|  | 177 | const MachineFunction &MF) { | 
| Oren Ben Simhon | fe34c5e | 2017-03-14 09:09:26 +0000 | [diff] [blame] | 178 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 179 | for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR; ++CSR) | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 180 | LiveRegs.addReg(*CSR); | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 181 | } | 
|  | 182 |  | 
| Krzysztof Parzyszek | f78eca8 | 2017-09-08 16:29:50 +0000 | [diff] [blame] | 183 | void LivePhysRegs::addPristines(const MachineFunction &MF) { | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 184 | const MachineFrameInfo &MFI = MF.getFrameInfo(); | 
|  | 185 | if (!MFI.isCalleeSavedInfoValid()) | 
|  | 186 | return; | 
| Krzysztof Parzyszek | f78eca8 | 2017-09-08 16:29:50 +0000 | [diff] [blame] | 187 | /// This function will usually be called on an empty object, handle this | 
|  | 188 | /// as a special case. | 
|  | 189 | if (empty()) { | 
|  | 190 | /// Add all callee saved regs, then remove the ones that are saved and | 
|  | 191 | /// restored. | 
|  | 192 | addCalleeSavedRegs(*this, MF); | 
|  | 193 | /// Remove the ones that are not saved/restored; they are pristine. | 
|  | 194 | for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) | 
|  | 195 | removeReg(Info.getReg()); | 
|  | 196 | return; | 
|  | 197 | } | 
|  | 198 | /// If a callee-saved register that is not pristine is already present | 
|  | 199 | /// in the set, we should make sure that it stays in it. Precompute the | 
|  | 200 | /// set of pristine registers in a separate object. | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 201 | /// Add all callee saved regs, then remove the ones that are saved+restored. | 
| Krzysztof Parzyszek | f78eca8 | 2017-09-08 16:29:50 +0000 | [diff] [blame] | 202 | LivePhysRegs Pristine(*TRI); | 
|  | 203 | addCalleeSavedRegs(Pristine, MF); | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 204 | /// Remove the ones that are not saved/restored; they are pristine. | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 205 | for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) | 
| Krzysztof Parzyszek | f78eca8 | 2017-09-08 16:29:50 +0000 | [diff] [blame] | 206 | Pristine.removeReg(Info.getReg()); | 
|  | 207 | for (MCPhysReg R : Pristine) | 
|  | 208 | addReg(R); | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 209 | } | 
|  | 210 |  | 
| Matthias Braun | d1aabb2 | 2016-05-03 00:24:32 +0000 | [diff] [blame] | 211 | void LivePhysRegs::addLiveOutsNoPristines(const MachineBasicBlock &MBB) { | 
| Eli Friedman | 98f8bba | 2018-02-06 23:00:17 +0000 | [diff] [blame] | 212 | // To get the live-outs we simply merge the live-ins of all successors. | 
|  | 213 | for (const MachineBasicBlock *Succ : MBB.successors()) | 
|  | 214 | addBlockLiveIns(*Succ); | 
|  | 215 | if (MBB.isReturnBlock()) { | 
|  | 216 | // Return blocks are a special case because we currently don't mark up | 
|  | 217 | // return instructions completely: specifically, there is no explicit | 
|  | 218 | // use for callee-saved registers. So we add all callee saved registers | 
|  | 219 | // that are saved and restored (somewhere). This does not include | 
|  | 220 | // callee saved registers that are unused and hence not saved and | 
|  | 221 | // restored; they are called pristine. | 
|  | 222 | // FIXME: PEI should add explicit markings to return instructions | 
|  | 223 | // instead of implicitly handling them here. | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 224 | const MachineFunction &MF = *MBB.getParent(); | 
|  | 225 | const MachineFrameInfo &MFI = MF.getFrameInfo(); | 
|  | 226 | if (MFI.isCalleeSavedInfoValid()) { | 
|  | 227 | for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) | 
| Krzysztof Parzyszek | bea30c6 | 2017-08-10 16:17:32 +0000 | [diff] [blame] | 228 | if (Info.isRestored()) | 
|  | 229 | addReg(Info.getReg()); | 
| Matthias Braun | eec1f36 | 2017-05-26 16:23:08 +0000 | [diff] [blame] | 230 | } | 
|  | 231 | } | 
| Matthias Braun | 24f26e6 | 2016-05-03 00:08:46 +0000 | [diff] [blame] | 232 | } | 
|  | 233 |  | 
| Matthias Braun | d1aabb2 | 2016-05-03 00:24:32 +0000 | [diff] [blame] | 234 | void LivePhysRegs::addLiveOuts(const MachineBasicBlock &MBB) { | 
| Matthias Braun | 4e8624d | 2017-06-03 00:26:35 +0000 | [diff] [blame] | 235 | const MachineFunction &MF = *MBB.getParent(); | 
| Eli Friedman | 98f8bba | 2018-02-06 23:00:17 +0000 | [diff] [blame] | 236 | addPristines(MF); | 
|  | 237 | addLiveOutsNoPristines(MBB); | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 238 | } | 
|  | 239 |  | 
| Matthias Braun | d1aabb2 | 2016-05-03 00:24:32 +0000 | [diff] [blame] | 240 | void LivePhysRegs::addLiveIns(const MachineBasicBlock &MBB) { | 
|  | 241 | const MachineFunction &MF = *MBB.getParent(); | 
| Krzysztof Parzyszek | f78eca8 | 2017-09-08 16:29:50 +0000 | [diff] [blame] | 242 | addPristines(MF); | 
| Krzysztof Parzyszek | abc0662 | 2016-10-12 22:53:41 +0000 | [diff] [blame] | 243 | addBlockLiveIns(MBB); | 
| Matthias Braun | e1cd96b | 2015-07-01 17:17:17 +0000 | [diff] [blame] | 244 | } | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 245 |  | 
| Matthias Braun | e51c435 | 2017-05-26 06:32:31 +0000 | [diff] [blame] | 246 | void llvm::computeLiveIns(LivePhysRegs &LiveRegs, | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 247 | const MachineBasicBlock &MBB) { | 
|  | 248 | const MachineFunction &MF = *MBB.getParent(); | 
|  | 249 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
| Matthias Braun | e51c435 | 2017-05-26 06:32:31 +0000 | [diff] [blame] | 250 | const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 251 | LiveRegs.init(TRI); | 
|  | 252 | LiveRegs.addLiveOutsNoPristines(MBB); | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 253 | for (const MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 254 | LiveRegs.stepBackward(MI); | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 255 | } | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 256 |  | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 257 | void llvm::addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs) { | 
|  | 258 | assert(MBB.livein_empty() && "Expected empty live-in list"); | 
|  | 259 | const MachineFunction &MF = *MBB.getParent(); | 
|  | 260 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
|  | 261 | const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); | 
|  | 262 | for (MCPhysReg Reg : LiveRegs) { | 
| Matthias Braun | e51c435 | 2017-05-26 06:32:31 +0000 | [diff] [blame] | 263 | if (MRI.isReserved(Reg)) | 
|  | 264 | continue; | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 265 | // Skip the register if we are about to add one of its super registers. | 
|  | 266 | bool ContainsSuperReg = false; | 
|  | 267 | for (MCSuperRegIterator SReg(Reg, &TRI); SReg.isValid(); ++SReg) { | 
| Matthias Braun | e51c435 | 2017-05-26 06:32:31 +0000 | [diff] [blame] | 268 | if (LiveRegs.contains(*SReg) && !MRI.isReserved(*SReg)) { | 
| Matthias Braun | 1819830 | 2016-12-16 23:55:37 +0000 | [diff] [blame] | 269 | ContainsSuperReg = true; | 
|  | 270 | break; | 
|  | 271 | } | 
|  | 272 | } | 
|  | 273 | if (ContainsSuperReg) | 
|  | 274 | continue; | 
|  | 275 | MBB.addLiveIn(Reg); | 
|  | 276 | } | 
|  | 277 | } | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 278 |  | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 279 | void llvm::recomputeLivenessFlags(MachineBasicBlock &MBB) { | 
|  | 280 | const MachineFunction &MF = *MBB.getParent(); | 
|  | 281 | const MachineRegisterInfo &MRI = MF.getRegInfo(); | 
|  | 282 | const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); | 
|  | 283 |  | 
|  | 284 | // We walk through the block backwards and start with the live outs. | 
|  | 285 | LivePhysRegs LiveRegs; | 
|  | 286 | LiveRegs.init(TRI); | 
|  | 287 | LiveRegs.addLiveOutsNoPristines(MBB); | 
|  | 288 |  | 
|  | 289 | for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) { | 
|  | 290 | // Recompute dead flags. | 
|  | 291 | for (MIBundleOperands MO(MI); MO.isValid(); ++MO) { | 
|  | 292 | if (!MO->isReg() || !MO->isDef() || MO->isDebug()) | 
|  | 293 | continue; | 
|  | 294 |  | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 295 | Register Reg = MO->getReg(); | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 296 | if (Reg == 0) | 
|  | 297 | continue; | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 298 | assert(Register::isPhysicalRegister(Reg)); | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 299 |  | 
|  | 300 | bool IsNotLive = LiveRegs.available(MRI, Reg); | 
|  | 301 | MO->setIsDead(IsNotLive); | 
|  | 302 | } | 
|  | 303 |  | 
|  | 304 | // Step backward over defs. | 
|  | 305 | LiveRegs.removeDefs(MI); | 
|  | 306 |  | 
|  | 307 | // Recompute kill flags. | 
|  | 308 | for (MIBundleOperands MO(MI); MO.isValid(); ++MO) { | 
|  | 309 | if (!MO->isReg() || !MO->readsReg() || MO->isDebug()) | 
|  | 310 | continue; | 
|  | 311 |  | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 312 | Register Reg = MO->getReg(); | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 313 | if (Reg == 0) | 
|  | 314 | continue; | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 315 | assert(Register::isPhysicalRegister(Reg)); | 
| Krzysztof Parzyszek | 6ca02b2 | 2017-09-14 15:53:11 +0000 | [diff] [blame] | 316 |  | 
|  | 317 | bool IsNotLive = LiveRegs.available(MRI, Reg); | 
|  | 318 | MO->setIsKill(IsNotLive); | 
|  | 319 | } | 
|  | 320 |  | 
|  | 321 | // Complete the stepbackward. | 
|  | 322 | LiveRegs.addUses(MI); | 
|  | 323 | } | 
|  | 324 | } | 
|  | 325 |  | 
| Matthias Braun | c9056b8 | 2017-09-06 20:45:24 +0000 | [diff] [blame] | 326 | void llvm::computeAndAddLiveIns(LivePhysRegs &LiveRegs, | 
|  | 327 | MachineBasicBlock &MBB) { | 
|  | 328 | computeLiveIns(LiveRegs, MBB); | 
|  | 329 | addLiveIns(MBB, LiveRegs); | 
|  | 330 | } |