mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-12-11 22:44:59 +00:00
Initial Commit
This commit is contained in:
177
thirdparty/capstone/suite/synctools/tablegen/include/llvm/CodeGen/LiveRegUnits.h
vendored
Normal file
177
thirdparty/capstone/suite/synctools/tablegen/include/llvm/CodeGen/LiveRegUnits.h
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
//===- 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 separately.
|
||||
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
|
||||
Reference in New Issue
Block a user