blob: 89567eff517933b601ee56cc5553fd4c80e5ecaf [file] [log] [blame]
Juergen Ributzka310034e2013-12-14 06:52:56 +00001//===--- LivePhysRegs.cpp - Live Physical Register Set --------------------===//
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 implements the LivePhysRegs utility for tracking liveness of
11// physical registers across machine instructions in forward or backward order.
12// A more detailed description can be found in the corresponding header file.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/CodeGen/LivePhysRegs.h"
17#include "llvm/CodeGen/MachineInstrBundle.h"
18#include "llvm/Support/Debug.h"
Benjamin Kramerde9f0902015-03-23 18:23:08 +000019#include "llvm/Support/raw_ostream.h"
Juergen Ributzka310034e2013-12-14 06:52:56 +000020using namespace llvm;
21
22
23/// \brief Remove all registers from the set that get clobbered by the register
24/// mask.
25void LivePhysRegs::removeRegsInMask(const MachineOperand &MO) {
26 SparseSet<unsigned>::iterator LRI = LiveRegs.begin();
27 while (LRI != LiveRegs.end()) {
28 if (MO.clobbersPhysReg(*LRI))
29 LRI = LiveRegs.erase(LRI);
30 else
31 ++LRI;
32 }
33}
34
35/// Simulates liveness when stepping backwards over an instruction(bundle):
36/// Remove Defs, add uses. This is the recommended way of calculating liveness.
37void LivePhysRegs::stepBackward(const MachineInstr &MI) {
38 // Remove defined registers and regmask kills from the set.
39 for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
40 if (O->isReg()) {
41 if (!O->isDef())
42 continue;
43 unsigned Reg = O->getReg();
44 if (Reg == 0)
45 continue;
46 removeReg(Reg);
47 } else if (O->isRegMask())
48 removeRegsInMask(*O);
49 }
50
51 // Add uses to the set.
52 for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
53 if (!O->isReg() || !O->readsReg() || O->isUndef())
54 continue;
55 unsigned Reg = O->getReg();
56 if (Reg == 0)
57 continue;
58 addReg(Reg);
59 }
60}
61
62/// Simulates liveness when stepping forward over an instruction(bundle): Remove
63/// killed-uses, add defs. This is the not recommended way, because it depends
64/// on accurate kill flags. If possible use stepBackwards() instead of this
65/// function.
66void LivePhysRegs::stepForward(const MachineInstr &MI) {
67 SmallVector<unsigned, 4> Defs;
68 // Remove killed registers from the set.
69 for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
70 if (O->isReg()) {
71 unsigned Reg = O->getReg();
72 if (Reg == 0)
73 continue;
74 if (O->isDef()) {
75 if (!O->isDead())
76 Defs.push_back(Reg);
77 } else {
78 if (!O->isKill())
79 continue;
80 assert(O->isUse());
81 removeReg(Reg);
82 }
83 } else if (O->isRegMask())
84 removeRegsInMask(*O);
85 }
86
87 // Add defs to the set.
88 for (unsigned i = 0, e = Defs.size(); i != e; ++i)
89 addReg(Defs[i]);
90}
91
92/// Prin the currently live registers to OS.
93void LivePhysRegs::print(raw_ostream &OS) const {
94 OS << "Live Registers:";
95 if (!TRI) {
96 OS << " (uninitialized)\n";
97 return;
98 }
99
100 if (empty()) {
101 OS << " (empty)\n";
102 return;
103 }
104
105 for (const_iterator I = begin(), E = end(); I != E; ++I)
106 OS << " " << PrintReg(*I, TRI);
107 OS << "\n";
108}
109
110/// Dumps the currently live registers to the debug output.
111void LivePhysRegs::dump() const {
112#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
113 dbgs() << " " << *this;
114#endif
115}