LLVM API Documentation

LivePhysRegs.cpp
Go to the documentation of this file.
00001 //===--- LivePhysRegs.cpp - Live Physical Register Set --------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the LivePhysRegs utility for tracking liveness of
00011 // physical registers across machine instructions in forward or backward order.
00012 // A more detailed description can be found in the corresponding header file.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #include "llvm/CodeGen/LivePhysRegs.h"
00017 #include "llvm/CodeGen/MachineInstrBundle.h"
00018 #include "llvm/Support/Debug.h"
00019 using namespace llvm;
00020 
00021 
00022 /// \brief Remove all registers from the set that get clobbered by the register
00023 /// mask.
00024 void LivePhysRegs::removeRegsInMask(const MachineOperand &MO) {
00025   SparseSet<unsigned>::iterator LRI = LiveRegs.begin();
00026   while (LRI != LiveRegs.end()) {
00027     if (MO.clobbersPhysReg(*LRI))
00028       LRI = LiveRegs.erase(LRI);
00029     else
00030       ++LRI;
00031   }
00032 }
00033 
00034 /// Simulates liveness when stepping backwards over an instruction(bundle):
00035 /// Remove Defs, add uses. This is the recommended way of calculating liveness.
00036 void LivePhysRegs::stepBackward(const MachineInstr &MI) {
00037   // Remove defined registers and regmask kills from the set.
00038   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
00039     if (O->isReg()) {
00040       if (!O->isDef())
00041         continue;
00042       unsigned Reg = O->getReg();
00043       if (Reg == 0)
00044         continue;
00045       removeReg(Reg);
00046     } else if (O->isRegMask())
00047       removeRegsInMask(*O);
00048   }
00049 
00050   // Add uses to the set.
00051   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
00052     if (!O->isReg() || !O->readsReg() || O->isUndef())
00053       continue;
00054     unsigned Reg = O->getReg();
00055     if (Reg == 0)
00056       continue;
00057     addReg(Reg);
00058   }
00059 }
00060 
00061 /// Simulates liveness when stepping forward over an instruction(bundle): Remove
00062 /// killed-uses, add defs. This is the not recommended way, because it depends
00063 /// on accurate kill flags. If possible use stepBackwards() instead of this
00064 /// function.
00065 void LivePhysRegs::stepForward(const MachineInstr &MI) {
00066   SmallVector<unsigned, 4> Defs;
00067   // Remove killed registers from the set.
00068   for (ConstMIBundleOperands O(&MI); O.isValid(); ++O) {
00069     if (O->isReg()) {
00070       unsigned Reg = O->getReg();
00071       if (Reg == 0)
00072         continue;
00073       if (O->isDef()) {
00074         if (!O->isDead())
00075           Defs.push_back(Reg);
00076       } else {
00077         if (!O->isKill())
00078           continue;
00079         assert(O->isUse());
00080         removeReg(Reg);
00081       }
00082     } else if (O->isRegMask())
00083       removeRegsInMask(*O);
00084   }
00085 
00086   // Add defs to the set.
00087   for (unsigned i = 0, e = Defs.size(); i != e; ++i)
00088     addReg(Defs[i]);
00089 }
00090 
00091 /// Prin the currently live registers to OS.
00092 void LivePhysRegs::print(raw_ostream &OS) const {
00093   OS << "Live Registers:";
00094   if (!TRI) {
00095     OS << " (uninitialized)\n";
00096     return;
00097   }
00098 
00099   if (empty()) {
00100     OS << " (empty)\n";
00101     return;
00102   }
00103 
00104   for (const_iterator I = begin(), E = end(); I != E; ++I)
00105     OS << " " << PrintReg(*I, TRI);
00106   OS << "\n";
00107 }
00108 
00109 /// Dumps the currently live registers to the debug output.
00110 void LivePhysRegs::dump() const {
00111 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
00112   dbgs() << "  " << *this;
00113 #endif
00114 }