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. removeRegsInMask(const MachineOperand & MO)25void 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. stepBackward(const MachineInstr & MI)37void 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. stepForward(const MachineInstr & MI)66void 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. print(raw_ostream & OS) const93void 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. dump() const111void LivePhysRegs::dump() const { 112 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 113 dbgs() << " " << *this; 114 #endif 115 } 116