blob: 32e266e9401ef4bd21e7edb403ddda8e724db2e5 [file] [log] [blame]
Evan Cheng7fae11b2011-12-14 02:11:42 +00001//===-- lib/CodeGen/MachineInstrBundle.cpp --------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Evan Cheng7fae11b2011-12-14 02:11:42 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/CodeGen/MachineInstrBundle.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000010#include "llvm/ADT/SmallSet.h"
11#include "llvm/ADT/SmallVector.h"
12#include "llvm/CodeGen/MachineFunctionPass.h"
Evan Cheng7fae11b2011-12-14 02:11:42 +000013#include "llvm/CodeGen/MachineInstrBuilder.h"
14#include "llvm/CodeGen/Passes.h"
David Blaikie3f833ed2017-11-08 01:01:31 +000015#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000016#include "llvm/CodeGen/TargetRegisterInfo.h"
17#include "llvm/CodeGen/TargetSubtargetInfo.h"
Evan Cheng7fae11b2011-12-14 02:11:42 +000018#include "llvm/Target/TargetMachine.h"
Benjamin Kramer82de7d32016-05-27 14:27:24 +000019#include <utility>
Evan Cheng7fae11b2011-12-14 02:11:42 +000020using namespace llvm;
21
22namespace {
23 class UnpackMachineBundles : public MachineFunctionPass {
24 public:
25 static char ID; // Pass identification
Matthias Braun8b38ffa2016-10-24 23:23:02 +000026 UnpackMachineBundles(
27 std::function<bool(const MachineFunction &)> Ftor = nullptr)
Benjamin Kramer82de7d32016-05-27 14:27:24 +000028 : MachineFunctionPass(ID), PredicateFtor(std::move(Ftor)) {
Evan Cheng7fae11b2011-12-14 02:11:42 +000029 initializeUnpackMachineBundlesPass(*PassRegistry::getPassRegistry());
30 }
31
Craig Topper4584cd52014-03-07 09:26:03 +000032 bool runOnMachineFunction(MachineFunction &MF) override;
Akira Hatanaka4a616192015-06-08 18:50:43 +000033
34 private:
Matthias Braun8b38ffa2016-10-24 23:23:02 +000035 std::function<bool(const MachineFunction &)> PredicateFtor;
Evan Cheng7fae11b2011-12-14 02:11:42 +000036 };
37} // end anonymous namespace
38
39char UnpackMachineBundles::ID = 0;
Andrew Trick1fa5bcb2012-02-08 21:23:13 +000040char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID;
Evan Chengc2679b22012-01-19 07:47:03 +000041INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles",
Evan Cheng7fae11b2011-12-14 02:11:42 +000042 "Unpack machine instruction bundles", false, false)
43
Evan Cheng7fae11b2011-12-14 02:11:42 +000044bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) {
Matthias Braun8b38ffa2016-10-24 23:23:02 +000045 if (PredicateFtor && !PredicateFtor(MF))
Akira Hatanaka4a616192015-06-08 18:50:43 +000046 return false;
47
Evan Cheng7fae11b2011-12-14 02:11:42 +000048 bool Changed = false;
49 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
50 MachineBasicBlock *MBB = &*I;
51
52 for (MachineBasicBlock::instr_iterator MII = MBB->instr_begin(),
53 MIE = MBB->instr_end(); MII != MIE; ) {
54 MachineInstr *MI = &*MII;
55
56 // Remove BUNDLE instruction and the InsideBundle flags from bundled
57 // instructions.
58 if (MI->isBundle()) {
Jakob Stoklund Olesen7bb2f972012-12-13 23:23:46 +000059 while (++MII != MIE && MII->isBundledWithPred()) {
60 MII->unbundleFromPred();
Evan Cheng7fae11b2011-12-14 02:11:42 +000061 for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
62 MachineOperand &MO = MII->getOperand(i);
63 if (MO.isReg() && MO.isInternalRead())
64 MO.setIsInternalRead(false);
65 }
66 }
67 MI->eraseFromParent();
68
69 Changed = true;
70 continue;
71 }
72
73 ++MII;
74 }
75 }
76
77 return Changed;
78}
79
Akira Hatanaka4a616192015-06-08 18:50:43 +000080FunctionPass *
Matthias Braun8b38ffa2016-10-24 23:23:02 +000081llvm::createUnpackMachineBundles(
82 std::function<bool(const MachineFunction &)> Ftor) {
Benjamin Kramerd3f4c052016-06-12 16:13:55 +000083 return new UnpackMachineBundles(std::move(Ftor));
Akira Hatanaka4a616192015-06-08 18:50:43 +000084}
Evan Chengc2679b22012-01-19 07:47:03 +000085
86namespace {
87 class FinalizeMachineBundles : public MachineFunctionPass {
88 public:
89 static char ID; // Pass identification
90 FinalizeMachineBundles() : MachineFunctionPass(ID) {
91 initializeFinalizeMachineBundlesPass(*PassRegistry::getPassRegistry());
92 }
93
Craig Topper4584cd52014-03-07 09:26:03 +000094 bool runOnMachineFunction(MachineFunction &MF) override;
Evan Chengc2679b22012-01-19 07:47:03 +000095 };
96} // end anonymous namespace
97
98char FinalizeMachineBundles::ID = 0;
Andrew Trick1fa5bcb2012-02-08 21:23:13 +000099char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID;
Evan Chengc2679b22012-01-19 07:47:03 +0000100INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles",
101 "Finalize machine instruction bundles", false, false)
102
Evan Chengc2679b22012-01-19 07:47:03 +0000103bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) {
104 return llvm::finalizeBundles(MF);
105}
106
Bjorn Petterssond378a392018-08-21 10:59:50 +0000107/// Return the first found DebugLoc that has a DILocation, given a range of
108/// instructions. The search range is from FirstMI to LastMI (exclusive). If no
109/// DILocation is found, then an empty location is returned.
110static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI,
111 MachineBasicBlock::instr_iterator LastMI) {
112 for (auto MII = FirstMI; MII != LastMI; ++MII)
113 if (MII->getDebugLoc().get())
114 return MII->getDebugLoc();
115 return DebugLoc();
116}
Evan Chengc2679b22012-01-19 07:47:03 +0000117
Evan Cheng1eb2bb22012-01-19 00:06:10 +0000118/// finalizeBundle - Finalize a machine instruction bundle which includes
Evan Cheng28794672012-01-19 00:46:06 +0000119/// a sequence of instructions starting from FirstMI to LastMI (exclusive).
Evan Cheng7fae11b2011-12-14 02:11:42 +0000120/// This routine adds a BUNDLE instruction to represent the bundle, it adds
121/// IsInternalRead markers to MachineOperands which are defined inside the
122/// bundle, and it copies externally visible defs and uses to the BUNDLE
123/// instruction.
Evan Cheng1eb2bb22012-01-19 00:06:10 +0000124void llvm::finalizeBundle(MachineBasicBlock &MBB,
Evan Cheng7fae11b2011-12-14 02:11:42 +0000125 MachineBasicBlock::instr_iterator FirstMI,
126 MachineBasicBlock::instr_iterator LastMI) {
Evan Cheng28794672012-01-19 00:46:06 +0000127 assert(FirstMI != LastMI && "Empty bundle?");
Jakob Stoklund Olesen7bb2f972012-12-13 23:23:46 +0000128 MIBundleBuilder Bundle(MBB, FirstMI, LastMI);
Evan Cheng28794672012-01-19 00:46:06 +0000129
Eric Christopher20c98932014-10-14 06:26:55 +0000130 MachineFunction &MF = *MBB.getParent();
131 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
132 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
Evan Cheng7fae11b2011-12-14 02:11:42 +0000133
Eric Christopher20c98932014-10-14 06:26:55 +0000134 MachineInstrBuilder MIB =
Bjorn Petterssond378a392018-08-21 10:59:50 +0000135 BuildMI(MF, getDebugLoc(FirstMI, LastMI), TII->get(TargetOpcode::BUNDLE));
Jakob Stoklund Olesen7bb2f972012-12-13 23:23:46 +0000136 Bundle.prepend(MIB);
Evan Cheng7fae11b2011-12-14 02:11:42 +0000137
Michael Ilseman4f0e00a2012-09-17 18:31:15 +0000138 SmallVector<unsigned, 32> LocalDefs;
139 SmallSet<unsigned, 32> LocalDefSet;
Evan Cheng7fae11b2011-12-14 02:11:42 +0000140 SmallSet<unsigned, 8> DeadDefSet;
Michael Ilseman4f0e00a2012-09-17 18:31:15 +0000141 SmallSet<unsigned, 16> KilledDefSet;
Evan Cheng7fae11b2011-12-14 02:11:42 +0000142 SmallVector<unsigned, 8> ExternUses;
143 SmallSet<unsigned, 8> ExternUseSet;
144 SmallSet<unsigned, 8> KilledUseSet;
145 SmallSet<unsigned, 8> UndefUseSet;
146 SmallVector<MachineOperand*, 4> Defs;
Bjorn Pettersson7ded6a92018-08-25 11:26:17 +0000147 for (auto MII = FirstMI; MII != LastMI; ++MII) {
148 for (unsigned i = 0, e = MII->getNumOperands(); i != e; ++i) {
149 MachineOperand &MO = MII->getOperand(i);
Evan Cheng7fae11b2011-12-14 02:11:42 +0000150 if (!MO.isReg())
151 continue;
152 if (MO.isDef()) {
153 Defs.push_back(&MO);
154 continue;
155 }
156
157 unsigned Reg = MO.getReg();
158 if (!Reg)
159 continue;
160 assert(TargetRegisterInfo::isPhysicalRegister(Reg));
161 if (LocalDefSet.count(Reg)) {
162 MO.setIsInternalRead();
163 if (MO.isKill())
164 // Internal def is now killed.
165 KilledDefSet.insert(Reg);
166 } else {
David Blaikie70573dc2014-11-19 07:49:26 +0000167 if (ExternUseSet.insert(Reg).second) {
Evan Cheng7fae11b2011-12-14 02:11:42 +0000168 ExternUses.push_back(Reg);
169 if (MO.isUndef())
170 UndefUseSet.insert(Reg);
171 }
172 if (MO.isKill())
173 // External def is now killed.
174 KilledUseSet.insert(Reg);
175 }
176 }
177
178 for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
179 MachineOperand &MO = *Defs[i];
180 unsigned Reg = MO.getReg();
181 if (!Reg)
182 continue;
183
David Blaikie70573dc2014-11-19 07:49:26 +0000184 if (LocalDefSet.insert(Reg).second) {
Evan Cheng7fae11b2011-12-14 02:11:42 +0000185 LocalDefs.push_back(Reg);
186 if (MO.isDead()) {
187 DeadDefSet.insert(Reg);
188 }
189 } else {
190 // Re-defined inside the bundle, it's no longer killed.
191 KilledDefSet.erase(Reg);
192 if (!MO.isDead())
193 // Previously defined but dead.
194 DeadDefSet.erase(Reg);
195 }
196
197 if (!MO.isDead()) {
Jakob Stoklund Olesen54038d72012-06-01 23:28:30 +0000198 for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
199 unsigned SubReg = *SubRegs;
David Blaikie70573dc2014-11-19 07:49:26 +0000200 if (LocalDefSet.insert(SubReg).second)
Evan Cheng7fae11b2011-12-14 02:11:42 +0000201 LocalDefs.push_back(SubReg);
202 }
203 }
204 }
205
Evan Cheng7fae11b2011-12-14 02:11:42 +0000206 Defs.clear();
Evan Cheng28794672012-01-19 00:46:06 +0000207 }
Evan Cheng7fae11b2011-12-14 02:11:42 +0000208
Michael Ilseman4f0e00a2012-09-17 18:31:15 +0000209 SmallSet<unsigned, 32> Added;
Evan Cheng7fae11b2011-12-14 02:11:42 +0000210 for (unsigned i = 0, e = LocalDefs.size(); i != e; ++i) {
211 unsigned Reg = LocalDefs[i];
David Blaikie70573dc2014-11-19 07:49:26 +0000212 if (Added.insert(Reg).second) {
Evan Cheng7fae11b2011-12-14 02:11:42 +0000213 // If it's not live beyond end of the bundle, mark it dead.
214 bool isDead = DeadDefSet.count(Reg) || KilledDefSet.count(Reg);
215 MIB.addReg(Reg, getDefRegState(true) | getDeadRegState(isDead) |
216 getImplRegState(true));
217 }
218 }
219
220 for (unsigned i = 0, e = ExternUses.size(); i != e; ++i) {
221 unsigned Reg = ExternUses[i];
222 bool isKill = KilledUseSet.count(Reg);
223 bool isUndef = UndefUseSet.count(Reg);
224 MIB.addReg(Reg, getKillRegState(isKill) | getUndefRegState(isUndef) |
225 getImplRegState(true));
226 }
Bjorn Pettersson7ded6a92018-08-25 11:26:17 +0000227
228 // Set FrameSetup/FrameDestroy for the bundle. If any of the instructions got
229 // the property, then also set it on the bundle.
230 for (auto MII = FirstMI; MII != LastMI; ++MII) {
231 if (MII->getFlag(MachineInstr::FrameSetup))
232 MIB.setMIFlag(MachineInstr::FrameSetup);
233 if (MII->getFlag(MachineInstr::FrameDestroy))
234 MIB.setMIFlag(MachineInstr::FrameDestroy);
235 }
Evan Cheng7fae11b2011-12-14 02:11:42 +0000236}
Evan Cheng28794672012-01-19 00:46:06 +0000237
238/// finalizeBundle - Same functionality as the previous finalizeBundle except
239/// the last instruction in the bundle is not provided as an input. This is
240/// used in cases where bundles are pre-determined by marking instructions
Evan Cheng6ca22722012-01-19 06:13:10 +0000241/// with 'InsideBundle' marker. It returns the MBB instruction iterator that
242/// points to the end of the bundle.
243MachineBasicBlock::instr_iterator
244llvm::finalizeBundle(MachineBasicBlock &MBB,
245 MachineBasicBlock::instr_iterator FirstMI) {
Evan Cheng28794672012-01-19 00:46:06 +0000246 MachineBasicBlock::instr_iterator E = MBB.instr_end();
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000247 MachineBasicBlock::instr_iterator LastMI = std::next(FirstMI);
Evan Cheng28794672012-01-19 00:46:06 +0000248 while (LastMI != E && LastMI->isInsideBundle())
249 ++LastMI;
250 finalizeBundle(MBB, FirstMI, LastMI);
Evan Cheng6ca22722012-01-19 06:13:10 +0000251 return LastMI;
Evan Cheng28794672012-01-19 00:46:06 +0000252}
Evan Chengc2679b22012-01-19 07:47:03 +0000253
254/// finalizeBundles - Finalize instruction bundles in the specified
255/// MachineFunction. Return true if any bundles are finalized.
256bool llvm::finalizeBundles(MachineFunction &MF) {
257 bool Changed = false;
258 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
259 MachineBasicBlock &MBB = *I;
Evan Chengc2679b22012-01-19 07:47:03 +0000260 MachineBasicBlock::instr_iterator MII = MBB.instr_begin();
Evan Chengc2679b22012-01-19 07:47:03 +0000261 MachineBasicBlock::instr_iterator MIE = MBB.instr_end();
Evan Cheng217a7042012-03-06 02:00:52 +0000262 if (MII == MIE)
263 continue;
Jakob Stoklund Olesen7f92b7a2013-01-04 22:17:31 +0000264 assert(!MII->isInsideBundle() &&
265 "First instr cannot be inside bundle before finalization!");
266
Evan Chengc2679b22012-01-19 07:47:03 +0000267 for (++MII; MII != MIE; ) {
268 if (!MII->isInsideBundle())
269 ++MII;
270 else {
Benjamin Kramerb6d0bd42014-03-02 12:27:27 +0000271 MII = finalizeBundle(MBB, std::prev(MII));
Evan Chengc2679b22012-01-19 07:47:03 +0000272 Changed = true;
273 }
274 }
275 }
276
277 return Changed;
278}
Jakob Stoklund Olesen9e8214562012-02-29 01:40:37 +0000279
280//===----------------------------------------------------------------------===//
281// MachineOperand iterator
282//===----------------------------------------------------------------------===//
283
James Molloy381fab92012-09-12 10:03:31 +0000284MachineOperandIteratorBase::VirtRegInfo
Jakob Stoklund Olesen9e8214562012-02-29 01:40:37 +0000285MachineOperandIteratorBase::analyzeVirtReg(unsigned Reg,
286 SmallVectorImpl<std::pair<MachineInstr*, unsigned> > *Ops) {
James Molloy381fab92012-09-12 10:03:31 +0000287 VirtRegInfo RI = { false, false, false };
Jakob Stoklund Olesen9e8214562012-02-29 01:40:37 +0000288 for(; isValid(); ++*this) {
289 MachineOperand &MO = deref();
290 if (!MO.isReg() || MO.getReg() != Reg)
291 continue;
292
293 // Remember each (MI, OpNo) that refers to Reg.
294 if (Ops)
295 Ops->push_back(std::make_pair(MO.getParent(), getOperandNo()));
296
297 // Both defs and uses can read virtual registers.
298 if (MO.readsReg()) {
299 RI.Reads = true;
300 if (MO.isDef())
301 RI.Tied = true;
302 }
303
304 // Only defs can write.
305 if (MO.isDef())
306 RI.Writes = true;
307 else if (!RI.Tied && MO.getParent()->isRegTiedToDefOperand(getOperandNo()))
308 RI.Tied = true;
309 }
310 return RI;
311}
James Molloy381fab92012-09-12 10:03:31 +0000312
313MachineOperandIteratorBase::PhysRegInfo
314MachineOperandIteratorBase::analyzePhysReg(unsigned Reg,
315 const TargetRegisterInfo *TRI) {
316 bool AllDefsDead = true;
Quentin Colombet3f192452016-04-26 23:14:24 +0000317 PhysRegInfo PRI = {false, false, false, false, false, false, false, false};
James Molloy381fab92012-09-12 10:03:31 +0000318
319 assert(TargetRegisterInfo::isPhysicalRegister(Reg) &&
320 "analyzePhysReg not given a physical register!");
321 for (; isValid(); ++*this) {
322 MachineOperand &MO = deref();
323
Matthias Braun60d69e22015-12-11 19:42:09 +0000324 if (MO.isRegMask() && MO.clobbersPhysReg(Reg)) {
325 PRI.Clobbered = true;
326 continue;
327 }
James Molloy381fab92012-09-12 10:03:31 +0000328
329 if (!MO.isReg())
330 continue;
331
332 unsigned MOReg = MO.getReg();
333 if (!MOReg || !TargetRegisterInfo::isPhysicalRegister(MOReg))
334 continue;
335
Matthias Braun60d69e22015-12-11 19:42:09 +0000336 if (!TRI->regsOverlap(MOReg, Reg))
James Molloy381fab92012-09-12 10:03:31 +0000337 continue;
338
Matthias Braun7e762e42016-01-05 00:45:35 +0000339 bool Covered = TRI->isSuperRegisterEq(Reg, MOReg);
Matthias Braun60d69e22015-12-11 19:42:09 +0000340 if (MO.readsReg()) {
341 PRI.Read = true;
342 if (Covered) {
343 PRI.FullyRead = true;
344 if (MO.isKill())
345 PRI.Killed = true;
346 }
347 } else if (MO.isDef()) {
348 PRI.Defined = true;
349 if (Covered)
350 PRI.FullyDefined = true;
James Molloy381fab92012-09-12 10:03:31 +0000351 if (!MO.isDead())
352 AllDefsDead = false;
353 }
James Molloy381fab92012-09-12 10:03:31 +0000354 }
355
Quentin Colombet3f192452016-04-26 23:14:24 +0000356 if (AllDefsDead) {
357 if (PRI.FullyDefined || PRI.Clobbered)
358 PRI.DeadDef = true;
Quentin Colombetddad5aa2016-04-27 00:16:29 +0000359 else if (PRI.Defined)
Quentin Colombet3f192452016-04-26 23:14:24 +0000360 PRI.PartialDeadDef = true;
361 }
James Molloy381fab92012-09-12 10:03:31 +0000362
363 return PRI;
364}