123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/CodeGen/LiveRegUnits.h - Register Unit Set ----------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file
- /// A set of register units. It is intended for register liveness tracking.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CODEGEN_LIVEREGUNITS_H
- #define LLVM_CODEGEN_LIVEREGUNITS_H
- #include "llvm/ADT/BitVector.h"
- #include "llvm/CodeGen/MachineInstrBundle.h"
- #include "llvm/CodeGen/TargetRegisterInfo.h"
- #include "llvm/MC/LaneBitmask.h"
- #include "llvm/MC/MCRegisterInfo.h"
- #include <cstdint>
- namespace llvm {
- class MachineInstr;
- class MachineBasicBlock;
- /// A set of register units used to track register liveness.
- class LiveRegUnits {
- const TargetRegisterInfo *TRI = nullptr;
- BitVector Units;
- public:
- /// Constructs a new empty LiveRegUnits set.
- LiveRegUnits() = default;
- /// Constructs and initialize an empty LiveRegUnits set.
- LiveRegUnits(const TargetRegisterInfo &TRI) {
- init(TRI);
- }
- /// For a machine instruction \p MI, adds all register units used in
- /// \p UsedRegUnits and defined or clobbered in \p ModifiedRegUnits. This is
- /// useful when walking over a range of instructions to track registers
- /// used or defined seperately.
- static void accumulateUsedDefed(const MachineInstr &MI,
- LiveRegUnits &ModifiedRegUnits,
- LiveRegUnits &UsedRegUnits,
- const TargetRegisterInfo *TRI) {
- for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
- if (O->isRegMask())
- ModifiedRegUnits.addRegsInMask(O->getRegMask());
- if (!O->isReg())
- continue;
- Register Reg = O->getReg();
- if (!Reg.isPhysical())
- continue;
- if (O->isDef()) {
- // Some architectures (e.g. AArch64 XZR/WZR) have registers that are
- // constant and may be used as destinations to indicate the generated
- // value is discarded. No need to track such case as a def.
- if (!TRI->isConstantPhysReg(Reg))
- ModifiedRegUnits.addReg(Reg);
- } else {
- assert(O->isUse() && "Reg operand not a def and not a use");
- UsedRegUnits.addReg(Reg);
- }
- }
- }
- /// Initialize and clear the set.
- void init(const TargetRegisterInfo &TRI) {
- this->TRI = &TRI;
- Units.reset();
- Units.resize(TRI.getNumRegUnits());
- }
- /// Clears the set.
- void clear() { Units.reset(); }
- /// Returns true if the set is empty.
- bool empty() const { return Units.none(); }
- /// Adds register units covered by physical register \p Reg.
- void addReg(MCPhysReg Reg) {
- for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
- Units.set(*Unit);
- }
- /// Adds register units covered by physical register \p Reg that are
- /// part of the lanemask \p Mask.
- void addRegMasked(MCPhysReg Reg, LaneBitmask Mask) {
- for (MCRegUnitMaskIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
- LaneBitmask UnitMask = (*Unit).second;
- if (UnitMask.none() || (UnitMask & Mask).any())
- Units.set((*Unit).first);
- }
- }
- /// Removes all register units covered by physical register \p Reg.
- void removeReg(MCPhysReg Reg) {
- for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
- Units.reset(*Unit);
- }
- /// Removes register units not preserved by the regmask \p RegMask.
- /// The regmask has the same format as the one in the RegMask machine operand.
- void removeRegsNotPreserved(const uint32_t *RegMask);
- /// Adds register units not preserved by the regmask \p RegMask.
- /// The regmask has the same format as the one in the RegMask machine operand.
- void addRegsInMask(const uint32_t *RegMask);
- /// Returns true if no part of physical register \p Reg is live.
- bool available(MCPhysReg Reg) const {
- for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
- if (Units.test(*Unit))
- return false;
- }
- return true;
- }
- /// Updates liveness when stepping backwards over the instruction \p MI.
- /// This removes all register units defined or clobbered in \p MI and then
- /// adds the units used (as in use operands) in \p MI.
- void stepBackward(const MachineInstr &MI);
- /// Adds all register units used, defined or clobbered in \p MI.
- /// This is useful when walking over a range of instruction to find registers
- /// unused over the whole range.
- void accumulate(const MachineInstr &MI);
- /// Adds registers living out of block \p MBB.
- /// Live out registers are the union of the live-in registers of the successor
- /// blocks and pristine registers. Live out registers of the end block are the
- /// callee saved registers.
- void addLiveOuts(const MachineBasicBlock &MBB);
- /// Adds registers living into block \p MBB.
- void addLiveIns(const MachineBasicBlock &MBB);
- /// Adds all register units marked in the bitvector \p RegUnits.
- void addUnits(const BitVector &RegUnits) {
- Units |= RegUnits;
- }
- /// Removes all register units marked in the bitvector \p RegUnits.
- void removeUnits(const BitVector &RegUnits) {
- Units.reset(RegUnits);
- }
- /// Return the internal bitvector representation of the set.
- const BitVector &getBitVector() const {
- return Units;
- }
- private:
- /// Adds pristine registers. Pristine registers are callee saved registers
- /// that are unused in the function.
- void addPristines(const MachineFunction &MF);
- };
- /// Returns an iterator range over all physical register and mask operands for
- /// \p MI and bundled instructions. This also skips any debug operands.
- inline iterator_range<filter_iterator<
- ConstMIBundleOperands, std::function<bool(const MachineOperand &)>>>
- phys_regs_and_masks(const MachineInstr &MI) {
- std::function<bool(const MachineOperand &)> Pred =
- [](const MachineOperand &MOP) {
- return MOP.isRegMask() || (MOP.isReg() && !MOP.isDebug() &&
- Register::isPhysicalRegister(MOP.getReg()));
- };
- return make_filter_range(const_mi_bundle_ops(MI), Pred);
- }
- } // end namespace llvm
- #endif // LLVM_CODEGEN_LIVEREGUNITS_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|