1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 12:12:47 +01:00
llvm-mirror/include/llvm/CodeGen/LiveRegUnits.h
Daniel Sanders c32fe492af Eliminate implicit Register->unsigned conversions in VirtRegMap. NFC
Summary:
This was mostly an experiment to assess the feasibility of completely
eliminating a problematic implicit conversion case in D61321 in advance of
landing that* but it also happens to align with the goal of propagating the
use of Register/MCRegister instead of unsigned so I believe it makes sense
to commit it.

The overall process for eliminating the implicit conversions from
Register/MCRegister -> unsigned was to:
1. Add an explicit conversion to support genuinely required conversions to
   unsigned. For example, using them as an index for IndexedMap. Sadly it's
   not possible to have an explicit and implicit conversion to the same
   type and only deprecate the implicit one so I called the explicit
   conversion get().
2. Temporarily annotate the implicit conversion to unsigned with
   LLVM_ATTRIBUTE_DEPRECATED to make them visible
3. Eliminate implicit conversions by propagating Register/MCRegister/
   explicit-conversions appropriately
4. Remove the deprecation added in 2.

* My conclusion is that it isn't feasible as there's too much code to
  update in one go.

Depends on D65678

Reviewers: arsenm

Subscribers: MatzeB, wdng, hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D65685

llvm-svn: 368643
2019-08-13 00:55:24 +00:00

166 lines
5.6 KiB
C++

//===- 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/MachineRegisterInfo.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);
}
}
return;
}
/// 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);
};
} // end namespace llvm
#endif // LLVM_CODEGEN_LIVEREGUNITS_H