1c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- C++ -*-===//
2c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
3c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//                     The LLVM Compiler Infrastructure
4c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
5c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// This file is distributed under the University of Illinois Open Source
6c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot// License. See LICENSE.TXT for details.
7c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
8c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
9c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
10c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// \file
11c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// A set of register units. It is intended for register liveness tracking.
12c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//
13c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot//===----------------------------------------------------------------------===//
14c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
15c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#ifndef LLVM_CODEGEN_LIVEREGUNITS_H
16c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#define LLVM_CODEGEN_LIVEREGUNITS_H
17c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
18c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/ADT/BitVector.h"
19c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/MC/LaneBitmask.h"
20c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/MC/MCRegisterInfo.h"
21c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include "llvm/Target/TargetRegisterInfo.h"
22c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#include <cstdint>
23c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
24c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotnamespace llvm {
25c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
26c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass MachineInstr;
27c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass MachineBasicBlock;
28c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
29c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot/// A set of register units used to track register liveness.
30c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotclass LiveRegUnits {
31c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const TargetRegisterInfo *TRI = nullptr;
32c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  BitVector Units;
33c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
34c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotpublic:
35c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Constructs a new empty LiveRegUnits set.
36c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  LiveRegUnits() = default;
37c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
38c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Constructs and initialize an empty LiveRegUnits set.
39c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  LiveRegUnits(const TargetRegisterInfo &TRI) {
40c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    init(TRI);
41c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
42c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
43c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Initialize and clear the set.
44c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void init(const TargetRegisterInfo &TRI) {
45c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    this->TRI = &TRI;
46c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Units.reset();
47c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Units.resize(TRI.getNumRegUnits());
48c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
49c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
50c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Clears the set.
51c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void clear() { Units.reset(); }
52c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
53c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Returns true if the set is empty.
54c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool empty() const { return Units.none(); }
55c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
56c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds register units covered by physical register \p Reg.
57c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addReg(unsigned Reg) {
58c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
59c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Units.set(*Unit);
60c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
61c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
62c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// \brief Adds register units covered by physical register \p Reg that are
63c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// part of the lanemask \p Mask.
64c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addRegMasked(unsigned Reg, LaneBitmask Mask) {
65c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
66c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      LaneBitmask UnitMask = (*Unit).second;
67c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (UnitMask.none() || (UnitMask & Mask).any())
68c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        Units.set((*Unit).first);
69c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
70c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
71c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
72c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Removes all register units covered by physical register \p Reg.
73c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void removeReg(unsigned Reg) {
74c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
75c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      Units.reset(*Unit);
76c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
77c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
78c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Removes register units not preserved by the regmask \p RegMask.
79c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// The regmask has the same format as the one in the RegMask machine operand.
80c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void removeRegsNotPreserved(const uint32_t *RegMask);
81c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
82c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds register units not preserved by the regmask \p RegMask.
83c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// The regmask has the same format as the one in the RegMask machine operand.
84c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addRegsInMask(const uint32_t *RegMask);
85c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
86c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Returns true if no part of physical register \p Reg is live.
87c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  bool available(unsigned Reg) const {
88c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
89c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot      if (Units.test(*Unit))
90c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot        return false;
91c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    }
92c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return true;
93c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
94c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
95c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Updates liveness when stepping backwards over the instruction \p MI.
96c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This removes all register units defined or clobbered in \p MI and then
97c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// adds the units used (as in use operands) in \p MI.
98c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void stepBackward(const MachineInstr &MI);
99c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
100c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds all register units used, defined or clobbered in \p MI.
101c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// This is useful when walking over a range of instruction to find registers
102c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// unused over the whole range.
103c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void accumulate(const MachineInstr &MI);
104c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
105c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds registers living out of block \p MBB.
106c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Live out registers are the union of the live-in registers of the successor
107c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// blocks and pristine registers. Live out registers of the end block are the
108c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// callee saved registers.
109c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addLiveOuts(const MachineBasicBlock &MBB);
110c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
111c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds registers living into block \p MBB.
112c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addLiveIns(const MachineBasicBlock &MBB);
113c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
114c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds all register units marked in the bitvector \p RegUnits.
115c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addUnits(const BitVector &RegUnits) {
116c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Units |= RegUnits;
117c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
118c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Removes all register units marked in the bitvector \p RegUnits.
119c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void removeUnits(const BitVector &RegUnits) {
120c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    Units.reset(RegUnits);
121c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
122c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Return the internal bitvector representation of the set.
123c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  const BitVector &getBitVector() const {
124c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot    return Units;
125c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  }
126c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
127c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robotprivate:
128c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// Adds pristine registers. Pristine registers are callee saved registers
129c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  /// that are unused in the function.
130c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot  void addPristines(const MachineFunction &MF);
131c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot};
132c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
133c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot} // end namespace llvm
134c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot
135c9cc9e7d29b8970d8ddb734c88fb62d01e0b727android-build-team Robot#endif // LLVM_CODEGEN_LIVEREGUNITS_H
136