Convert liveness tracking to work on a sub-register level instead of just register...
[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 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/LivePhysRegs.h"
16 #include "llvm/CodeGen/MachineInstrBundle.h"
17 using namespace llvm;
18
19
20 /// We assume the high bits of a physical super-register are not preserved
21 /// unless the instruction has an implicit-use operand reading the
22 /// super-register.
23
24 /// \brief Remove all registers from the set that get clobbered by the register
25 /// mask.
26 void LivePhysRegs::removeRegsInMask(const MachineOperand &MO) {
27   SparseSet<unsigned>::iterator LRI = LiveRegs.begin();
28   while (LRI != LiveRegs.end()) {
29     if (MO.clobbersPhysReg(*LRI))
30       LRI = LiveRegs.erase(LRI);
31     else
32       ++LRI;
33   }
34 }
35
36 /// Simulates liveness when stepping backwards over an instruction(bundle):
37 /// Remove Defs, add uses. This is the recommended way of calculating liveness.
38 void LivePhysRegs::stepBackward(const MachineInstr &MI) {
39   // Remove defined registers and regmask kills from the set.
40   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
41     if (O->isReg()) {
42       if (!O->isDef())
43         continue;
44       unsigned Reg = O->getReg();
45       if (Reg == 0)
46         continue;
47       removeReg(Reg);
48     } else if (O->isRegMask())
49       removeRegsInMask(*O);
50   }
51
52   // Add uses to the set.
53   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
54     if (!O->isReg() || !O->readsReg() || O->isUndef())
55       continue;
56     unsigned Reg = O->getReg();
57     if (Reg == 0)
58       continue;
59     addReg(Reg);
60   }
61 }
62
63 /// Simulates liveness when stepping forward over an instruction(bundle): Remove
64 /// killed-uses, add defs. This is the not recommended way, because it depends
65 /// on accurate kill flags. If possible use stepBackwards() instead of this
66 /// function.
67 void LivePhysRegs::stepForward(const MachineInstr &MI) {
68   SmallVector<unsigned, 4> Defs;
69   // Remove killed registers from the set.
70   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
71     if (O->isReg()) {
72       unsigned Reg = O->getReg();
73       if (Reg == 0)
74         continue;
75       if (O->isDef()) {
76         if (!O->isDead())
77           Defs.push_back(Reg);
78       } else {
79         if (!O->isKill())
80           continue;
81         assert(O->isUse());
82         removeReg(Reg);
83       }
84     } else if (O->isRegMask())
85       removeRegsInMask(*O);
86   }
87
88   // Add defs to the set.
89   for (unsigned i = 0, e = Defs.size(); i != e; ++i)
90     addReg(Defs[i]);
91 }