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