[SEH] Implement GetExceptionCode in __except blocks
[oota-llvm.git] / lib / CodeGen / LivePhysRegs.cpp
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"
19 #include "llvm/Support/raw_ostream.h"
20 using namespace llvm;
21
22
23 /// \brief Remove all registers from the set that get clobbered by the register
24 /// mask.
25 void 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.
37 void 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.
66 void 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.
93 void 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.
111 void LivePhysRegs::dump() const {
112 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
113   dbgs() << "  " << *this;
114 #endif
115 }