1//===--- 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}
115