1//===-- llvm/CodeGen/LiveRegUnits.h - Live register unit set ----*- C++ -*-===//
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 a Set of live register units. This can be used for ad
11// hoc liveness tracking after register allocation. You can start with the
12// live-ins/live-outs at the beginning/end of a block and update the information
13// while walking the instructions inside the block.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
18#define LLVM_CODEGEN_LIVEREGUNITS_H
19
20#include "llvm/ADT/SparseSet.h"
21#include "llvm/CodeGen/MachineBasicBlock.h"
22#include "llvm/Target/TargetRegisterInfo.h"
23#include <cassert>
24
25namespace llvm {
26
27class MachineInstr;
28
29/// A set of live register units with functions to track liveness when walking
30/// backward/forward through a basic block.
31class LiveRegUnits {
32  SparseSet<unsigned> LiveUnits;
33
34  LiveRegUnits(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
35  LiveRegUnits &operator=(const LiveRegUnits&) LLVM_DELETED_FUNCTION;
36public:
37  /// \brief Constructs a new empty LiveRegUnits set.
38  LiveRegUnits() {}
39
40  void init(const TargetRegisterInfo *TRI) {
41    LiveUnits.clear();
42    LiveUnits.setUniverse(TRI->getNumRegs());
43  }
44
45  void clear() { LiveUnits.clear(); }
46
47  bool empty() const { return LiveUnits.empty(); }
48
49  /// \brief Adds a register to the set.
50  void addReg(unsigned Reg, const MCRegisterInfo &MCRI) {
51    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
52      LiveUnits.insert(*RUnits);
53  }
54
55  /// \brief Removes a register from the set.
56  void removeReg(unsigned Reg, const MCRegisterInfo &MCRI) {
57    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits)
58      LiveUnits.erase(*RUnits);
59  }
60
61  /// \brief Removes registers clobbered by the regmask operand @p Op.
62  void removeRegsInMask(const MachineOperand &Op, const MCRegisterInfo &MCRI);
63
64  /// \brief Returns true if register @p Reg (or one of its super register) is
65  /// contained in the set.
66  bool contains(unsigned Reg, const MCRegisterInfo &MCRI) const {
67    for (MCRegUnitIterator RUnits(Reg, &MCRI); RUnits.isValid(); ++RUnits) {
68      if (LiveUnits.count(*RUnits))
69        return true;
70    }
71    return false;
72  }
73
74  /// \brief Simulates liveness when stepping backwards over an
75  /// instruction(bundle): Remove Defs, add uses.
76  void stepBackward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
77
78  /// \brief Simulates liveness when stepping forward over an
79  /// instruction(bundle): Remove killed-uses, add defs.
80  void stepForward(const MachineInstr &MI, const MCRegisterInfo &MCRI);
81
82  /// \brief Adds all registers in the live-in list of block @p BB.
83  void addLiveIns(const MachineBasicBlock *MBB, const MCRegisterInfo &MCRI);
84};
85
86} // namespace llvm
87
88#endif
89