| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 1 | //===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===// | 
|  | 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 is an extremely simple MachineInstr-level copy propagation pass. | 
|  | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/Passes.h" | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 15 | #include "llvm/ADT/DenseMap.h" | 
|  | 16 | #include "llvm/ADT/SetVector.h" | 
|  | 17 | #include "llvm/ADT/SmallVector.h" | 
|  | 18 | #include "llvm/ADT/Statistic.h" | 
| Chandler Carruth | ed0881b | 2012-12-03 16:50:05 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/MachineFunction.h" | 
|  | 20 | #include "llvm/CodeGen/MachineFunctionPass.h" | 
|  | 21 | #include "llvm/CodeGen/MachineRegisterInfo.h" | 
|  | 22 | #include "llvm/Pass.h" | 
|  | 23 | #include "llvm/Support/Debug.h" | 
|  | 24 | #include "llvm/Support/ErrorHandling.h" | 
|  | 25 | #include "llvm/Support/raw_ostream.h" | 
|  | 26 | #include "llvm/Target/TargetInstrInfo.h" | 
|  | 27 | #include "llvm/Target/TargetRegisterInfo.h" | 
| Eric Christopher | d913448 | 2014-08-04 21:25:23 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetSubtargetInfo.h" | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 29 | using namespace llvm; | 
|  | 30 |  | 
| Chandler Carruth | 1b9dde0 | 2014-04-22 02:02:50 +0000 | [diff] [blame] | 31 | #define DEBUG_TYPE "codegen-cp" | 
|  | 32 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 33 | STATISTIC(NumDeletes, "Number of dead copies deleted"); | 
|  | 34 |  | 
|  | 35 | namespace { | 
|  | 36 | class MachineCopyPropagation : public MachineFunctionPass { | 
|  | 37 | const TargetRegisterInfo *TRI; | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 38 | const TargetInstrInfo *TII; | 
| Jakob Stoklund Olesen | c30a9af | 2012-10-15 21:57:41 +0000 | [diff] [blame] | 39 | MachineRegisterInfo *MRI; | 
| Andrew Trick | 9e76199 | 2012-02-08 21:22:43 +0000 | [diff] [blame] | 40 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 41 | public: | 
|  | 42 | static char ID; // Pass identification, replacement for typeid | 
|  | 43 | MachineCopyPropagation() : MachineFunctionPass(ID) { | 
|  | 44 | initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry()); | 
|  | 45 | } | 
|  | 46 |  | 
| Craig Topper | 4584cd5 | 2014-03-07 09:26:03 +0000 | [diff] [blame] | 47 | bool runOnMachineFunction(MachineFunction &MF) override; | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 48 |  | 
|  | 49 | private: | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 50 | typedef SmallVector<unsigned, 4> DestList; | 
|  | 51 | typedef DenseMap<unsigned, DestList> SourceMap; | 
|  | 52 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 53 | void SourceNoLongerAvailable(unsigned Reg, | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 54 | SourceMap &SrcMap, | 
|  | 55 | DenseMap<unsigned, MachineInstr*> &AvailCopyMap); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 56 | bool CopyPropagateBlock(MachineBasicBlock &MBB); | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 57 | void removeCopy(MachineInstr *MI); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 58 | }; | 
|  | 59 | } | 
|  | 60 | char MachineCopyPropagation::ID = 0; | 
| Andrew Trick | 1fa5bcb | 2012-02-08 21:23:13 +0000 | [diff] [blame] | 61 | char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 62 |  | 
|  | 63 | INITIALIZE_PASS(MachineCopyPropagation, "machine-cp", | 
|  | 64 | "Machine Copy Propagation Pass", false, false) | 
|  | 65 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 66 | void | 
|  | 67 | MachineCopyPropagation::SourceNoLongerAvailable(unsigned Reg, | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 68 | SourceMap &SrcMap, | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 69 | DenseMap<unsigned, MachineInstr*> &AvailCopyMap) { | 
| Jakob Stoklund Olesen | 92a0083 | 2012-06-01 20:36:54 +0000 | [diff] [blame] | 70 | for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { | 
|  | 71 | SourceMap::iterator SI = SrcMap.find(*AI); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 72 | if (SI != SrcMap.end()) { | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 73 | const DestList& Defs = SI->second; | 
|  | 74 | for (DestList::const_iterator I = Defs.begin(), E = Defs.end(); | 
| Lang Hames | 551662b | 2012-03-27 00:44:47 +0000 | [diff] [blame] | 75 | I != E; ++I) { | 
|  | 76 | unsigned MappedDef = *I; | 
| Jakob Stoklund Olesen | 92a0083 | 2012-06-01 20:36:54 +0000 | [diff] [blame] | 77 | // Source of copy is no longer available for propagation. | 
| Hao Liu | 0418324 | 2015-03-13 05:15:23 +0000 | [diff] [blame] | 78 | AvailCopyMap.erase(MappedDef); | 
|  | 79 | for (MCSubRegIterator SR(MappedDef, TRI); SR.isValid(); ++SR) | 
|  | 80 | AvailCopyMap.erase(*SR); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 81 | } | 
|  | 82 | } | 
|  | 83 | } | 
|  | 84 | } | 
|  | 85 |  | 
| Evan Cheng | 520730f | 2012-01-08 19:52:28 +0000 | [diff] [blame] | 86 | static bool NoInterveningSideEffect(const MachineInstr *CopyMI, | 
|  | 87 | const MachineInstr *MI) { | 
|  | 88 | const MachineBasicBlock *MBB = CopyMI->getParent(); | 
|  | 89 | if (MI->getParent() != MBB) | 
|  | 90 | return false; | 
|  | 91 | MachineBasicBlock::const_iterator I = CopyMI; | 
|  | 92 | MachineBasicBlock::const_iterator E = MBB->end(); | 
|  | 93 | MachineBasicBlock::const_iterator E2 = MI; | 
|  | 94 |  | 
|  | 95 | ++I; | 
|  | 96 | while (I != E && I != E2) { | 
|  | 97 | if (I->hasUnmodeledSideEffects() || I->isCall() || | 
|  | 98 | I->isTerminator()) | 
|  | 99 | return false; | 
|  | 100 | ++I; | 
|  | 101 | } | 
|  | 102 | return true; | 
|  | 103 | } | 
|  | 104 |  | 
| Evan Cheng | 63618f9 | 2012-02-20 23:28:17 +0000 | [diff] [blame] | 105 | /// isNopCopy - Return true if the specified copy is really a nop. That is | 
|  | 106 | /// if the source of the copy is the same of the definition of the copy that | 
|  | 107 | /// supplied the source. If the source of the copy is a sub-register than it | 
|  | 108 | /// must check the sub-indices match. e.g. | 
|  | 109 | /// ecx = mov eax | 
|  | 110 | /// al  = mov cl | 
|  | 111 | /// But not | 
|  | 112 | /// ecx = mov eax | 
|  | 113 | /// al  = mov ch | 
|  | 114 | static bool isNopCopy(MachineInstr *CopyMI, unsigned Def, unsigned Src, | 
|  | 115 | const TargetRegisterInfo *TRI) { | 
|  | 116 | unsigned SrcSrc = CopyMI->getOperand(1).getReg(); | 
|  | 117 | if (Def == SrcSrc) | 
|  | 118 | return true; | 
|  | 119 | if (TRI->isSubRegister(SrcSrc, Def)) { | 
|  | 120 | unsigned SrcDef = CopyMI->getOperand(0).getReg(); | 
|  | 121 | unsigned SubIdx = TRI->getSubRegIndex(SrcSrc, Def); | 
|  | 122 | if (!SubIdx) | 
|  | 123 | return false; | 
|  | 124 | return SubIdx == TRI->getSubRegIndex(SrcDef, Src); | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 | return false; | 
|  | 128 | } | 
|  | 129 |  | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 130 | // Remove MI from the function because it has been determined it is dead. | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 131 | // Turn it into a noop KILL instruction as opposed to removing it to | 
|  | 132 | // maintain imp-use/imp-def chains. | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 133 | void MachineCopyPropagation::removeCopy(MachineInstr *MI) { | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 134 | MI->setDesc(TII->get(TargetOpcode::KILL)); | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 135 | } | 
|  | 136 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 137 | bool MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { | 
| Lang Hames | 551662b | 2012-03-27 00:44:47 +0000 | [diff] [blame] | 138 | SmallSetVector<MachineInstr*, 8> MaybeDeadCopies;  // Candidates for deletion | 
|  | 139 | DenseMap<unsigned, MachineInstr*> AvailCopyMap;    // Def -> available copies map | 
|  | 140 | DenseMap<unsigned, MachineInstr*> CopyMap;         // Def -> copies map | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 141 | SourceMap SrcMap; // Src -> Def map | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 142 |  | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 143 | DEBUG(dbgs() << "MCP: CopyPropagateBlock " << MBB.getName() << "\n"); | 
|  | 144 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 145 | bool Changed = false; | 
|  | 146 | for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) { | 
|  | 147 | MachineInstr *MI = &*I; | 
|  | 148 | ++I; | 
|  | 149 |  | 
|  | 150 | if (MI->isCopy()) { | 
|  | 151 | unsigned Def = MI->getOperand(0).getReg(); | 
|  | 152 | unsigned Src = MI->getOperand(1).getReg(); | 
|  | 153 |  | 
|  | 154 | if (TargetRegisterInfo::isVirtualRegister(Def) || | 
|  | 155 | TargetRegisterInfo::isVirtualRegister(Src)) | 
|  | 156 | report_fatal_error("MachineCopyPropagation should be run after" | 
|  | 157 | " register allocation!"); | 
|  | 158 |  | 
|  | 159 | DenseMap<unsigned, MachineInstr*>::iterator CI = AvailCopyMap.find(Src); | 
|  | 160 | if (CI != AvailCopyMap.end()) { | 
|  | 161 | MachineInstr *CopyMI = CI->second; | 
| Jakob Stoklund Olesen | c30a9af | 2012-10-15 21:57:41 +0000 | [diff] [blame] | 162 | if (!MRI->isReserved(Def) && | 
|  | 163 | (!MRI->isReserved(Src) || NoInterveningSideEffect(CopyMI, MI)) && | 
| Evan Cheng | 63618f9 | 2012-02-20 23:28:17 +0000 | [diff] [blame] | 164 | isNopCopy(CopyMI, Def, Src, TRI)) { | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 165 | // The two copies cancel out and the source of the first copy | 
|  | 166 | // hasn't been overridden, eliminate the second one. e.g. | 
|  | 167 | //  %ECX<def> = COPY %EAX<kill> | 
|  | 168 | //  ... nothing clobbered EAX. | 
|  | 169 | //  %EAX<def> = COPY %ECX | 
|  | 170 | // => | 
|  | 171 | //  %ECX<def> = COPY %EAX | 
| Evan Cheng | 520730f | 2012-01-08 19:52:28 +0000 | [diff] [blame] | 172 | // | 
|  | 173 | // Also avoid eliminating a copy from reserved registers unless the | 
|  | 174 | // definition is proven not clobbered. e.g. | 
|  | 175 | // %RSP<def> = COPY %RAX | 
|  | 176 | // CALL | 
|  | 177 | // %RAX<def> = COPY %RSP | 
| Jakob Stoklund Olesen | 8c139a5 | 2012-01-26 17:52:15 +0000 | [diff] [blame] | 178 |  | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 179 | DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; MI->dump()); | 
|  | 180 |  | 
| Jakob Stoklund Olesen | 8c139a5 | 2012-01-26 17:52:15 +0000 | [diff] [blame] | 181 | // Clear any kills of Def between CopyMI and MI. This extends the | 
|  | 182 | // live range. | 
|  | 183 | for (MachineBasicBlock::iterator I = CopyMI, E = MI; I != E; ++I) | 
|  | 184 | I->clearRegisterKills(Def, TRI); | 
|  | 185 |  | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 186 | removeCopy(MI); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 187 | Changed = true; | 
|  | 188 | ++NumDeletes; | 
|  | 189 | continue; | 
|  | 190 | } | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | // If Src is defined by a previous copy, it cannot be eliminated. | 
| Jakob Stoklund Olesen | 92a0083 | 2012-06-01 20:36:54 +0000 | [diff] [blame] | 194 | for (MCRegAliasIterator AI(Src, TRI, true); AI.isValid(); ++AI) { | 
|  | 195 | CI = CopyMap.find(*AI); | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 196 | if (CI != CopyMap.end()) { | 
|  | 197 | DEBUG(dbgs() << "MCP: Copy is no longer dead: "; CI->second->dump()); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 198 | MaybeDeadCopies.remove(CI->second); | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 199 | } | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 200 | } | 
|  | 201 |  | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 202 | DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump()); | 
|  | 203 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 204 | // Copy is now a candidate for deletion. | 
|  | 205 | MaybeDeadCopies.insert(MI); | 
|  | 206 |  | 
|  | 207 | // If 'Src' is previously source of another copy, then this earlier copy's | 
|  | 208 | // source is no longer available. e.g. | 
|  | 209 | // %xmm9<def> = copy %xmm2 | 
|  | 210 | // ... | 
|  | 211 | // %xmm2<def> = copy %xmm0 | 
|  | 212 | // ... | 
|  | 213 | // %xmm2<def> = copy %xmm9 | 
|  | 214 | SourceNoLongerAvailable(Def, SrcMap, AvailCopyMap); | 
|  | 215 |  | 
|  | 216 | // Remember Def is defined by the copy. | 
| Evan Cheng | ddeb9d1 | 2012-02-27 21:46:42 +0000 | [diff] [blame] | 217 | // ... Make sure to clear the def maps of aliases first. | 
| Jakob Stoklund Olesen | 54038d7 | 2012-06-01 23:28:30 +0000 | [diff] [blame] | 218 | for (MCRegAliasIterator AI(Def, TRI, false); AI.isValid(); ++AI) { | 
|  | 219 | CopyMap.erase(*AI); | 
|  | 220 | AvailCopyMap.erase(*AI); | 
| Evan Cheng | ddeb9d1 | 2012-02-27 21:46:42 +0000 | [diff] [blame] | 221 | } | 
| Chad Rosier | abdb1d6 | 2013-05-22 23:17:36 +0000 | [diff] [blame] | 222 | for (MCSubRegIterator SR(Def, TRI, /*IncludeSelf=*/true); SR.isValid(); | 
|  | 223 | ++SR) { | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 224 | CopyMap[*SR] = MI; | 
|  | 225 | AvailCopyMap[*SR] = MI; | 
|  | 226 | } | 
|  | 227 |  | 
|  | 228 | // Remember source that's copied to Def. Once it's clobbered, then | 
|  | 229 | // it's no longer available for copy propagation. | 
| Lang Hames | 5544bf1 | 2012-03-27 19:10:45 +0000 | [diff] [blame] | 230 | if (std::find(SrcMap[Src].begin(), SrcMap[Src].end(), Def) == | 
|  | 231 | SrcMap[Src].end()) { | 
|  | 232 | SrcMap[Src].push_back(Def); | 
|  | 233 | } | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 234 |  | 
|  | 235 | continue; | 
|  | 236 | } | 
|  | 237 |  | 
|  | 238 | // Not a copy. | 
|  | 239 | SmallVector<unsigned, 2> Defs; | 
| Jakob Stoklund Olesen | 938b4d2 | 2012-02-09 00:19:08 +0000 | [diff] [blame] | 240 | int RegMaskOpNum = -1; | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 241 | for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { | 
|  | 242 | MachineOperand &MO = MI->getOperand(i); | 
| Jakob Stoklund Olesen | 8610a59 | 2012-02-08 22:37:35 +0000 | [diff] [blame] | 243 | if (MO.isRegMask()) | 
| Jakob Stoklund Olesen | 938b4d2 | 2012-02-09 00:19:08 +0000 | [diff] [blame] | 244 | RegMaskOpNum = i; | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 245 | if (!MO.isReg()) | 
|  | 246 | continue; | 
|  | 247 | unsigned Reg = MO.getReg(); | 
|  | 248 | if (!Reg) | 
|  | 249 | continue; | 
|  | 250 |  | 
|  | 251 | if (TargetRegisterInfo::isVirtualRegister(Reg)) | 
|  | 252 | report_fatal_error("MachineCopyPropagation should be run after" | 
|  | 253 | " register allocation!"); | 
|  | 254 |  | 
| Quentin Colombet | 796d906 | 2015-04-23 21:17:39 +0000 | [diff] [blame] | 255 | // Treat undef use like defs. | 
|  | 256 | // The backends are allowed to do whatever they want with undef value | 
|  | 257 | // and we cannot be sure this register will not be rewritten to break | 
|  | 258 | // some false dependencies for the hardware for instance. | 
|  | 259 | if (MO.isDef() || MO.isUndef()) { | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 260 | Defs.push_back(Reg); | 
|  | 261 | continue; | 
|  | 262 | } | 
|  | 263 |  | 
|  | 264 | // If 'Reg' is defined by a copy, the copy is no longer a candidate | 
|  | 265 | // for elimination. | 
| Jakob Stoklund Olesen | 92a0083 | 2012-06-01 20:36:54 +0000 | [diff] [blame] | 266 | for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { | 
|  | 267 | DenseMap<unsigned, MachineInstr*>::iterator CI = CopyMap.find(*AI); | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 268 | if (CI != CopyMap.end()) { | 
|  | 269 | DEBUG(dbgs() << "MCP: Copy is used - not dead: "; CI->second->dump()); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 270 | MaybeDeadCopies.remove(CI->second); | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 271 | } | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 272 | } | 
|  | 273 | } | 
|  | 274 |  | 
| Jakob Stoklund Olesen | 8610a59 | 2012-02-08 22:37:35 +0000 | [diff] [blame] | 275 | // The instruction has a register mask operand which means that it clobbers | 
|  | 276 | // a large set of registers.  It is possible to use the register mask to | 
|  | 277 | // prune the available copies, but treat it like a basic block boundary for | 
|  | 278 | // now. | 
| Jakob Stoklund Olesen | 938b4d2 | 2012-02-09 00:19:08 +0000 | [diff] [blame] | 279 | if (RegMaskOpNum >= 0) { | 
|  | 280 | // Erase any MaybeDeadCopies whose destination register is clobbered. | 
|  | 281 | const MachineOperand &MaskMO = MI->getOperand(RegMaskOpNum); | 
|  | 282 | for (SmallSetVector<MachineInstr*, 8>::iterator | 
|  | 283 | DI = MaybeDeadCopies.begin(), DE = MaybeDeadCopies.end(); | 
|  | 284 | DI != DE; ++DI) { | 
|  | 285 | unsigned Reg = (*DI)->getOperand(0).getReg(); | 
| Jakob Stoklund Olesen | c30a9af | 2012-10-15 21:57:41 +0000 | [diff] [blame] | 286 | if (MRI->isReserved(Reg) || !MaskMO.clobbersPhysReg(Reg)) | 
| Jakob Stoklund Olesen | 938b4d2 | 2012-02-09 00:19:08 +0000 | [diff] [blame] | 287 | continue; | 
| James Molloy | d787d3e | 2014-01-22 09:12:27 +0000 | [diff] [blame] | 288 | DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: "; | 
|  | 289 | (*DI)->dump()); | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 290 | removeCopy(*DI); | 
| Jakob Stoklund Olesen | 938b4d2 | 2012-02-09 00:19:08 +0000 | [diff] [blame] | 291 | Changed = true; | 
|  | 292 | ++NumDeletes; | 
|  | 293 | } | 
|  | 294 |  | 
|  | 295 | // Clear all data structures as if we were beginning a new basic block. | 
| Jakob Stoklund Olesen | 8610a59 | 2012-02-08 22:37:35 +0000 | [diff] [blame] | 296 | MaybeDeadCopies.clear(); | 
|  | 297 | AvailCopyMap.clear(); | 
|  | 298 | CopyMap.clear(); | 
|  | 299 | SrcMap.clear(); | 
|  | 300 | continue; | 
|  | 301 | } | 
|  | 302 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 303 | for (unsigned i = 0, e = Defs.size(); i != e; ++i) { | 
|  | 304 | unsigned Reg = Defs[i]; | 
|  | 305 |  | 
|  | 306 | // No longer defined by a copy. | 
| Jakob Stoklund Olesen | 92a0083 | 2012-06-01 20:36:54 +0000 | [diff] [blame] | 307 | for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { | 
|  | 308 | CopyMap.erase(*AI); | 
|  | 309 | AvailCopyMap.erase(*AI); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 310 | } | 
|  | 311 |  | 
|  | 312 | // If 'Reg' is previously source of a copy, it is no longer available for | 
|  | 313 | // copy propagation. | 
|  | 314 | SourceNoLongerAvailable(Reg, SrcMap, AvailCopyMap); | 
|  | 315 | } | 
|  | 316 | } | 
|  | 317 |  | 
|  | 318 | // If MBB doesn't have successors, delete the copies whose defs are not used. | 
|  | 319 | // If MBB does have successors, then conservative assume the defs are live-out | 
|  | 320 | // since we don't want to trust live-in lists. | 
|  | 321 | if (MBB.succ_empty()) { | 
|  | 322 | for (SmallSetVector<MachineInstr*, 8>::iterator | 
|  | 323 | DI = MaybeDeadCopies.begin(), DE = MaybeDeadCopies.end(); | 
|  | 324 | DI != DE; ++DI) { | 
| Jakob Stoklund Olesen | c30a9af | 2012-10-15 21:57:41 +0000 | [diff] [blame] | 325 | if (!MRI->isReserved((*DI)->getOperand(0).getReg())) { | 
| Jakob Stoklund Olesen | bb1e983 | 2012-11-30 23:53:00 +0000 | [diff] [blame] | 326 | removeCopy(*DI); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 327 | Changed = true; | 
|  | 328 | ++NumDeletes; | 
|  | 329 | } | 
|  | 330 | } | 
|  | 331 | } | 
|  | 332 |  | 
|  | 333 | return Changed; | 
|  | 334 | } | 
|  | 335 |  | 
|  | 336 | bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) { | 
| Paul Robinson | 7c99ec5 | 2014-03-31 17:43:35 +0000 | [diff] [blame] | 337 | if (skipOptnoneFunction(*MF.getFunction())) | 
|  | 338 | return false; | 
|  | 339 |  | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 340 | bool Changed = false; | 
|  | 341 |  | 
| Eric Christopher | fc6de42 | 2014-08-05 02:39:49 +0000 | [diff] [blame] | 342 | TRI = MF.getSubtarget().getRegisterInfo(); | 
|  | 343 | TII = MF.getSubtarget().getInstrInfo(); | 
| Jakob Stoklund Olesen | c30a9af | 2012-10-15 21:57:41 +0000 | [diff] [blame] | 344 | MRI = &MF.getRegInfo(); | 
| Evan Cheng | 00b1a3c | 2012-01-07 03:02:36 +0000 | [diff] [blame] | 345 |  | 
|  | 346 | for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) | 
|  | 347 | Changed |= CopyPropagateBlock(*I); | 
|  | 348 |  | 
|  | 349 | return Changed; | 
|  | 350 | } |