1259698Sdim//===-- llvm/CodeGen/LiveRegUnits.h - Live register unit set ----*- C++ -*-===// 2259698Sdim// 3259698Sdim// The LLVM Compiler Infrastructure 4259698Sdim// 5259698Sdim// This file is distributed under the University of Illinois Open Source 6259698Sdim// License. See LICENSE.TXT for details. 7259698Sdim// 8259698Sdim//===----------------------------------------------------------------------===// 9259698Sdim// 10259698Sdim// This file implements a Set of live register units. This can be used for ad 11259698Sdim// hoc liveness tracking after register allocation. You can start with the 12259698Sdim// live-ins/live-outs at the beginning/end of a block and update the information 13259698Sdim// while walking the instructions inside the block. 14259698Sdim// 15259698Sdim//===----------------------------------------------------------------------===// 16259698Sdim 17259698Sdim#ifndef LLVM_CODEGEN_LIVEREGUNITS_H 18259698Sdim#define LLVM_CODEGEN_LIVEREGUNITS_H 19259698Sdim 20259698Sdim#include "llvm/ADT/SparseSet.h" 21259698Sdim#include "llvm/CodeGen/MachineBasicBlock.h" 22259698Sdim#include "llvm/Target/TargetRegisterInfo.h" 23259698Sdim#include <cassert> 24259698Sdim 25259698Sdimnamespace llvm { 26259698Sdim 27259698Sdimclass MachineInstr; 28259698Sdim 29259698Sdim/// A set of live register units with functions to track liveness when walking 30259698Sdim/// backward/forward through a basic block. 31259698Sdimclass LiveRegUnits { 32259698Sdim SparseSet<unsigned> LiveUnits; 33259698Sdim 34259698Sdim LiveRegUnits(const LiveRegUnits&) LLVM_DELETED_FUNCTION; 35259698Sdim LiveRegUnits &operator=(const LiveRegUnits&) LLVM_DELETED_FUNCTION; 36259698Sdimpublic: 37259698Sdim /// \brief Constructs a new empty LiveRegUnits set. 38259698Sdim LiveRegUnits() {} 39259698Sdim 40259698Sdim void init(const TargetRegisterInfo *TRI) { 41259698Sdim LiveUnits.clear(); 42259698Sdim LiveUnits.setUniverse(TRI->getNumRegs()); 43259698Sdim } 44259698Sdim 45259698Sdim void clear() { LiveUnits.clear(); } 46259698Sdim 47259698Sdim bool empty() const { return LiveUnits.empty(); } 48259698Sdim 49259698Sdim /// \brief Adds a register to the set. 50259698Sdim void addReg(unsigned Reg, const MCRegisterInfo &MCRI) { 51259698Sdim for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) 52259698Sdim LiveUnits.insert(*RUnits); 53259698Sdim } 54259698Sdim 55259698Sdim /// \brief Removes a register from the set. 56259698Sdim void removeReg(unsigned Reg, const MCRegisterInfo &MCRI) { 57259698Sdim for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) 58259698Sdim LiveUnits.erase(*RUnits); 59259698Sdim } 60259698Sdim 61259698Sdim /// \brief Removes registers clobbered by the regmask operand @p Op. 62259698Sdim void removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI); 63259698Sdim 64259698Sdim /// \brief Returns true if register @p Reg (or one of its super register) is 65259698Sdim /// contained in the set. 66259698Sdim bool contains(unsigned Reg, const MCRegisterInfo &MCRI) const { 67259698Sdim for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) { 68259698Sdim if (LiveUnits.count(*RUnits)) 69259698Sdim return true; 70259698Sdim } 71259698Sdim return false; 72259698Sdim } 73259698Sdim 74259698Sdim /// \brief Simulates liveness when stepping backwards over an 75259698Sdim /// instruction(bundle): Remove Defs, add uses. 76259698Sdim void stepBackward(const MachineInstr &MI, const MCRegisterInfo &MCRI); 77259698Sdim 78259698Sdim /// \brief Simulates liveness when stepping forward over an 79259698Sdim /// instruction(bundle): Remove killed-uses, add defs. 80259698Sdim void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI); 81259698Sdim 82259698Sdim /// \brief Adds all registers in the live-in list of block @p BB. 83259698Sdim void addLiveIns(const MachineBasicBlock *MBB, const MCRegisterInfo &MCRI); 84259698Sdim}; 85259698Sdim 86259698Sdim} // namespace llvm 87259698Sdim 88259698Sdim#endif 89