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