mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
Extract LaneBitmask into a separate type
Specifically avoid implicit conversions from/to integral types to avoid potential errors when changing the underlying type. For example, a typical initialization of a "full" mask was "LaneMask = ~0u", which would result in a value of 0x00000000FFFFFFFF if the type was extended to uint64_t. Differential Revision: https://reviews.llvm.org/D27454 llvm-svn: 289820
This commit is contained in:
parent
97b5f6a46b
commit
b6cc44c368
@ -459,7 +459,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
|
||||
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
|
||||
MachineBasicBlock::iterator End,
|
||||
const SlotIndex endIdx, LiveRange &LR,
|
||||
unsigned Reg, LaneBitmask LaneMask = ~0u);
|
||||
unsigned Reg,
|
||||
LaneBitmask LaneMask = LaneBitmask::getAll());
|
||||
|
||||
class HMEditor;
|
||||
};
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <functional>
|
||||
@ -35,9 +36,6 @@ class StringRef;
|
||||
class raw_ostream;
|
||||
class MachineBranchProbabilityInfo;
|
||||
|
||||
// Forward declaration to avoid circular include problem with TargetRegisterInfo
|
||||
typedef unsigned LaneBitmask;
|
||||
|
||||
template <> struct ilist_traits<MachineInstr> {
|
||||
private:
|
||||
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
|
||||
@ -278,7 +276,8 @@ public:
|
||||
/// Adds the specified register as a live in. Note that it is an error to add
|
||||
/// the same register to the same set more than once unless the intention is
|
||||
/// to call sortUniqueLiveIns after all registers are added.
|
||||
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask = ~0u) {
|
||||
void addLiveIn(MCPhysReg PhysReg,
|
||||
LaneBitmask LaneMask = LaneBitmask::getAll()) {
|
||||
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
|
||||
}
|
||||
void addLiveIn(const RegisterMaskPair &RegMaskPair) {
|
||||
@ -296,10 +295,12 @@ public:
|
||||
unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
|
||||
|
||||
/// Remove the specified register from the live in set.
|
||||
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u);
|
||||
void removeLiveIn(MCPhysReg Reg,
|
||||
LaneBitmask LaneMask = LaneBitmask::getAll());
|
||||
|
||||
/// Return true if the specified register is in the live in set.
|
||||
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u) const;
|
||||
bool isLiveIn(MCPhysReg Reg,
|
||||
LaneBitmask LaneMask = LaneBitmask::getAll()) const;
|
||||
|
||||
// Iteration support for live in sets. These sets are kept in sorted
|
||||
// order by their register number.
|
||||
|
@ -278,7 +278,7 @@ public:
|
||||
unsigned SparseIndex = getSparseIndexFromReg(Reg);
|
||||
RegSet::const_iterator I = Regs.find(SparseIndex);
|
||||
if (I == Regs.end())
|
||||
return 0;
|
||||
return LaneBitmask::getNone();
|
||||
return I->LaneMask;
|
||||
}
|
||||
|
||||
@ -288,11 +288,11 @@ public:
|
||||
unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
|
||||
auto InsertRes = Regs.insert(IndexMaskPair(SparseIndex, Pair.LaneMask));
|
||||
if (!InsertRes.second) {
|
||||
unsigned PrevMask = InsertRes.first->LaneMask;
|
||||
LaneBitmask PrevMask = InsertRes.first->LaneMask;
|
||||
InsertRes.first->LaneMask |= Pair.LaneMask;
|
||||
return PrevMask;
|
||||
}
|
||||
return 0;
|
||||
return LaneBitmask::getNone();
|
||||
}
|
||||
|
||||
/// Clears the \p Pair.LaneMask lanes of \p Pair.Reg (mark them as dead).
|
||||
@ -301,8 +301,8 @@ public:
|
||||
unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
|
||||
RegSet::iterator I = Regs.find(SparseIndex);
|
||||
if (I == Regs.end())
|
||||
return 0;
|
||||
unsigned PrevMask = I->LaneMask;
|
||||
return LaneBitmask::getNone();
|
||||
LaneBitmask PrevMask = I->LaneMask;
|
||||
I->LaneMask &= ~Pair.LaneMask;
|
||||
return PrevMask;
|
||||
}
|
||||
@ -315,7 +315,7 @@ public:
|
||||
void appendTo(ContainerT &To) const {
|
||||
for (const IndexMaskPair &P : Regs) {
|
||||
unsigned Reg = getRegFromSparseIndex(P.Index);
|
||||
if (P.LaneMask != 0)
|
||||
if (!P.LaneMask.none())
|
||||
To.push_back(RegisterMaskPair(Reg, P.LaneMask));
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
}
|
||||
|
||||
/// Tell the scavenger a register is used.
|
||||
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u);
|
||||
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll());
|
||||
private:
|
||||
/// Returns true if a register is reserved. It is never "unused".
|
||||
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }
|
||||
|
88
include/llvm/MC/LaneBitmask.h
Normal file
88
include/llvm/MC/LaneBitmask.h
Normal file
@ -0,0 +1,88 @@
|
||||
//===-- llvm/MC/LaneBitmask.h -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// A common definition of LaneBitmask for use in TableGen and CodeGen.
|
||||
///
|
||||
/// A lane mask is a bitmask representing the covering of a register with
|
||||
/// sub-registers.
|
||||
///
|
||||
/// This is typically used to track liveness at sub-register granularity.
|
||||
/// Lane masks for sub-register indices are similar to register units for
|
||||
/// physical registers. The individual bits in a lane mask can't be assigned
|
||||
/// any specific meaning. They can be used to check if two sub-register
|
||||
/// indices overlap.
|
||||
///
|
||||
/// Iff the target has a register such that:
|
||||
///
|
||||
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
|
||||
///
|
||||
/// then:
|
||||
///
|
||||
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
|
||||
|
||||
#ifndef LLVM_MC_LANEBITMASK_H
|
||||
#define LLVM_MC_LANEBITMASK_H
|
||||
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/Printable.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
struct LaneBitmask {
|
||||
// When changing the underlying type, change the format string as well.
|
||||
typedef unsigned Type;
|
||||
enum : unsigned { BitWidth = 8*sizeof(Type) };
|
||||
constexpr static const char *const FormatStr = "%08X";
|
||||
|
||||
constexpr LaneBitmask() = default;
|
||||
explicit constexpr LaneBitmask(Type V) : Mask(V) {}
|
||||
|
||||
constexpr bool operator== (LaneBitmask M) const { return Mask == M.Mask; }
|
||||
constexpr bool operator!= (LaneBitmask M) const { return Mask != M.Mask; }
|
||||
constexpr bool operator< (LaneBitmask M) const { return Mask < M.Mask; }
|
||||
constexpr bool none() const { return Mask == 0; }
|
||||
constexpr bool all() const { return ~Mask == 0; }
|
||||
|
||||
constexpr LaneBitmask operator~() const {
|
||||
return LaneBitmask(~Mask);
|
||||
}
|
||||
constexpr LaneBitmask operator|(LaneBitmask M) const {
|
||||
return LaneBitmask(Mask | M.Mask);
|
||||
}
|
||||
constexpr LaneBitmask operator&(LaneBitmask M) const {
|
||||
return LaneBitmask(Mask & M.Mask);
|
||||
}
|
||||
LaneBitmask &operator|=(LaneBitmask M) {
|
||||
Mask |= M.Mask;
|
||||
return *this;
|
||||
}
|
||||
LaneBitmask &operator&=(LaneBitmask M) {
|
||||
Mask &= M.Mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr Type getAsInteger() const { return Mask; }
|
||||
|
||||
static LaneBitmask getNone() { return LaneBitmask(0); }
|
||||
static LaneBitmask getAll() { return ~LaneBitmask(0); }
|
||||
|
||||
private:
|
||||
Type Mask = 0;
|
||||
};
|
||||
|
||||
/// Create Printable object to print LaneBitmasks on a \ref raw_ostream.
|
||||
static LLVM_ATTRIBUTE_UNUSED Printable PrintLaneMask(LaneBitmask LaneMask) {
|
||||
return Printable([LaneMask](raw_ostream &OS) {
|
||||
OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LLVM_MC_LANEBITMASK_H
|
@ -17,6 +17,7 @@
|
||||
#define LLVM_MC_MCREGISTERINFO_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <cassert>
|
||||
|
||||
@ -161,7 +162,7 @@ private:
|
||||
unsigned NumRegUnits; // Number of regunits.
|
||||
const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table.
|
||||
const MCPhysReg *DiffLists; // Pointer to the difflists array
|
||||
const unsigned *RegUnitMaskSequences; // Pointer to lane mask sequences
|
||||
const LaneBitmask *RegUnitMaskSequences; // Pointer to lane mask sequences
|
||||
// for register units.
|
||||
const char *RegStrings; // Pointer to the string table.
|
||||
const char *RegClassStrings; // Pointer to the class strings.
|
||||
@ -248,7 +249,7 @@ public:
|
||||
const MCPhysReg (*RURoots)[2],
|
||||
unsigned NRU,
|
||||
const MCPhysReg *DL,
|
||||
const unsigned *RUMS,
|
||||
const LaneBitmask *RUMS,
|
||||
const char *Strings,
|
||||
const char *ClassStrings,
|
||||
const uint16_t *SubIndices,
|
||||
@ -584,7 +585,7 @@ public:
|
||||
/// numerical order.
|
||||
class MCRegUnitMaskIterator {
|
||||
MCRegUnitIterator RUIter;
|
||||
const unsigned *MaskListIter;
|
||||
const LaneBitmask *MaskListIter;
|
||||
public:
|
||||
MCRegUnitMaskIterator() {}
|
||||
/// Constructs an iterator that traverses the register units and their
|
||||
@ -596,7 +597,7 @@ public:
|
||||
}
|
||||
|
||||
/// Returns a (RegUnit, LaneMask) pair.
|
||||
std::pair<unsigned,unsigned> operator*() const {
|
||||
std::pair<unsigned,LaneBitmask> operator*() const {
|
||||
return std::make_pair(*RUIter, *MaskListIter);
|
||||
}
|
||||
|
||||
|
@ -36,23 +36,6 @@ class VirtRegMap;
|
||||
class raw_ostream;
|
||||
class LiveRegMatrix;
|
||||
|
||||
/// A bitmask representing the covering of a register with sub-registers.
|
||||
///
|
||||
/// This is typically used to track liveness at sub-register granularity.
|
||||
/// Lane masks for sub-register indices are similar to register units for
|
||||
/// physical registers. The individual bits in a lane mask can't be assigned
|
||||
/// any specific meaning. They can be used to check if two sub-register
|
||||
/// indices overlap.
|
||||
///
|
||||
/// Iff the target has a register such that:
|
||||
///
|
||||
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
|
||||
///
|
||||
/// then:
|
||||
///
|
||||
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
|
||||
typedef unsigned LaneBitmask;
|
||||
|
||||
class TargetRegisterClass {
|
||||
public:
|
||||
typedef const MCPhysReg* iterator;
|
||||
@ -269,7 +252,7 @@ private:
|
||||
const LaneBitmask *SubRegIndexLaneMasks;
|
||||
|
||||
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
|
||||
unsigned CoveringLanes;
|
||||
LaneBitmask CoveringLanes;
|
||||
|
||||
protected:
|
||||
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||
@ -277,7 +260,7 @@ protected:
|
||||
regclass_iterator RegClassEnd,
|
||||
const char *const *SRINames,
|
||||
const LaneBitmask *SRILaneMasks,
|
||||
unsigned CoveringLanes);
|
||||
LaneBitmask CoveringLanes);
|
||||
virtual ~TargetRegisterInfo();
|
||||
public:
|
||||
|
||||
@ -1141,9 +1124,6 @@ Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI);
|
||||
/// registers on a \ref raw_ostream.
|
||||
Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI);
|
||||
|
||||
/// Create Printable object to print LaneBitmasks on a \ref raw_ostream.
|
||||
Printable PrintLaneMask(LaneBitmask LaneMask);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -210,7 +210,7 @@ void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
|
||||
VRegInfo &MORegInfo = VRegInfos[MORegIdx];
|
||||
LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
|
||||
// Any change at all?
|
||||
if ((UsedLanes & ~PrevUsedLanes) == 0)
|
||||
if ((UsedLanes & ~PrevUsedLanes).none())
|
||||
return;
|
||||
|
||||
// Set UsedLanes and remember instruction for further propagation.
|
||||
@ -303,7 +303,7 @@ void DetectDeadLanes::transferDefinedLanesStep(const MachineOperand &Use,
|
||||
VRegInfo &RegInfo = VRegInfos[DefRegIdx];
|
||||
LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
|
||||
// Any change at all?
|
||||
if ((DefinedLanes & ~PrevDefinedLanes) == 0)
|
||||
if ((DefinedLanes & ~PrevDefinedLanes).none())
|
||||
return;
|
||||
|
||||
RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
|
||||
@ -356,7 +356,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
// Live-In or unused registers have no definition but are considered fully
|
||||
// defined.
|
||||
if (!MRI->hasOneDef(Reg))
|
||||
return ~0u;
|
||||
return LaneBitmask::getAll();
|
||||
|
||||
const MachineOperand &Def = *MRI->def_begin(Reg);
|
||||
const MachineInstr &DefMI = *Def.getParent();
|
||||
@ -368,7 +368,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
PutInWorklist(RegIdx);
|
||||
|
||||
if (Def.isDead())
|
||||
return 0;
|
||||
return LaneBitmask::getNone();
|
||||
|
||||
// COPY/PHI can copy across unrelated register classes (example: float/int)
|
||||
// with incompatible subregister structure. Do not include these in the
|
||||
@ -376,7 +376,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
|
||||
|
||||
// Determine initially DefinedLanes.
|
||||
LaneBitmask DefinedLanes = 0;
|
||||
LaneBitmask DefinedLanes;
|
||||
for (const MachineOperand &MO : DefMI.uses()) {
|
||||
if (!MO.isReg() || !MO.readsReg())
|
||||
continue;
|
||||
@ -386,9 +386,9 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
|
||||
LaneBitmask MODefinedLanes;
|
||||
if (TargetRegisterInfo::isPhysicalRegister(MOReg)) {
|
||||
MODefinedLanes = ~0u;
|
||||
MODefinedLanes = LaneBitmask::getAll();
|
||||
} else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
|
||||
MODefinedLanes = ~0u;
|
||||
MODefinedLanes = LaneBitmask::getAll();
|
||||
} else {
|
||||
assert(TargetRegisterInfo::isVirtualRegister(MOReg));
|
||||
if (MRI->hasOneDef(MOReg)) {
|
||||
@ -410,7 +410,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
return DefinedLanes;
|
||||
}
|
||||
if (DefMI.isImplicitDef() || Def.isDead())
|
||||
return 0;
|
||||
return LaneBitmask::getNone();
|
||||
|
||||
assert(Def.getSubReg() == 0 &&
|
||||
"Should not have subregister defs in machine SSA phase");
|
||||
@ -418,7 +418,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
|
||||
}
|
||||
|
||||
LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
|
||||
LaneBitmask UsedLanes = 0;
|
||||
LaneBitmask UsedLanes = LaneBitmask::getNone();
|
||||
for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
|
||||
if (!MO.readsReg())
|
||||
continue;
|
||||
@ -462,7 +462,7 @@ bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
|
||||
const VRegInfo &RegInfo) const {
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||
return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask) == 0;
|
||||
return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
|
||||
}
|
||||
|
||||
bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
|
||||
@ -482,7 +482,7 @@ bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
|
||||
|
||||
const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
|
||||
LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
|
||||
if (UsedLanes != 0)
|
||||
if (!UsedLanes.none())
|
||||
return false;
|
||||
|
||||
unsigned MOReg = MO.getReg();
|
||||
@ -546,7 +546,7 @@ bool DetectDeadLanes::runOnce(MachineFunction &MF) {
|
||||
continue;
|
||||
unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
|
||||
const VRegInfo &RegInfo = VRegInfos[RegIdx];
|
||||
if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes == 0) {
|
||||
if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
|
||||
DEBUG(dbgs() << "Marking operand '" << MO << "' as dead in " << MI);
|
||||
MO.setIsDead();
|
||||
}
|
||||
|
@ -876,7 +876,7 @@ void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
|
||||
const SlotIndexes &Indexes) const {
|
||||
assert(TargetRegisterInfo::isVirtualRegister(reg));
|
||||
LaneBitmask VRegMask = MRI.getMaxLaneMaskForVReg(reg);
|
||||
assert((VRegMask & LaneMask) != 0);
|
||||
assert(!(VRegMask & LaneMask).none());
|
||||
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
|
||||
for (const MachineOperand &MO : MRI.def_operands(reg)) {
|
||||
if (!MO.isUndef())
|
||||
@ -885,7 +885,7 @@ void LiveInterval::computeSubRangeUndefs(SmallVectorImpl<SlotIndex> &Undefs,
|
||||
assert(SubReg != 0 && "Undef should only be set on subreg defs");
|
||||
LaneBitmask DefMask = TRI.getSubRegIndexLaneMask(SubReg);
|
||||
LaneBitmask UndefMask = VRegMask & ~DefMask;
|
||||
if ((UndefMask & LaneMask) != 0) {
|
||||
if (!(UndefMask & LaneMask).none()) {
|
||||
const MachineInstr &MI = *MO.getParent();
|
||||
bool EarlyClobber = MO.isEarlyClobber();
|
||||
SlotIndex Pos = Indexes.getInstructionIndex(MI).getRegSlot(EarlyClobber);
|
||||
@ -982,15 +982,16 @@ void LiveInterval::verify(const MachineRegisterInfo *MRI) const {
|
||||
super::verify();
|
||||
|
||||
// Make sure SubRanges are fine and LaneMasks are disjunct.
|
||||
LaneBitmask Mask = 0;
|
||||
LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg) : ~0u;
|
||||
LaneBitmask Mask;
|
||||
LaneBitmask MaxMask = MRI != nullptr ? MRI->getMaxLaneMaskForVReg(reg)
|
||||
: LaneBitmask::getAll();
|
||||
for (const SubRange &SR : subranges()) {
|
||||
// Subrange lanemask should be disjunct to any previous subrange masks.
|
||||
assert((Mask & SR.LaneMask) == 0);
|
||||
assert((Mask & SR.LaneMask).none());
|
||||
Mask |= SR.LaneMask;
|
||||
|
||||
// subrange mask should not contained in maximum lane mask for the vreg.
|
||||
assert((Mask & ~MaxMask) == 0);
|
||||
assert((Mask & ~MaxMask).none());
|
||||
// empty subranges must be removed.
|
||||
assert(!SR.empty());
|
||||
|
||||
|
@ -514,7 +514,7 @@ void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg) {
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
if (SubReg != 0) {
|
||||
LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||
if ((LaneMask & SR.LaneMask) == 0)
|
||||
if ((LaneMask & SR.LaneMask).none())
|
||||
continue;
|
||||
}
|
||||
// We only need to visit each instruction once.
|
||||
@ -718,7 +718,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
LaneBitmask DefinedLanesMask;
|
||||
if (!SRs.empty()) {
|
||||
// Compute a mask of lanes that are defined.
|
||||
DefinedLanesMask = 0;
|
||||
DefinedLanesMask = LaneBitmask::getNone();
|
||||
for (auto &SRP : SRs) {
|
||||
const LiveInterval::SubRange &SR = *SRP.first;
|
||||
LiveRange::const_iterator &I = SRP.second;
|
||||
@ -731,7 +731,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
DefinedLanesMask |= SR.LaneMask;
|
||||
}
|
||||
} else
|
||||
DefinedLanesMask = ~0u;
|
||||
DefinedLanesMask = LaneBitmask::getAll();
|
||||
|
||||
bool IsFullWrite = false;
|
||||
for (const MachineOperand &MO : MI->operands()) {
|
||||
@ -740,7 +740,7 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
|
||||
if (MO.isUse()) {
|
||||
// Reading any undefined lanes?
|
||||
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
||||
if ((UseMask & ~DefinedLanesMask) != 0)
|
||||
if (!(UseMask & ~DefinedLanesMask).none())
|
||||
goto CancelKill;
|
||||
} else if (MO.getSubReg() == 0) {
|
||||
// Writing to the full register?
|
||||
@ -951,12 +951,12 @@ public:
|
||||
LaneBitmask LaneMask = SubReg ? TRI.getSubRegIndexLaneMask(SubReg)
|
||||
: MRI.getMaxLaneMaskForVReg(Reg);
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
if ((S.LaneMask & LaneMask) == 0)
|
||||
if ((S.LaneMask & LaneMask).none())
|
||||
continue;
|
||||
updateRange(S, Reg, S.LaneMask);
|
||||
}
|
||||
}
|
||||
updateRange(LI, Reg, 0);
|
||||
updateRange(LI, Reg, LaneBitmask::getNone());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -964,7 +964,7 @@ public:
|
||||
// precomputed live range.
|
||||
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
|
||||
if (LiveRange *LR = getRegUnitLI(*Units))
|
||||
updateRange(*LR, *Units, 0);
|
||||
updateRange(*LR, *Units, LaneBitmask::getNone());
|
||||
}
|
||||
if (hasRegMask)
|
||||
updateRegMaskSlots();
|
||||
@ -980,7 +980,7 @@ private:
|
||||
dbgs() << " ";
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
dbgs() << PrintReg(Reg);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
dbgs() << " L" << PrintLaneMask(LaneMask);
|
||||
} else {
|
||||
dbgs() << PrintRegUnit(Reg, &TRI);
|
||||
@ -1314,8 +1314,8 @@ private:
|
||||
if (MO.isUndef())
|
||||
continue;
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
if (SubReg != 0 && LaneMask != 0
|
||||
&& (TRI.getSubRegIndexLaneMask(SubReg) & LaneMask) == 0)
|
||||
if (SubReg != 0 && !LaneMask.none()
|
||||
&& (TRI.getSubRegIndexLaneMask(SubReg) & LaneMask).none())
|
||||
continue;
|
||||
|
||||
const MachineInstr &MI = *MO.getParent();
|
||||
@ -1422,7 +1422,7 @@ void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin,
|
||||
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
|
||||
if ((Mask & LaneMask) == 0)
|
||||
if ((Mask & LaneMask).none())
|
||||
continue;
|
||||
|
||||
if (MO.isDef()) {
|
||||
|
@ -144,13 +144,15 @@ bool LivePhysRegs::available(const MachineRegisterInfo &MRI,
|
||||
void LivePhysRegs::addBlockLiveIns(const MachineBasicBlock &MBB) {
|
||||
for (const auto &LI : MBB.liveins()) {
|
||||
MCSubRegIndexIterator S(LI.PhysReg, TRI);
|
||||
if (LI.LaneMask == ~0u || (LI.LaneMask != 0 && !S.isValid())) {
|
||||
if (LI.LaneMask.all() || (!LI.LaneMask.none() && !S.isValid())) {
|
||||
addReg(LI.PhysReg);
|
||||
continue;
|
||||
}
|
||||
for (; S.isValid(); ++S)
|
||||
if (LI.LaneMask & TRI->getSubRegIndexLaneMask(S.getSubRegIndex()))
|
||||
for (; S.isValid(); ++S) {
|
||||
unsigned SI = S.getSubRegIndex();
|
||||
if (!(LI.LaneMask & TRI->getSubRegIndexLaneMask(SI)).none())
|
||||
addReg(S.getSubReg());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,11 +79,12 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
// A Mask for subregs common to the existing subrange and current def.
|
||||
LaneBitmask Common = S.LaneMask & Mask;
|
||||
if (Common == 0)
|
||||
if (Common.none())
|
||||
continue;
|
||||
LiveInterval::SubRange *CommonRange;
|
||||
// A Mask for subregs covered by the subrange but not the current def.
|
||||
if (LaneBitmask RM = S.LaneMask & ~Mask) {
|
||||
LaneBitmask RM = S.LaneMask & ~Mask;
|
||||
if (!RM.none()) {
|
||||
// Split the subrange S into two parts: one covered by the current
|
||||
// def (CommonRange), and the one not affected by it (updated S).
|
||||
S.LaneMask = RM;
|
||||
@ -97,7 +98,7 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
|
||||
Mask &= ~Common;
|
||||
}
|
||||
// Create a new SubRange for subregs we did not cover yet.
|
||||
if (Mask != 0) {
|
||||
if (!Mask.none()) {
|
||||
LiveInterval::SubRange *NewRange = LI.createSubRange(*Alloc, Mask);
|
||||
if (MO.isDef())
|
||||
createDeadDef(*Indexes, *Alloc, *NewRange, MO);
|
||||
@ -126,7 +127,7 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
|
||||
constructMainRangeFromSubranges(LI);
|
||||
} else {
|
||||
resetLiveOutMap();
|
||||
extendToUses(LI, Reg, ~0u);
|
||||
extendToUses(LI, Reg, LaneBitmask::getAll());
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +144,7 @@ void LiveRangeCalc::constructMainRangeFromSubranges(LiveInterval &LI) {
|
||||
}
|
||||
}
|
||||
resetLiveOutMap();
|
||||
extendToUses(MainRange, LI.reg, ~0U, &LI);
|
||||
extendToUses(MainRange, LI.reg, LaneBitmask::getAll(), &LI);
|
||||
}
|
||||
|
||||
void LiveRangeCalc::createDeadDefs(LiveRange &LR, unsigned Reg) {
|
||||
@ -163,7 +164,7 @@ void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask,
|
||||
LI->computeSubRangeUndefs(Undefs, Mask, *MRI, *Indexes);
|
||||
|
||||
// Visit all operands that read Reg. This may include partial defs.
|
||||
bool IsSubRange = (Mask != ~0U);
|
||||
bool IsSubRange = !Mask.all();
|
||||
const TargetRegisterInfo &TRI = *MRI->getTargetRegisterInfo();
|
||||
for (MachineOperand &MO : MRI->reg_nodbg_operands(Reg)) {
|
||||
// Clear all kill flags. They will be reinserted after register allocation
|
||||
@ -183,7 +184,7 @@ void LiveRangeCalc::extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask Mask,
|
||||
if (MO.isDef())
|
||||
SLM = ~SLM;
|
||||
// Ignore uses not reading the current (sub)range.
|
||||
if ((SLM & Mask) == 0)
|
||||
if ((SLM & Mask).none())
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -160,7 +160,8 @@ class LiveRangeCalc {
|
||||
/// all uses must be jointly dominated by the definitions from @p LR
|
||||
/// together with definitions of other lanes where @p LR becomes undefined
|
||||
/// (via <def,read-undef> operands).
|
||||
/// If @p LR is a main range, the @p LaneMask should be set to ~0.
|
||||
/// If @p LR is a main range, the @p LaneMask should be set to ~0, i.e.
|
||||
/// LaneBitmask::getAll().
|
||||
void extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask,
|
||||
LiveInterval *LI = nullptr);
|
||||
|
||||
@ -215,7 +216,7 @@ public:
|
||||
/// All uses must be jointly dominated by existing liveness. PHI-defs are
|
||||
/// inserted as needed to preserve SSA form.
|
||||
void extendToUses(LiveRange &LR, unsigned PhysReg) {
|
||||
extendToUses(LR, PhysReg, ~0u);
|
||||
extendToUses(LR, PhysReg, LaneBitmask::getAll());
|
||||
}
|
||||
|
||||
/// Calculates liveness for the register specified in live interval @p LI.
|
||||
|
@ -236,7 +236,7 @@ bool LiveRangeEdit::useIsKill(const LiveInterval &LI,
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
|
||||
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
||||
if ((S.LaneMask & LaneMask) != 0 && S.Query(Idx).isKill())
|
||||
if (!(S.LaneMask & LaneMask).none() && S.Query(Idx).isKill())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -79,7 +79,7 @@ static bool foreachUnit(const TargetRegisterInfo *TRI,
|
||||
unsigned Unit = (*Units).first;
|
||||
LaneBitmask Mask = (*Units).second;
|
||||
for (LiveInterval::SubRange &S : VRegInterval.subranges()) {
|
||||
if (S.LaneMask & Mask) {
|
||||
if (!(S.LaneMask & Mask).none()) {
|
||||
if (Func(Unit, S))
|
||||
return true;
|
||||
break;
|
||||
|
@ -456,15 +456,18 @@ bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
|
||||
if (parseNamedRegister(Reg))
|
||||
return true;
|
||||
lex();
|
||||
LaneBitmask Mask = ~LaneBitmask(0);
|
||||
LaneBitmask Mask = LaneBitmask::getAll();
|
||||
if (consumeIfPresent(MIToken::colon)) {
|
||||
// Parse lane mask.
|
||||
if (Token.isNot(MIToken::IntegerLiteral) &&
|
||||
Token.isNot(MIToken::HexLiteral))
|
||||
return error("expected a lane mask");
|
||||
static_assert(sizeof(LaneBitmask) == sizeof(unsigned), "");
|
||||
if (getUnsigned(Mask))
|
||||
static_assert(sizeof(LaneBitmask::Type) == sizeof(unsigned),
|
||||
"Use correct get-function for lane mask");
|
||||
LaneBitmask::Type V;
|
||||
if (getUnsigned(V))
|
||||
return error("invalid lane mask value");
|
||||
Mask = LaneBitmask(V);
|
||||
lex();
|
||||
}
|
||||
MBB.addLiveIn(Reg, Mask);
|
||||
|
@ -498,7 +498,7 @@ void MIPrinter::print(const MachineBasicBlock &MBB) {
|
||||
OS << ", ";
|
||||
First = false;
|
||||
printReg(LI.PhysReg, OS, TRI);
|
||||
if (LI.LaneMask != ~0u)
|
||||
if (!LI.LaneMask.all())
|
||||
OS << ":0x" << PrintLaneMask(LI.LaneMask);
|
||||
}
|
||||
OS << "\n";
|
||||
|
@ -291,7 +291,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
|
||||
OS << " Live Ins:";
|
||||
for (const auto &LI : make_range(livein_begin(), livein_end())) {
|
||||
OS << ' ' << PrintReg(LI.PhysReg, TRI);
|
||||
if (LI.LaneMask != ~0u)
|
||||
if (!LI.LaneMask.all())
|
||||
OS << ':' << PrintLaneMask(LI.LaneMask);
|
||||
}
|
||||
OS << '\n';
|
||||
@ -342,14 +342,14 @@ void MachineBasicBlock::removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) {
|
||||
return;
|
||||
|
||||
I->LaneMask &= ~LaneMask;
|
||||
if (I->LaneMask == 0)
|
||||
if (I->LaneMask.none())
|
||||
LiveIns.erase(I);
|
||||
}
|
||||
|
||||
bool MachineBasicBlock::isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask) const {
|
||||
livein_iterator I = find_if(
|
||||
LiveIns, [Reg](const RegisterMaskPair &LI) { return LI.PhysReg == Reg; });
|
||||
return I != livein_end() && (I->LaneMask & LaneMask) != 0;
|
||||
return I != livein_end() && !(I->LaneMask & LaneMask).none();
|
||||
}
|
||||
|
||||
void MachineBasicBlock::sortUniqueLiveIns() {
|
||||
|
@ -1742,11 +1742,13 @@ static void computeLiveOuts(MachineFunction &MF, RegPressureTracker &RPTracker,
|
||||
unsigned Reg = MO.getReg();
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
if (!Uses.count(Reg))
|
||||
LiveOutRegs.push_back(RegisterMaskPair(Reg, 0));
|
||||
LiveOutRegs.push_back(RegisterMaskPair(Reg,
|
||||
LaneBitmask::getNone()));
|
||||
} else if (MRI.isAllocatable(Reg)) {
|
||||
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
|
||||
if (!Uses.count(*Units))
|
||||
LiveOutRegs.push_back(RegisterMaskPair(*Units, 0));
|
||||
LiveOutRegs.push_back(RegisterMaskPair(*Units,
|
||||
LaneBitmask::getNone()));
|
||||
}
|
||||
}
|
||||
RPTracker.addLiveRegs(LiveOutRegs);
|
||||
|
@ -894,7 +894,7 @@ void ScheduleDAGMILive::collectVRegUses(SUnit &SU) {
|
||||
break;
|
||||
}
|
||||
if (UI == VRegUses.end())
|
||||
VRegUses.insert(VReg2SUnit(Reg, 0, &SU));
|
||||
VRegUses.insert(VReg2SUnit(Reg, LaneBitmask::getNone(), &SU));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1040,7 +1040,7 @@ void ScheduleDAGMILive::updatePressureDiffs(
|
||||
// this fact anymore => decrement pressure.
|
||||
// If the register has just become dead then other uses make it come
|
||||
// back to life => increment pressure.
|
||||
bool Decrement = P.LaneMask != 0;
|
||||
bool Decrement = !P.LaneMask.none();
|
||||
|
||||
for (const VReg2SUnit &V2SU
|
||||
: make_range(VRegUses.find(Reg), VRegUses.end())) {
|
||||
@ -1059,7 +1059,7 @@ void ScheduleDAGMILive::updatePressureDiffs(
|
||||
);
|
||||
}
|
||||
} else {
|
||||
assert(P.LaneMask != 0);
|
||||
assert(!P.LaneMask.none());
|
||||
DEBUG(dbgs() << " LiveReg: " << PrintVRegOrUnit(Reg, TRI) << "\n");
|
||||
// This may be called before CurrentBottom has been initialized. However,
|
||||
// BotRPTracker must have a valid position. We want the value live into the
|
||||
|
@ -229,10 +229,10 @@ namespace {
|
||||
void checkLiveness(const MachineOperand *MO, unsigned MONum);
|
||||
void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
|
||||
SlotIndex UseIdx, const LiveRange &LR, unsigned Reg,
|
||||
LaneBitmask LaneMask = 0);
|
||||
LaneBitmask LaneMask = LaneBitmask::getNone());
|
||||
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
|
||||
SlotIndex DefIdx, const LiveRange &LR, unsigned Reg,
|
||||
LaneBitmask LaneMask = 0);
|
||||
LaneBitmask LaneMask = LaneBitmask::getNone());
|
||||
|
||||
void markReachable(const MachineBasicBlock *MBB);
|
||||
void calcRegsPassed();
|
||||
@ -243,11 +243,12 @@ namespace {
|
||||
void verifyLiveIntervals();
|
||||
void verifyLiveInterval(const LiveInterval&);
|
||||
void verifyLiveRangeValue(const LiveRange&, const VNInfo*, unsigned,
|
||||
unsigned);
|
||||
LaneBitmask);
|
||||
void verifyLiveRangeSegment(const LiveRange&,
|
||||
const LiveRange::const_iterator I, unsigned,
|
||||
unsigned);
|
||||
void verifyLiveRange(const LiveRange&, unsigned, LaneBitmask LaneMask = 0);
|
||||
LaneBitmask);
|
||||
void verifyLiveRange(const LiveRange&, unsigned,
|
||||
LaneBitmask LaneMask = LaneBitmask::getNone());
|
||||
|
||||
void verifyStackFrame();
|
||||
|
||||
@ -481,7 +482,7 @@ void MachineVerifier::report_context(const LiveRange &LR, unsigned VRegUnit,
|
||||
LaneBitmask LaneMask) const {
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegUnit);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
report_context_lanemask(LaneMask);
|
||||
}
|
||||
|
||||
@ -1161,7 +1162,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
|
||||
LiveQueryResult LRQ = LR.Query(UseIdx);
|
||||
// Check if we have a segment at the use, note however that we only need one
|
||||
// live subregister range, the others may be dead.
|
||||
if (!LRQ.valueIn() && LaneMask == 0) {
|
||||
if (!LRQ.valueIn() && LaneMask.none()) {
|
||||
report("No live segment at use", MO, MONum);
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegOrUnit);
|
||||
@ -1171,7 +1172,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
|
||||
report("Live range continues after kill flag", MO, MONum);
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegOrUnit);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
report_context_lanemask(LaneMask);
|
||||
report_context(UseIdx);
|
||||
}
|
||||
@ -1186,7 +1187,7 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
|
||||
report("Inconsistent valno->def", MO, MONum);
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegOrUnit);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
report_context_lanemask(LaneMask);
|
||||
report_context(*VNI);
|
||||
report_context(DefIdx);
|
||||
@ -1195,7 +1196,7 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
|
||||
report("No live segment at def", MO, MONum);
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegOrUnit);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
report_context_lanemask(LaneMask);
|
||||
report_context(DefIdx);
|
||||
}
|
||||
@ -1225,7 +1226,7 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
|
||||
report("Live range continues after dead def flag", MO, MONum);
|
||||
report_context_liverange(LR);
|
||||
report_context_vreg_regunit(VRegOrUnit);
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
report_context_lanemask(LaneMask);
|
||||
}
|
||||
}
|
||||
@ -1273,9 +1274,9 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
|
||||
LaneBitmask MOMask = SubRegIdx != 0
|
||||
? TRI->getSubRegIndexLaneMask(SubRegIdx)
|
||||
: MRI->getMaxLaneMaskForVReg(Reg);
|
||||
LaneBitmask LiveInMask = 0;
|
||||
LaneBitmask LiveInMask;
|
||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||
if ((MOMask & SR.LaneMask) == 0)
|
||||
if ((MOMask & SR.LaneMask).none())
|
||||
continue;
|
||||
checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask);
|
||||
LiveQueryResult LRQ = SR.Query(UseIdx);
|
||||
@ -1283,7 +1284,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
|
||||
LiveInMask |= SR.LaneMask;
|
||||
}
|
||||
// At least parts of the register has to be live at the use.
|
||||
if ((LiveInMask & MOMask) == 0) {
|
||||
if ((LiveInMask & MOMask).none()) {
|
||||
report("No live subrange at use", MO, MONum);
|
||||
report_context(LI);
|
||||
report_context(UseIdx);
|
||||
@ -1375,7 +1376,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
|
||||
? TRI->getSubRegIndexLaneMask(SubRegIdx)
|
||||
: MRI->getMaxLaneMaskForVReg(Reg);
|
||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||
if ((SR.LaneMask & MOMask) == 0)
|
||||
if ((SR.LaneMask & MOMask).none())
|
||||
continue;
|
||||
checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, SR.LaneMask);
|
||||
}
|
||||
@ -1688,8 +1689,8 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
|
||||
!TRI->hasRegUnit(MOI->getReg(), Reg))
|
||||
continue;
|
||||
}
|
||||
if (LaneMask != 0 &&
|
||||
(TRI->getSubRegIndexLaneMask(MOI->getSubReg()) & LaneMask) == 0)
|
||||
if (!LaneMask.none() &&
|
||||
(TRI->getSubRegIndexLaneMask(MOI->getSubReg()) & LaneMask).none())
|
||||
continue;
|
||||
hasDef = true;
|
||||
if (MOI->isEarlyClobber())
|
||||
@ -1821,7 +1822,8 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||
if (!MOI->isReg() || MOI->getReg() != Reg)
|
||||
continue;
|
||||
unsigned Sub = MOI->getSubReg();
|
||||
LaneBitmask SLM = Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) : ~0U;
|
||||
LaneBitmask SLM = Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub)
|
||||
: LaneBitmask::getAll();
|
||||
if (MOI->isDef()) {
|
||||
if (Sub != 0) {
|
||||
hasSubRegDef = true;
|
||||
@ -1833,7 +1835,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||
if (MOI->isDead())
|
||||
hasDeadDef = true;
|
||||
}
|
||||
if (LaneMask != 0 && !(LaneMask & SLM))
|
||||
if (!LaneMask.none() && (LaneMask & SLM).none())
|
||||
continue;
|
||||
if (MOI->readsReg())
|
||||
hasRead = true;
|
||||
@ -1842,7 +1844,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||
// Make sure that the corresponding machine operand for a "dead" live
|
||||
// range has the dead flag. We cannot perform this check for subregister
|
||||
// liveranges as partially dead values are allowed.
|
||||
if (LaneMask == 0 && !hasDeadDef) {
|
||||
if (LaneMask.none() && !hasDeadDef) {
|
||||
report("Instruction ending live segment on dead slot has no dead flag",
|
||||
MI);
|
||||
report_context(LR, Reg, LaneMask);
|
||||
@ -1852,7 +1854,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||
if (!hasRead) {
|
||||
// When tracking subregister liveness, the main range must start new
|
||||
// values on partial register writes, even if there is no read.
|
||||
if (!MRI->shouldTrackSubRegLiveness(Reg) || LaneMask != 0 ||
|
||||
if (!MRI->shouldTrackSubRegLiveness(Reg) || !LaneMask.none() ||
|
||||
!hasSubRegDef) {
|
||||
report("Instruction ending live segment doesn't read the register",
|
||||
MI);
|
||||
@ -1896,7 +1898,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
|
||||
|
||||
// All predecessors must have a live-out value if this is not a
|
||||
// subregister liverange.
|
||||
if (!PVNI && LaneMask == 0) {
|
||||
if (!PVNI && LaneMask.none()) {
|
||||
report("Register not marked live out of predecessor", *PI);
|
||||
report_context(LR, Reg, LaneMask);
|
||||
report_context(*VNI);
|
||||
@ -1936,14 +1938,14 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
|
||||
assert(TargetRegisterInfo::isVirtualRegister(Reg));
|
||||
verifyLiveRange(LI, Reg);
|
||||
|
||||
LaneBitmask Mask = 0;
|
||||
LaneBitmask Mask;
|
||||
LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
|
||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||
if ((Mask & SR.LaneMask) != 0) {
|
||||
if (!(Mask & SR.LaneMask).none()) {
|
||||
report("Lane masks of sub ranges overlap in live interval", MF);
|
||||
report_context(LI);
|
||||
}
|
||||
if ((SR.LaneMask & ~MaxMask) != 0) {
|
||||
if (!(SR.LaneMask & ~MaxMask).none()) {
|
||||
report("Subrange lanemask is invalid", MF);
|
||||
report_context(LI);
|
||||
}
|
||||
|
@ -1833,8 +1833,8 @@ ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
|
||||
// sub-register we are tracking.
|
||||
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
|
||||
if (!TRI ||
|
||||
(TRI->getSubRegIndexLaneMask(DefSubReg) &
|
||||
TRI->getSubRegIndexLaneMask(InsertedReg.SubIdx)) != 0)
|
||||
!(TRI->getSubRegIndexLaneMask(DefSubReg) &
|
||||
TRI->getSubRegIndexLaneMask(InsertedReg.SubIdx)).none())
|
||||
return ValueTrackerResult();
|
||||
// At this point, the value is available in v0 via the same subreg
|
||||
// we used for Def.
|
||||
|
@ -815,14 +815,14 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
||||
for (LiveInterval::SubRange &SB : IntB.subranges()) {
|
||||
LaneBitmask BMask = SB.LaneMask;
|
||||
LaneBitmask Common = BMask & AMask;
|
||||
if (Common == 0)
|
||||
if (Common.none())
|
||||
continue;
|
||||
|
||||
DEBUG( dbgs() << "\t\tCopy_Merge " << PrintLaneMask(BMask)
|
||||
<< " into " << PrintLaneMask(Common) << '\n');
|
||||
LaneBitmask BRest = BMask & ~AMask;
|
||||
LiveInterval::SubRange *CommonRange;
|
||||
if (BRest != 0) {
|
||||
if (!BRest.none()) {
|
||||
SB.LaneMask = BRest;
|
||||
DEBUG(dbgs() << "\t\tReduce Lane to " << PrintLaneMask(BRest)
|
||||
<< '\n');
|
||||
@ -841,7 +841,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
||||
addSegmentsWithValNo(*CommonRange, BSubValNo, SA, ASubValNo);
|
||||
AMask &= ~BMask;
|
||||
}
|
||||
if (AMask != 0) {
|
||||
if (!AMask.none()) {
|
||||
DEBUG(dbgs() << "\t\tNew Lane " << PrintLaneMask(AMask) << '\n');
|
||||
LiveRange *NewRange = IntB.createSubRange(Allocator, AMask);
|
||||
VNInfo *BSubValNo = NewRange->getNextValue(CopyIdx, Allocator);
|
||||
@ -1061,7 +1061,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
||||
SR.createDeadDef(DefIndex, Alloc);
|
||||
MaxMask &= ~SR.LaneMask;
|
||||
}
|
||||
if (MaxMask != 0) {
|
||||
if (!MaxMask.none()) {
|
||||
LiveInterval::SubRange *SR = DstInt.createSubRange(Alloc, MaxMask);
|
||||
SR->createDeadDef(DefIndex, Alloc);
|
||||
}
|
||||
@ -1154,7 +1154,7 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||
if (SrcSubIdx != 0 && SrcLI.hasSubRanges()) {
|
||||
LaneBitmask SrcMask = TRI->getSubRegIndexLaneMask(SrcSubIdx);
|
||||
for (const LiveInterval::SubRange &SR : SrcLI.subranges()) {
|
||||
if ((SR.LaneMask & SrcMask) == 0)
|
||||
if ((SR.LaneMask & SrcMask).none())
|
||||
continue;
|
||||
if (SR.liveAt(Idx))
|
||||
return false;
|
||||
@ -1175,7 +1175,7 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||
// The affected subregister segments can be removed.
|
||||
LaneBitmask DstMask = TRI->getSubRegIndexLaneMask(DstSubIdx);
|
||||
for (LiveInterval::SubRange &SR : DstLI.subranges()) {
|
||||
if ((SR.LaneMask & DstMask) == 0)
|
||||
if ((SR.LaneMask & DstMask).none())
|
||||
continue;
|
||||
|
||||
VNInfo *SVNI = SR.getVNInfoAt(RegIndex);
|
||||
@ -1194,10 +1194,10 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI) {
|
||||
SlotIndex UseIdx = LIS->getInstructionIndex(MI);
|
||||
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
|
||||
bool isLive;
|
||||
if (UseMask != ~0u && DstLI.hasSubRanges()) {
|
||||
if (!UseMask.all() && DstLI.hasSubRanges()) {
|
||||
isLive = false;
|
||||
for (const LiveInterval::SubRange &SR : DstLI.subranges()) {
|
||||
if ((SR.LaneMask & UseMask) == 0)
|
||||
if ((SR.LaneMask & UseMask).none())
|
||||
continue;
|
||||
if (SR.liveAt(UseIdx)) {
|
||||
isLive = true;
|
||||
@ -1232,7 +1232,7 @@ void RegisterCoalescer::addUndefFlag(const LiveInterval &Int, SlotIndex UseIdx,
|
||||
Mask = ~Mask;
|
||||
bool IsUndef = true;
|
||||
for (const LiveInterval::SubRange &S : Int.subranges()) {
|
||||
if ((S.LaneMask & Mask) == 0)
|
||||
if ((S.LaneMask & Mask).none())
|
||||
continue;
|
||||
if (S.liveAt(UseIdx)) {
|
||||
IsUndef = false;
|
||||
@ -1458,7 +1458,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
|
||||
});
|
||||
}
|
||||
|
||||
ShrinkMask = 0;
|
||||
ShrinkMask = LaneBitmask::getNone();
|
||||
ShrinkMainRange = false;
|
||||
|
||||
// Okay, attempt to join these two intervals. On failure, this returns false.
|
||||
@ -1516,10 +1516,10 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
|
||||
updateRegDefsUses(CP.getSrcReg(), CP.getDstReg(), CP.getSrcIdx());
|
||||
|
||||
// Shrink subregister ranges if necessary.
|
||||
if (ShrinkMask != 0) {
|
||||
if (!ShrinkMask.none()) {
|
||||
LiveInterval &LI = LIS->getInterval(CP.getDstReg());
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
if ((S.LaneMask & ShrinkMask) == 0)
|
||||
if ((S.LaneMask & ShrinkMask).none())
|
||||
continue;
|
||||
DEBUG(dbgs() << "Shrink LaneUses (Lane " << PrintLaneMask(S.LaneMask)
|
||||
<< ")\n");
|
||||
@ -1817,11 +1817,11 @@ class JoinVals {
|
||||
/// True once Pruned above has been computed.
|
||||
bool PrunedComputed;
|
||||
|
||||
Val() : Resolution(CR_Keep), WriteLanes(0), ValidLanes(0),
|
||||
Val() : Resolution(CR_Keep), WriteLanes(), ValidLanes(),
|
||||
RedefVNI(nullptr), OtherVNI(nullptr), ErasableImplicitDef(false),
|
||||
Pruned(false), PrunedComputed(false) {}
|
||||
|
||||
bool isAnalyzed() const { return WriteLanes != 0; }
|
||||
bool isAnalyzed() const { return !WriteLanes.none(); }
|
||||
};
|
||||
|
||||
/// One entry per value number in LI.
|
||||
@ -1938,7 +1938,7 @@ public:
|
||||
|
||||
LaneBitmask JoinVals::computeWriteLanes(const MachineInstr *DefMI, bool &Redef)
|
||||
const {
|
||||
LaneBitmask L = 0;
|
||||
LaneBitmask L;
|
||||
for (const MachineOperand &MO : DefMI->operands()) {
|
||||
if (!MO.isReg() || MO.getReg() != Reg || !MO.isDef())
|
||||
continue;
|
||||
@ -1976,7 +1976,7 @@ std::pair<const VNInfo*, unsigned> JoinVals::followCopyChain(
|
||||
for (const LiveInterval::SubRange &S : LI.subranges()) {
|
||||
// Transform lanemask to a mask in the joined live interval.
|
||||
LaneBitmask SMask = TRI->composeSubRegIndexLaneMask(SubIdx, S.LaneMask);
|
||||
if ((SMask & LaneMask) == 0)
|
||||
if ((SMask & LaneMask).none())
|
||||
continue;
|
||||
LiveQueryResult LRQ = S.Query(Def);
|
||||
ValueIn = LRQ.valueIn();
|
||||
@ -2016,7 +2016,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
assert(!V.isAnalyzed() && "Value has already been analyzed!");
|
||||
VNInfo *VNI = LR.getValNumInfo(ValNo);
|
||||
if (VNI->isUnused()) {
|
||||
V.WriteLanes = ~0u;
|
||||
V.WriteLanes = LaneBitmask::getAll();
|
||||
return CR_Keep;
|
||||
}
|
||||
|
||||
@ -2024,16 +2024,17 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
const MachineInstr *DefMI = nullptr;
|
||||
if (VNI->isPHIDef()) {
|
||||
// Conservatively assume that all lanes in a PHI are valid.
|
||||
LaneBitmask Lanes = SubRangeJoin ? 1 : TRI->getSubRegIndexLaneMask(SubIdx);
|
||||
LaneBitmask Lanes = SubRangeJoin ? LaneBitmask(1)
|
||||
: TRI->getSubRegIndexLaneMask(SubIdx);
|
||||
V.ValidLanes = V.WriteLanes = Lanes;
|
||||
} else {
|
||||
DefMI = Indexes->getInstructionFromIndex(VNI->def);
|
||||
assert(DefMI != nullptr);
|
||||
if (SubRangeJoin) {
|
||||
// We don't care about the lanes when joining subregister ranges.
|
||||
V.WriteLanes = V.ValidLanes = 1;
|
||||
V.WriteLanes = V.ValidLanes = LaneBitmask(1);
|
||||
if (DefMI->isImplicitDef()) {
|
||||
V.ValidLanes = 0;
|
||||
V.ValidLanes = LaneBitmask::getNone();
|
||||
V.ErasableImplicitDef = true;
|
||||
}
|
||||
} else {
|
||||
@ -2106,7 +2107,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
// predecessor, the PHI itself can't introduce any conflicts.
|
||||
if (VNI->isPHIDef())
|
||||
return CR_Merge;
|
||||
if (V.ValidLanes & OtherV.ValidLanes)
|
||||
if (!(V.ValidLanes & OtherV.ValidLanes).none())
|
||||
// Overlapping lanes can't be resolved.
|
||||
return CR_Impossible;
|
||||
else
|
||||
@ -2151,7 +2152,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
// We need the def for the subregister if there is nothing else live at the
|
||||
// subrange at this point.
|
||||
if (TrackSubRegLiveness
|
||||
&& (V.WriteLanes & (OtherV.ValidLanes | OtherV.WriteLanes)) == 0)
|
||||
&& (V.WriteLanes & (OtherV.ValidLanes | OtherV.WriteLanes)).none())
|
||||
return CR_Replace;
|
||||
return CR_Erase;
|
||||
}
|
||||
@ -2191,7 +2192,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
//
|
||||
// Here OtherVNI will map to itself in [1;2), but to VNI in [2;5). CR_Replace
|
||||
// handles this complex value mapping.
|
||||
if ((V.WriteLanes & OtherV.ValidLanes) == 0)
|
||||
if ((V.WriteLanes & OtherV.ValidLanes).none())
|
||||
return CR_Replace;
|
||||
|
||||
// If the other live range is killed by DefMI and the live ranges are still
|
||||
@ -2212,7 +2213,7 @@ JoinVals::analyzeValue(unsigned ValNo, JoinVals &Other) {
|
||||
// possibility that no instructions actually read the clobbered lanes.
|
||||
// If we're clobbering all the lanes in OtherVNI, at least one must be read.
|
||||
// Otherwise Other.RI wouldn't be live here.
|
||||
if ((TRI->getSubRegIndexLaneMask(Other.SubIdx) & ~V.WriteLanes) == 0)
|
||||
if ((TRI->getSubRegIndexLaneMask(Other.SubIdx) & ~V.WriteLanes).none())
|
||||
return CR_Impossible;
|
||||
|
||||
// We need to verify that no instructions are reading the clobbered lanes. To
|
||||
@ -2260,7 +2261,7 @@ void JoinVals::computeAssignment(unsigned ValNo, JoinVals &Other) {
|
||||
Val &OtherV = Other.Vals[V.OtherVNI->id];
|
||||
// We cannot erase an IMPLICIT_DEF if we don't have valid values for all
|
||||
// its lanes.
|
||||
if ((OtherV.WriteLanes & ~V.ValidLanes) != 0 && TrackSubRegLiveness)
|
||||
if (!(OtherV.WriteLanes & ~V.ValidLanes).none() && TrackSubRegLiveness)
|
||||
OtherV.ErasableImplicitDef = false;
|
||||
OtherV.Pruned = true;
|
||||
LLVM_FALLTHROUGH;
|
||||
@ -2321,7 +2322,7 @@ taintExtent(unsigned ValNo, LaneBitmask TaintedLanes, JoinVals &Other,
|
||||
TaintedLanes &= ~OV.WriteLanes;
|
||||
if (!OV.RedefVNI)
|
||||
break;
|
||||
} while (TaintedLanes);
|
||||
} while (!TaintedLanes.none());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2334,8 +2335,8 @@ bool JoinVals::usesLanes(const MachineInstr &MI, unsigned Reg, unsigned SubIdx,
|
||||
continue;
|
||||
if (!MO.readsReg())
|
||||
continue;
|
||||
if (Lanes & TRI->getSubRegIndexLaneMask(
|
||||
TRI->composeSubRegIndices(SubIdx, MO.getSubReg())))
|
||||
unsigned S = TRI->composeSubRegIndices(SubIdx, MO.getSubReg());
|
||||
if (!(Lanes & TRI->getSubRegIndexLaneMask(S)).none())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -2722,7 +2723,7 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
||||
// LaneMask of subregisters common to subrange R and ToMerge.
|
||||
LaneBitmask Common = RMask & LaneMask;
|
||||
// There is nothing to do without common subregs.
|
||||
if (Common == 0)
|
||||
if (Common.none())
|
||||
continue;
|
||||
|
||||
DEBUG(dbgs() << "\t\tCopy+Merge " << PrintLaneMask(RMask) << " into "
|
||||
@ -2731,7 +2732,7 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
||||
// they have to split into their own subrange.
|
||||
LaneBitmask LRest = RMask & ~LaneMask;
|
||||
LiveInterval::SubRange *CommonRange;
|
||||
if (LRest != 0) {
|
||||
if (!LRest.none()) {
|
||||
R.LaneMask = LRest;
|
||||
DEBUG(dbgs() << "\t\tReduce Lane to " << PrintLaneMask(LRest) << '\n');
|
||||
// Duplicate SubRange for newly merged common stuff.
|
||||
@ -2746,7 +2747,7 @@ void RegisterCoalescer::mergeSubRangeInto(LiveInterval &LI,
|
||||
LaneMask &= ~RMask;
|
||||
}
|
||||
|
||||
if (LaneMask != 0) {
|
||||
if (!LaneMask.none()) {
|
||||
DEBUG(dbgs() << "\t\tNew Lane " << PrintLaneMask(LaneMask) << '\n');
|
||||
LI.createSubRangeFrom(Allocator, LaneMask, ToMerge);
|
||||
}
|
||||
@ -2757,10 +2758,10 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
||||
LiveInterval &RHS = LIS->getInterval(CP.getSrcReg());
|
||||
LiveInterval &LHS = LIS->getInterval(CP.getDstReg());
|
||||
bool TrackSubRegLiveness = MRI->shouldTrackSubRegLiveness(*CP.getNewRC());
|
||||
JoinVals RHSVals(RHS, CP.getSrcReg(), CP.getSrcIdx(), 0, NewVNInfo, CP, LIS,
|
||||
TRI, false, TrackSubRegLiveness);
|
||||
JoinVals LHSVals(LHS, CP.getDstReg(), CP.getDstIdx(), 0, NewVNInfo, CP, LIS,
|
||||
TRI, false, TrackSubRegLiveness);
|
||||
JoinVals RHSVals(RHS, CP.getSrcReg(), CP.getSrcIdx(), LaneBitmask::getNone(),
|
||||
NewVNInfo, CP, LIS, TRI, false, TrackSubRegLiveness);
|
||||
JoinVals LHSVals(LHS, CP.getDstReg(), CP.getDstIdx(), LaneBitmask::getNone(),
|
||||
NewVNInfo, CP, LIS, TRI, false, TrackSubRegLiveness);
|
||||
|
||||
DEBUG(dbgs() << "\t\tRHS = " << RHS
|
||||
<< "\n\t\tLHS = " << LHS
|
||||
@ -2786,7 +2787,7 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
||||
LaneBitmask Mask = DstIdx == 0 ? CP.getNewRC()->getLaneMask()
|
||||
: TRI->getSubRegIndexLaneMask(DstIdx);
|
||||
// LHS must support subregs or we wouldn't be in this codepath.
|
||||
assert(Mask != 0);
|
||||
assert(!Mask.none());
|
||||
LHS.createSubRangeFrom(Allocator, Mask, LHS);
|
||||
} else if (DstIdx != 0) {
|
||||
// Transform LHS lanemasks to new register class if necessary.
|
||||
@ -3166,7 +3167,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
|
||||
// If subranges are still supported, then the same subregs
|
||||
// should still be supported.
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
assert((S.LaneMask & ~MaxMask) == 0);
|
||||
assert((S.LaneMask & ~MaxMask).none());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ using namespace llvm;
|
||||
static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
|
||||
const MachineRegisterInfo &MRI, unsigned Reg,
|
||||
LaneBitmask PrevMask, LaneBitmask NewMask) {
|
||||
assert((PrevMask & ~NewMask) == 0 && "Must not remove bits");
|
||||
if (PrevMask != 0 || NewMask == 0)
|
||||
assert((PrevMask & ~NewMask).none() && "Must not remove bits");
|
||||
if (!PrevMask.none() || NewMask.none())
|
||||
return;
|
||||
|
||||
PSetIterator PSetI = MRI.getPressureSets(Reg);
|
||||
@ -40,8 +40,8 @@ static void increaseSetPressure(std::vector<unsigned> &CurrSetPressure,
|
||||
static void decreaseSetPressure(std::vector<unsigned> &CurrSetPressure,
|
||||
const MachineRegisterInfo &MRI, unsigned Reg,
|
||||
LaneBitmask PrevMask, LaneBitmask NewMask) {
|
||||
assert((NewMask & !PrevMask) == 0 && "Must not add bits");
|
||||
if (NewMask != 0 || PrevMask == 0)
|
||||
//assert((NewMask & !PrevMask) == 0 && "Must not add bits");
|
||||
if (!NewMask.none() || PrevMask.none())
|
||||
return;
|
||||
|
||||
PSetIterator PSetI = MRI.getPressureSets(Reg);
|
||||
@ -73,7 +73,7 @@ void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
|
||||
dbgs() << "Live In: ";
|
||||
for (const RegisterMaskPair &P : LiveInRegs) {
|
||||
dbgs() << PrintVRegOrUnit(P.RegUnit, TRI);
|
||||
if (P.LaneMask != ~0u)
|
||||
if (!P.LaneMask.all())
|
||||
dbgs() << ':' << PrintLaneMask(P.LaneMask);
|
||||
dbgs() << ' ';
|
||||
}
|
||||
@ -81,7 +81,7 @@ void RegisterPressure::dump(const TargetRegisterInfo *TRI) const {
|
||||
dbgs() << "Live Out: ";
|
||||
for (const RegisterMaskPair &P : LiveOutRegs) {
|
||||
dbgs() << PrintVRegOrUnit(P.RegUnit, TRI);
|
||||
if (P.LaneMask != ~0u)
|
||||
if (!P.LaneMask.all())
|
||||
dbgs() << ':' << PrintLaneMask(P.LaneMask);
|
||||
dbgs() << ' ';
|
||||
}
|
||||
@ -112,7 +112,7 @@ void PressureDiff::dump(const TargetRegisterInfo &TRI) const {
|
||||
void RegPressureTracker::increaseRegPressure(unsigned RegUnit,
|
||||
LaneBitmask PreviousMask,
|
||||
LaneBitmask NewMask) {
|
||||
if (PreviousMask != 0 || NewMask == 0)
|
||||
if (!PreviousMask.none() || NewMask.none())
|
||||
return;
|
||||
|
||||
PSetIterator PSetI = MRI->getPressureSets(RegUnit);
|
||||
@ -322,7 +322,8 @@ void RegPressureTracker::initLiveThru(const RegPressureTracker &RPTracker) {
|
||||
unsigned RegUnit = Pair.RegUnit;
|
||||
if (TargetRegisterInfo::isVirtualRegister(RegUnit)
|
||||
&& !RPTracker.hasUntiedDef(RegUnit))
|
||||
increaseSetPressure(LiveThruPressure, *MRI, RegUnit, 0, Pair.LaneMask);
|
||||
increaseSetPressure(LiveThruPressure, *MRI, RegUnit,
|
||||
LaneBitmask::getNone(), Pair.LaneMask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,14 +333,14 @@ static LaneBitmask getRegLanes(ArrayRef<RegisterMaskPair> RegUnits,
|
||||
return Other.RegUnit == RegUnit;
|
||||
});
|
||||
if (I == RegUnits.end())
|
||||
return 0;
|
||||
return LaneBitmask::getNone();
|
||||
return I->LaneMask;
|
||||
}
|
||||
|
||||
static void addRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
|
||||
RegisterMaskPair Pair) {
|
||||
unsigned RegUnit = Pair.RegUnit;
|
||||
assert(Pair.LaneMask != 0);
|
||||
assert(!Pair.LaneMask.none());
|
||||
auto I = find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
|
||||
return Other.RegUnit == RegUnit;
|
||||
});
|
||||
@ -356,22 +357,22 @@ static void setRegZero(SmallVectorImpl<RegisterMaskPair> &RegUnits,
|
||||
return Other.RegUnit == RegUnit;
|
||||
});
|
||||
if (I == RegUnits.end()) {
|
||||
RegUnits.push_back(RegisterMaskPair(RegUnit, 0));
|
||||
RegUnits.push_back(RegisterMaskPair(RegUnit, LaneBitmask::getNone()));
|
||||
} else {
|
||||
I->LaneMask = 0;
|
||||
I->LaneMask = LaneBitmask::getNone();
|
||||
}
|
||||
}
|
||||
|
||||
static void removeRegLanes(SmallVectorImpl<RegisterMaskPair> &RegUnits,
|
||||
RegisterMaskPair Pair) {
|
||||
unsigned RegUnit = Pair.RegUnit;
|
||||
assert(Pair.LaneMask != 0);
|
||||
assert(!Pair.LaneMask.none());
|
||||
auto I = find_if(RegUnits, [RegUnit](const RegisterMaskPair Other) {
|
||||
return Other.RegUnit == RegUnit;
|
||||
});
|
||||
if (I != RegUnits.end()) {
|
||||
I->LaneMask &= ~Pair.LaneMask;
|
||||
if (I->LaneMask == 0)
|
||||
if (I->LaneMask.none())
|
||||
RegUnits.erase(I);
|
||||
}
|
||||
}
|
||||
@ -382,14 +383,15 @@ static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
|
||||
bool(*Property)(const LiveRange &LR, SlotIndex Pos)) {
|
||||
if (TargetRegisterInfo::isVirtualRegister(RegUnit)) {
|
||||
const LiveInterval &LI = LIS.getInterval(RegUnit);
|
||||
LaneBitmask Result = 0;
|
||||
LaneBitmask Result;
|
||||
if (TrackLaneMasks && LI.hasSubRanges()) {
|
||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||
if (Property(SR, Pos))
|
||||
Result |= SR.LaneMask;
|
||||
}
|
||||
} else if (Property(LI, Pos)) {
|
||||
Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit) : ~0u;
|
||||
Result = TrackLaneMasks ? MRI.getMaxLaneMaskForVReg(RegUnit)
|
||||
: LaneBitmask::getAll();
|
||||
}
|
||||
|
||||
return Result;
|
||||
@ -399,7 +401,7 @@ static LaneBitmask getLanesWithProperty(const LiveIntervals &LIS,
|
||||
// for physical registers on targets with many registers (GPUs).
|
||||
if (LR == nullptr)
|
||||
return SafeDefault;
|
||||
return Property(*LR, Pos) ? ~0u : 0;
|
||||
return Property(*LR, Pos) ? LaneBitmask::getAll() : LaneBitmask::getNone();
|
||||
}
|
||||
}
|
||||
|
||||
@ -407,7 +409,8 @@ static LaneBitmask getLiveLanesAt(const LiveIntervals &LIS,
|
||||
const MachineRegisterInfo &MRI,
|
||||
bool TrackLaneMasks, unsigned RegUnit,
|
||||
SlotIndex Pos) {
|
||||
return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
|
||||
return getLanesWithProperty(LIS, MRI, TrackLaneMasks, RegUnit, Pos,
|
||||
LaneBitmask::getAll(),
|
||||
[](const LiveRange &LR, SlotIndex Pos) {
|
||||
return LR.liveAt(Pos);
|
||||
});
|
||||
@ -474,10 +477,10 @@ class RegisterOperandsCollector {
|
||||
void pushReg(unsigned Reg,
|
||||
SmallVectorImpl<RegisterMaskPair> &RegUnits) const {
|
||||
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
|
||||
addRegLanes(RegUnits, RegisterMaskPair(Reg, ~0u));
|
||||
addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneBitmask::getAll()));
|
||||
} else if (MRI.isAllocatable(Reg)) {
|
||||
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
|
||||
addRegLanes(RegUnits, RegisterMaskPair(*Units, ~0u));
|
||||
addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -512,7 +515,7 @@ class RegisterOperandsCollector {
|
||||
addRegLanes(RegUnits, RegisterMaskPair(Reg, LaneMask));
|
||||
} else if (MRI.isAllocatable(Reg)) {
|
||||
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
|
||||
addRegLanes(RegUnits, RegisterMaskPair(*Units, ~0u));
|
||||
addRegLanes(RegUnits, RegisterMaskPair(*Units, LaneBitmask::getAll()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -563,11 +566,11 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
|
||||
// of a subregister def we need a read-undef flag.
|
||||
unsigned RegUnit = I->RegUnit;
|
||||
if (TargetRegisterInfo::isVirtualRegister(RegUnit) &&
|
||||
AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask) == 0)
|
||||
AddFlagsMI != nullptr && (LiveAfter & ~I->LaneMask).none())
|
||||
AddFlagsMI->setRegisterDefReadUndef(RegUnit);
|
||||
|
||||
LaneBitmask ActualDef = I->LaneMask & LiveAfter;
|
||||
if (ActualDef == 0) {
|
||||
if (ActualDef.none()) {
|
||||
I = Defs.erase(I);
|
||||
} else {
|
||||
I->LaneMask = ActualDef;
|
||||
@ -578,7 +581,7 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
|
||||
LaneBitmask LiveBefore = getLiveLanesAt(LIS, MRI, true, I->RegUnit,
|
||||
Pos.getBaseIndex());
|
||||
LaneBitmask LaneMask = I->LaneMask & LiveBefore;
|
||||
if (LaneMask == 0) {
|
||||
if (LaneMask.none()) {
|
||||
I = Uses.erase(I);
|
||||
} else {
|
||||
I->LaneMask = LaneMask;
|
||||
@ -592,7 +595,7 @@ void RegisterOperands::adjustLaneLiveness(const LiveIntervals &LIS,
|
||||
continue;
|
||||
LaneBitmask LiveAfter = getLiveLanesAt(LIS, MRI, true, RegUnit,
|
||||
Pos.getDeadSlot());
|
||||
if (LiveAfter == 0)
|
||||
if (LiveAfter.none())
|
||||
AddFlagsMI->setRegisterDefReadUndef(RegUnit);
|
||||
}
|
||||
}
|
||||
@ -669,7 +672,7 @@ void RegPressureTracker::addLiveRegs(ArrayRef<RegisterMaskPair> Regs) {
|
||||
|
||||
void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
|
||||
SmallVectorImpl<RegisterMaskPair> &LiveInOrOut) {
|
||||
assert(Pair.LaneMask != 0);
|
||||
assert(!Pair.LaneMask.none());
|
||||
|
||||
unsigned RegUnit = Pair.RegUnit;
|
||||
auto I = find_if(LiveInOrOut, [RegUnit](const RegisterMaskPair &Other) {
|
||||
@ -678,7 +681,7 @@ void RegPressureTracker::discoverLiveInOrOut(RegisterMaskPair Pair,
|
||||
LaneBitmask PrevMask;
|
||||
LaneBitmask NewMask;
|
||||
if (I == LiveInOrOut.end()) {
|
||||
PrevMask = 0;
|
||||
PrevMask = LaneBitmask::getNone();
|
||||
NewMask = Pair.LaneMask;
|
||||
LiveInOrOut.push_back(Pair);
|
||||
} else {
|
||||
@ -733,14 +736,15 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
LaneBitmask NewMask = PreviousMask & ~Def.LaneMask;
|
||||
|
||||
LaneBitmask LiveOut = Def.LaneMask & ~PreviousMask;
|
||||
if (LiveOut != 0) {
|
||||
if (!LiveOut.none()) {
|
||||
discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
|
||||
// Retroactively model effects on pressure of the live out lanes.
|
||||
increaseSetPressure(CurrSetPressure, *MRI, Reg, 0, LiveOut);
|
||||
increaseSetPressure(CurrSetPressure, *MRI, Reg, LaneBitmask::getNone(),
|
||||
LiveOut);
|
||||
PreviousMask = LiveOut;
|
||||
}
|
||||
|
||||
if (NewMask == 0) {
|
||||
if (NewMask.none()) {
|
||||
// Add a 0 entry to LiveUses as a marker that the complete vreg has become
|
||||
// dead.
|
||||
if (TrackLaneMasks && LiveUses != nullptr)
|
||||
@ -757,14 +761,14 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
// Generate liveness for uses.
|
||||
for (const RegisterMaskPair &Use : RegOpers.Uses) {
|
||||
unsigned Reg = Use.RegUnit;
|
||||
assert(Use.LaneMask != 0);
|
||||
assert(!Use.LaneMask.none());
|
||||
LaneBitmask PreviousMask = LiveRegs.insert(Use);
|
||||
LaneBitmask NewMask = PreviousMask | Use.LaneMask;
|
||||
if (NewMask == PreviousMask)
|
||||
continue;
|
||||
|
||||
// Did the register just become live?
|
||||
if (PreviousMask == 0) {
|
||||
if (PreviousMask.none()) {
|
||||
if (LiveUses != nullptr) {
|
||||
if (!TrackLaneMasks) {
|
||||
addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
|
||||
@ -775,7 +779,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
bool IsRedef = I != LiveUses->end();
|
||||
if (IsRedef) {
|
||||
// ignore re-defs here...
|
||||
assert(I->LaneMask == 0);
|
||||
assert(I->LaneMask.none());
|
||||
removeRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
|
||||
} else {
|
||||
addRegLanes(*LiveUses, RegisterMaskPair(Reg, NewMask));
|
||||
@ -786,7 +790,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
// Discover live outs if this may be the first occurance of this register.
|
||||
if (RequireIntervals) {
|
||||
LaneBitmask LiveOut = getLiveThroughAt(Reg, SlotIdx);
|
||||
if (LiveOut != 0)
|
||||
if (!LiveOut.none())
|
||||
discoverLiveOut(RegisterMaskPair(Reg, LiveOut));
|
||||
}
|
||||
}
|
||||
@ -797,7 +801,7 @@ void RegPressureTracker::recede(const RegisterOperands &RegOpers,
|
||||
for (const RegisterMaskPair &Def : RegOpers.Defs) {
|
||||
unsigned RegUnit = Def.RegUnit;
|
||||
if (TargetRegisterInfo::isVirtualRegister(RegUnit) &&
|
||||
(LiveRegs.contains(RegUnit) & Def.LaneMask) == 0)
|
||||
(LiveRegs.contains(RegUnit) & Def.LaneMask).none())
|
||||
UntiedDefs.insert(RegUnit);
|
||||
}
|
||||
}
|
||||
@ -865,7 +869,7 @@ void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
|
||||
unsigned Reg = Use.RegUnit;
|
||||
LaneBitmask LiveMask = LiveRegs.contains(Reg);
|
||||
LaneBitmask LiveIn = Use.LaneMask & ~LiveMask;
|
||||
if (LiveIn != 0) {
|
||||
if (!LiveIn.none()) {
|
||||
discoverLiveIn(RegisterMaskPair(Reg, LiveIn));
|
||||
increaseRegPressure(Reg, LiveMask, LiveMask | LiveIn);
|
||||
LiveRegs.insert(RegisterMaskPair(Reg, LiveIn));
|
||||
@ -873,7 +877,7 @@ void RegPressureTracker::advance(const RegisterOperands &RegOpers) {
|
||||
// Kill liveness at last uses.
|
||||
if (RequireIntervals) {
|
||||
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
||||
if (LastUseMask != 0) {
|
||||
if (!LastUseMask.none()) {
|
||||
LiveRegs.erase(RegisterMaskPair(Reg, LastUseMask));
|
||||
decreaseRegPressure(Reg, LiveMask, LiveMask & ~LastUseMask);
|
||||
}
|
||||
@ -1186,8 +1190,8 @@ static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
|
||||
unsigned SubRegIdx = MO.getSubReg();
|
||||
LaneBitmask UseMask = TRI.getSubRegIndexLaneMask(SubRegIdx);
|
||||
LastUseMask &= ~UseMask;
|
||||
if (LastUseMask == 0)
|
||||
return 0;
|
||||
if (LastUseMask.none())
|
||||
return LaneBitmask::getNone();
|
||||
}
|
||||
}
|
||||
return LastUseMask;
|
||||
@ -1196,7 +1200,8 @@ static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
|
||||
LaneBitmask RegPressureTracker::getLiveLanesAt(unsigned RegUnit,
|
||||
SlotIndex Pos) const {
|
||||
assert(RequireIntervals);
|
||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, ~0u,
|
||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
|
||||
LaneBitmask::getAll(),
|
||||
[](const LiveRange &LR, SlotIndex Pos) {
|
||||
return LR.liveAt(Pos);
|
||||
});
|
||||
@ -1206,7 +1211,7 @@ LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
|
||||
SlotIndex Pos) const {
|
||||
assert(RequireIntervals);
|
||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit,
|
||||
Pos.getBaseIndex(), 0,
|
||||
Pos.getBaseIndex(), LaneBitmask::getNone(),
|
||||
[](const LiveRange &LR, SlotIndex Pos) {
|
||||
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
||||
return S != nullptr && S->end == Pos.getRegSlot();
|
||||
@ -1216,7 +1221,8 @@ LaneBitmask RegPressureTracker::getLastUsedLanes(unsigned RegUnit,
|
||||
LaneBitmask RegPressureTracker::getLiveThroughAt(unsigned RegUnit,
|
||||
SlotIndex Pos) const {
|
||||
assert(RequireIntervals);
|
||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos, 0u,
|
||||
return getLanesWithProperty(*LIS, *MRI, TrackLaneMasks, RegUnit, Pos,
|
||||
LaneBitmask::getNone(),
|
||||
[](const LiveRange &LR, SlotIndex Pos) {
|
||||
const LiveRange::Segment *S = LR.getSegmentContaining(Pos);
|
||||
return S != nullptr && S->start < Pos.getRegSlot(true) &&
|
||||
@ -1247,7 +1253,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
|
||||
for (const RegisterMaskPair &Use : RegOpers.Uses) {
|
||||
unsigned Reg = Use.RegUnit;
|
||||
LaneBitmask LastUseMask = getLastUsedLanes(Reg, SlotIdx);
|
||||
if (LastUseMask == 0)
|
||||
if (LastUseMask.none())
|
||||
continue;
|
||||
// The LastUseMask is queried from the liveness information of instruction
|
||||
// which may be further down the schedule. Some lanes may actually not be
|
||||
@ -1257,7 +1263,7 @@ void RegPressureTracker::bumpDownwardPressure(const MachineInstr *MI) {
|
||||
SlotIndex CurrIdx = getCurrSlot();
|
||||
LastUseMask
|
||||
= findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS);
|
||||
if (LastUseMask == 0)
|
||||
if (LastUseMask.none())
|
||||
continue;
|
||||
|
||||
LaneBitmask LiveMask = LiveRegs.contains(Reg);
|
||||
|
@ -34,7 +34,7 @@ using namespace llvm;
|
||||
void RegScavenger::setRegUsed(unsigned Reg, LaneBitmask LaneMask) {
|
||||
for (MCRegUnitMaskIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
|
||||
LaneBitmask UnitMask = (*RUI).second;
|
||||
if (UnitMask == 0 || (LaneMask & UnitMask) != 0)
|
||||
if (UnitMask.none() || !(LaneMask & UnitMask).none())
|
||||
RegUnitsAvailable.reset((*RUI).first);
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ bool RenameIndependentSubregs::findComponents(IntEqClasses &Classes,
|
||||
unsigned MergedID = ~0u;
|
||||
for (RenameIndependentSubregs::SubRangeInfo &SRInfo : SubRangeInfos) {
|
||||
const LiveInterval::SubRange &SR = *SRInfo.SR;
|
||||
if ((SR.LaneMask & LaneMask) == 0)
|
||||
if ((SR.LaneMask & LaneMask).none())
|
||||
continue;
|
||||
SlotIndex Pos = LIS->getInstructionIndex(*MO.getParent());
|
||||
Pos = MO.isDef() ? Pos.getRegSlot(MO.isEarlyClobber())
|
||||
@ -228,7 +228,7 @@ void RenameIndependentSubregs::rewriteOperands(const IntEqClasses &Classes,
|
||||
unsigned ID = ~0u;
|
||||
for (const SubRangeInfo &SRInfo : SubRangeInfos) {
|
||||
const LiveInterval::SubRange &SR = *SRInfo.SR;
|
||||
if ((SR.LaneMask & LaneMask) == 0)
|
||||
if ((SR.LaneMask & LaneMask).none())
|
||||
continue;
|
||||
const VNInfo *VNI = SR.getVNInfoAt(Pos);
|
||||
if (VNI == nullptr)
|
||||
|
@ -398,7 +398,7 @@ LaneBitmask ScheduleDAGInstrs::getLaneMaskForMO(const MachineOperand &MO) const
|
||||
// No point in tracking lanemasks if we don't have interesting subregisters.
|
||||
const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
|
||||
if (!RC.HasDisjunctSubRegs)
|
||||
return ~0u;
|
||||
return LaneBitmask::getAll();
|
||||
|
||||
unsigned SubReg = MO.getSubReg();
|
||||
if (SubReg == 0)
|
||||
@ -424,14 +424,14 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
DefLaneMask = getLaneMaskForMO(MO);
|
||||
// If we have a <read-undef> flag, none of the lane values comes from an
|
||||
// earlier instruction.
|
||||
KillLaneMask = IsKill ? ~0u : DefLaneMask;
|
||||
KillLaneMask = IsKill ? LaneBitmask::getAll() : DefLaneMask;
|
||||
|
||||
// Clear undef flag, we'll re-add it later once we know which subregister
|
||||
// Def is first.
|
||||
MO.setIsUndef(false);
|
||||
} else {
|
||||
DefLaneMask = ~0u;
|
||||
KillLaneMask = ~0u;
|
||||
DefLaneMask = LaneBitmask::getAll();
|
||||
KillLaneMask = LaneBitmask::getAll();
|
||||
}
|
||||
|
||||
if (MO.isDead()) {
|
||||
@ -444,12 +444,12 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
E = CurrentVRegUses.end(); I != E; /*empty*/) {
|
||||
LaneBitmask LaneMask = I->LaneMask;
|
||||
// Ignore uses of other lanes.
|
||||
if ((LaneMask & KillLaneMask) == 0) {
|
||||
if ((LaneMask & KillLaneMask).none()) {
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((LaneMask & DefLaneMask) != 0) {
|
||||
if (!(LaneMask & DefLaneMask).none()) {
|
||||
SUnit *UseSU = I->SU;
|
||||
MachineInstr *Use = UseSU->getInstr();
|
||||
SDep Dep(SU, SDep::Data, Reg);
|
||||
@ -461,7 +461,7 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
|
||||
LaneMask &= ~KillLaneMask;
|
||||
// If we found a Def for all lanes of this use, remove it from the list.
|
||||
if (LaneMask != 0) {
|
||||
if (!LaneMask.none()) {
|
||||
I->LaneMask = LaneMask;
|
||||
++I;
|
||||
} else
|
||||
@ -484,7 +484,7 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
for (VReg2SUnit &V2SU : make_range(CurrentVRegDefs.find(Reg),
|
||||
CurrentVRegDefs.end())) {
|
||||
// Ignore defs for other lanes.
|
||||
if ((V2SU.LaneMask & LaneMask) == 0)
|
||||
if ((V2SU.LaneMask & LaneMask).none())
|
||||
continue;
|
||||
// Add an output dependence.
|
||||
SUnit *DefSU = V2SU.SU;
|
||||
@ -507,11 +507,11 @@ void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
|
||||
LaneBitmask NonOverlapMask = V2SU.LaneMask & ~LaneMask;
|
||||
V2SU.SU = SU;
|
||||
V2SU.LaneMask = OverlapMask;
|
||||
if (NonOverlapMask != 0)
|
||||
if (!NonOverlapMask.none())
|
||||
CurrentVRegDefs.insert(VReg2SUnit(Reg, NonOverlapMask, DefSU));
|
||||
}
|
||||
// If there was no CurrentVRegDefs entry for some lanes yet, create one.
|
||||
if (LaneMask != 0)
|
||||
if (!LaneMask.none())
|
||||
CurrentVRegDefs.insert(VReg2SUnit(Reg, LaneMask, SU));
|
||||
}
|
||||
|
||||
@ -527,7 +527,8 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
|
||||
unsigned Reg = MO.getReg();
|
||||
|
||||
// Remember the use. Data dependencies will be added when we find the def.
|
||||
LaneBitmask LaneMask = TrackLaneMasks ? getLaneMaskForMO(MO) : ~0u;
|
||||
LaneBitmask LaneMask = TrackLaneMasks ? getLaneMaskForMO(MO)
|
||||
: LaneBitmask::getAll();
|
||||
CurrentVRegUses.insert(VReg2SUnitOperIdx(Reg, LaneMask, OperIdx, SU));
|
||||
|
||||
// Add antidependences to the following defs of the vreg.
|
||||
@ -535,7 +536,7 @@ void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
|
||||
CurrentVRegDefs.end())) {
|
||||
// Ignore defs for unrelated lanes.
|
||||
LaneBitmask PrevDefLaneMask = V2SU.LaneMask;
|
||||
if ((PrevDefLaneMask & LaneMask) == 0)
|
||||
if ((PrevDefLaneMask & LaneMask).none())
|
||||
continue;
|
||||
if (V2SU.SU == SU)
|
||||
continue;
|
||||
|
@ -412,7 +412,7 @@ void SplitEditor::addDeadDef(LiveInterval &LI, VNInfo *VNI, bool Original) {
|
||||
// register, we need to check which subranges need to be updated.
|
||||
const MachineInstr *DefMI = LIS.getInstructionFromIndex(Def);
|
||||
assert(DefMI != nullptr);
|
||||
LaneBitmask LM = 0;
|
||||
LaneBitmask LM;
|
||||
for (const MachineOperand &DefOp : DefMI->defs()) {
|
||||
unsigned R = DefOp.getReg();
|
||||
if (R != LI.reg)
|
||||
@ -425,7 +425,7 @@ void SplitEditor::addDeadDef(LiveInterval &LI, VNInfo *VNI, bool Original) {
|
||||
}
|
||||
}
|
||||
for (LiveInterval::SubRange &S : LI.subranges())
|
||||
if (S.LaneMask & LM)
|
||||
if (!(S.LaneMask & LM).none())
|
||||
S.createDeadDef(Def, LIS.getVNInfoAllocator());
|
||||
}
|
||||
}
|
||||
@ -1102,8 +1102,8 @@ void SplitEditor::extendPHIRange(MachineBasicBlock &B, LiveRangeCalc &LRC,
|
||||
LiveInterval &PLI = Edit->getParent();
|
||||
// Need the cast because the inputs to ?: would otherwise be deemed
|
||||
// "incompatible": SubRange vs LiveInterval.
|
||||
LiveRange &PSR = (LM != ~0u) ? getSubRangeForMask(LM, PLI)
|
||||
: static_cast<LiveRange&>(PLI);
|
||||
LiveRange &PSR = !LM.all() ? getSubRangeForMask(LM, PLI)
|
||||
: static_cast<LiveRange&>(PLI);
|
||||
if (PSR.liveAt(LastUse))
|
||||
LRC.extend(LR, End, /*PhysReg=*/0, Undefs);
|
||||
}
|
||||
@ -1126,7 +1126,7 @@ void SplitEditor::extendPHIKillRanges() {
|
||||
LiveRangeCalc &LRC = getLRCalc(RegIdx);
|
||||
MachineBasicBlock &B = *LIS.getMBBFromIndex(V->def);
|
||||
if (!removeDeadSegment(V->def, LI))
|
||||
extendPHIRange(B, LRC, LI, ~0u, /*Undefs=*/{});
|
||||
extendPHIRange(B, LRC, LI, LaneBitmask::getAll(), /*Undefs=*/{});
|
||||
}
|
||||
|
||||
SmallVector<SlotIndex, 4> Undefs;
|
||||
@ -1229,7 +1229,7 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) {
|
||||
LaneBitmask LM = Sub != 0 ? TRI.getSubRegIndexLaneMask(Sub)
|
||||
: MRI.getMaxLaneMaskForVReg(Reg);
|
||||
for (LiveInterval::SubRange &S : LI.subranges()) {
|
||||
if (!(S.LaneMask & LM))
|
||||
if ((S.LaneMask & LM).none())
|
||||
continue;
|
||||
// The problem here can be that the new register may have been created
|
||||
// for a partially defined original register. For example:
|
||||
|
@ -30,8 +30,8 @@ using namespace llvm;
|
||||
TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||
regclass_iterator RCB, regclass_iterator RCE,
|
||||
const char *const *SRINames,
|
||||
const unsigned *SRILaneMasks,
|
||||
unsigned SRICoveringLanes)
|
||||
const LaneBitmask *SRILaneMasks,
|
||||
LaneBitmask SRICoveringLanes)
|
||||
: InfoDesc(ID), SubRegIndexNames(SRINames),
|
||||
SubRegIndexLaneMasks(SRILaneMasks),
|
||||
RegClassBegin(RCB), RegClassEnd(RCE),
|
||||
@ -127,12 +127,6 @@ Printable PrintVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) {
|
||||
});
|
||||
}
|
||||
|
||||
Printable PrintLaneMask(LaneBitmask LaneMask) {
|
||||
return Printable([LaneMask](raw_ostream &OS) {
|
||||
OS << format("%08X", LaneMask);
|
||||
});
|
||||
}
|
||||
|
||||
} // End of llvm namespace
|
||||
|
||||
/// getAllocatableClass - Return the maximal subclass of the given register
|
||||
|
@ -266,7 +266,7 @@ void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
|
||||
SlotIndex MBBBegin = MBBI->first;
|
||||
// Advance all subrange iterators so that their end position is just
|
||||
// behind MBBBegin (or the iterator is at the end).
|
||||
LaneBitmask LaneMask = 0;
|
||||
LaneBitmask LaneMask;
|
||||
for (auto &RangeIterPair : SubRanges) {
|
||||
const LiveInterval::SubRange *SR = RangeIterPair.first;
|
||||
LiveInterval::const_iterator &SRI = RangeIterPair.second;
|
||||
@ -277,7 +277,7 @@ void VirtRegRewriter::addLiveInsForSubRanges(const LiveInterval &LI,
|
||||
if (SRI->start <= MBBBegin)
|
||||
LaneMask |= SR->LaneMask;
|
||||
}
|
||||
if (LaneMask == 0)
|
||||
if (LaneMask.none())
|
||||
continue;
|
||||
MachineBasicBlock *MBB = MBBI->second;
|
||||
MBB->addLiveIn(PhysReg, LaneMask);
|
||||
@ -342,7 +342,7 @@ bool VirtRegRewriter::readsUndefSubreg(const MachineOperand &MO) const {
|
||||
LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(SubRegIdx);
|
||||
// See if any of the relevant subregister liveranges is defined at this point.
|
||||
for (const LiveInterval::SubRange &SR : LI.subranges()) {
|
||||
if ((SR.LaneMask & UseMask) != 0 && SR.liveAt(BaseIndex))
|
||||
if (!(SR.LaneMask & UseMask).none() && SR.liveAt(BaseIndex))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -12,6 +12,8 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -1027,7 +1027,8 @@ const TargetRegisterClass *SIRegisterInfo::getSubRegClass(
|
||||
return RC;
|
||||
|
||||
// We can assume that each lane corresponds to one 32-bit register.
|
||||
unsigned Count = countPopulation(getSubRegIndexLaneMask(SubIdx));
|
||||
LaneBitmask::Type Mask = getSubRegIndexLaneMask(SubIdx).getAsInteger();
|
||||
unsigned Count = countPopulation(Mask);
|
||||
if (isSGPRClass(RC)) {
|
||||
switch (Count) {
|
||||
case 1:
|
||||
|
@ -234,13 +234,13 @@ HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns(
|
||||
RegisterSet LiveIns;
|
||||
RegisterSet Tmp;
|
||||
for (auto I : B.liveins()) {
|
||||
if (I.LaneMask == ~LaneBitmask(0)) {
|
||||
if (I.LaneMask.all()) {
|
||||
Tmp.insert({I.PhysReg,0});
|
||||
continue;
|
||||
}
|
||||
for (MCSubRegIndexIterator S(I.PhysReg, &TRI); S.isValid(); ++S) {
|
||||
LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
|
||||
if (M & I.LaneMask)
|
||||
if (!(M & I.LaneMask).none())
|
||||
Tmp.insert({S.getSubReg(), 0});
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ void HexagonExpandCondsets::updateDeadsInRange(unsigned Reg, LaneBitmask LM,
|
||||
if (!TargetRegisterInfo::isVirtualRegister(DR) || DR != Reg)
|
||||
return false;
|
||||
LaneBitmask SLM = getLaneMask(DR, DSR);
|
||||
return (SLM & LM) != 0;
|
||||
return !(SLM & LM).none();
|
||||
};
|
||||
|
||||
// The splitting step will create pairs of predicated definitions without
|
||||
|
@ -30,7 +30,7 @@ namespace llvm {
|
||||
namespace rdf {
|
||||
|
||||
raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P) {
|
||||
if (P.Mask != ~LaneBitmask(0))
|
||||
if (!P.Mask.all())
|
||||
OS << ':' << PrintLaneMask(P.Mask);
|
||||
return OS;
|
||||
}
|
||||
@ -662,7 +662,7 @@ bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
|
||||
RegisterRef NR = normalize(RR);
|
||||
auto F = Masks.find(NR.Reg);
|
||||
if (F != Masks.end()) {
|
||||
if (F->second & NR.Mask)
|
||||
if (!(F->second & NR.Mask).none())
|
||||
return true;
|
||||
}
|
||||
if (CheckUnits) {
|
||||
@ -676,7 +676,7 @@ bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
|
||||
bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
|
||||
// Always have a cover for empty lane mask.
|
||||
RegisterRef NR = normalize(RR);
|
||||
if (!NR.Mask)
|
||||
if (NR.Mask.none())
|
||||
return true;
|
||||
auto F = Masks.find(NR.Reg);
|
||||
if (F == Masks.end())
|
||||
@ -717,7 +717,7 @@ RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
|
||||
if (F == Masks.end())
|
||||
return *this;
|
||||
LaneBitmask NewM = F->second & ~NR.Mask;
|
||||
if (NewM == LaneBitmask(0))
|
||||
if (NewM.none())
|
||||
Masks.erase(F);
|
||||
else
|
||||
F->second = NewM;
|
||||
@ -1089,7 +1089,7 @@ RegisterRef DataFlowGraph::normalizeRef(RegisterRef RR) const {
|
||||
RegisterRef DataFlowGraph::restrictRef(RegisterRef AR, RegisterRef BR) const {
|
||||
if (AR.Reg == BR.Reg) {
|
||||
LaneBitmask M = AR.Mask & BR.Mask;
|
||||
return M ? RegisterRef(AR.Reg, M) : RegisterRef();
|
||||
return !M.none() ? RegisterRef(AR.Reg, M) : RegisterRef();
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
RegisterRef NAR = normalizeRef(AR);
|
||||
@ -1211,7 +1211,7 @@ bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
// This can happen when the register has only one unit, or when the
|
||||
// unit corresponds to explicit aliasing. In such cases, the lane mask
|
||||
// from RegisterRef should be ignored.
|
||||
if (!PA.second || !PB.second)
|
||||
if (PA.second.none() || PB.second.none())
|
||||
return true;
|
||||
|
||||
// At this point the common unit corresponds to a subregister. The lane
|
||||
@ -1221,7 +1221,7 @@ bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
// while the lane mask of r2 in d1 may be 0b0001.
|
||||
LaneBitmask LA = PA.second & RA.Mask;
|
||||
LaneBitmask LB = PB.second & RB.Mask;
|
||||
if (LA != 0 && LB != 0) {
|
||||
if (!LA.none() && !LB.none()) {
|
||||
unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
|
||||
// If register units were guaranteed to only have 1 bit in any lane
|
||||
// mask, the code below would not be necessary. This is because LA
|
||||
@ -1232,7 +1232,7 @@ bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Root);
|
||||
LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
|
||||
LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
|
||||
if (MaskA & MaskB & RC.LaneMask)
|
||||
if (!(MaskA & MaskB & RC.LaneMask).none())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -403,9 +403,9 @@ namespace rdf {
|
||||
LaneBitmask Mask;
|
||||
|
||||
RegisterRef() : RegisterRef(0) {}
|
||||
explicit RegisterRef(RegisterId R, LaneBitmask M = ~LaneBitmask(0))
|
||||
: Reg(R), Mask(R != 0 ? M : 0) {}
|
||||
operator bool() const { return Reg != 0 && Mask != LaneBitmask(0); }
|
||||
explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
|
||||
: Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
|
||||
operator bool() const { return Reg != 0 && !Mask.none(); }
|
||||
bool operator== (const RegisterRef &RR) const {
|
||||
return Reg == RR.Reg && Mask == RR.Mask;
|
||||
}
|
||||
@ -458,7 +458,7 @@ namespace rdf {
|
||||
uint32_t find(T Val) const {
|
||||
auto F = llvm::find(Map, Val);
|
||||
assert(F != Map.end());
|
||||
return *F;
|
||||
return F - Map.begin();
|
||||
}
|
||||
private:
|
||||
std::vector<T> Map;
|
||||
@ -468,15 +468,15 @@ namespace rdf {
|
||||
LaneMaskIndex() = default;
|
||||
|
||||
LaneBitmask getLaneMaskForIndex(uint32_t K) const {
|
||||
return K == 0 ? ~LaneBitmask(0) : get(K);
|
||||
return K == 0 ? LaneBitmask::getAll() : get(K);
|
||||
}
|
||||
uint32_t getIndexForLaneMask(LaneBitmask LM) {
|
||||
assert(LM != LaneBitmask(0));
|
||||
return LM == ~LaneBitmask(0) ? 0 : insert(LM);
|
||||
assert(!LM.none());
|
||||
return LM.all() ? 0 : insert(LM);
|
||||
}
|
||||
uint32_t getIndexForLaneMask(LaneBitmask LM) const {
|
||||
assert(LM != LaneBitmask(0));
|
||||
return LM == ~LaneBitmask(0) ? 0 : find(LM);
|
||||
assert(!LM.none());
|
||||
return LM.all() ? 0 : find(LM);
|
||||
}
|
||||
PackedRegisterRef pack(RegisterRef RR) {
|
||||
return { RR.Reg, getIndexForLaneMask(RR.Mask) };
|
||||
|
@ -659,7 +659,7 @@ void Liveness::computeLiveIns() {
|
||||
RegisterRef UR = DFG.normalizeRef(getRestrictedRegRef(PUA));
|
||||
for (const std::pair<RegisterId,NodeRefSet> &T : RUs) {
|
||||
// Check if T.first aliases UR?
|
||||
LaneBitmask M = 0;
|
||||
LaneBitmask M;
|
||||
for (std::pair<NodeId,LaneBitmask> P : T.second)
|
||||
M |= P.second;
|
||||
|
||||
@ -710,7 +710,7 @@ void Liveness::computeLiveIns() {
|
||||
}
|
||||
do {
|
||||
LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
|
||||
if (M & P.second)
|
||||
if (!(M & P.second).none())
|
||||
LV.push_back(RegisterRef(S.getSubReg()));
|
||||
++S;
|
||||
} while (S.isValid());
|
||||
@ -759,7 +759,7 @@ void Liveness::resetKills(MachineBasicBlock *B) {
|
||||
}
|
||||
do {
|
||||
LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
|
||||
if (M & I.LaneMask)
|
||||
if (!(M & I.LaneMask).none())
|
||||
LV.set(S.getSubReg());
|
||||
++S;
|
||||
} while (S.isValid());
|
||||
@ -1001,7 +1001,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
|
||||
RegisterAggr &Local = LiveMap[B];
|
||||
RefMap &LON = PhiLON[B];
|
||||
for (auto &R : LON) {
|
||||
LaneBitmask M = 0;
|
||||
LaneBitmask M;
|
||||
for (auto P : R.second)
|
||||
M |= P.second;
|
||||
Local.insert(RegisterRef(R.first,M));
|
||||
|
@ -51,7 +51,7 @@ using namespace llvm;
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
|
||||
: TheDef(R), EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) {
|
||||
: TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true) {
|
||||
Name = R->getName();
|
||||
if (R->getValue("Namespace"))
|
||||
Namespace = R->getValueAsString("Namespace");
|
||||
@ -62,7 +62,7 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
|
||||
CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
|
||||
unsigned Enum)
|
||||
: TheDef(nullptr), Name(N), Namespace(Nspace), Size(-1), Offset(-1),
|
||||
EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) {
|
||||
EnumValue(Enum), AllSuperRegsCovered(true) {
|
||||
}
|
||||
|
||||
std::string CodeGenSubRegIndex::getQualifiedName() const {
|
||||
@ -102,19 +102,19 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CodeGenSubRegIndex::computeLaneMask() const {
|
||||
LaneBitmask CodeGenSubRegIndex::computeLaneMask() const {
|
||||
// Already computed?
|
||||
if (LaneMask)
|
||||
if (!LaneMask.none())
|
||||
return LaneMask;
|
||||
|
||||
// Recursion guard, shouldn't be required.
|
||||
LaneMask = ~0u;
|
||||
LaneMask = LaneBitmask::getAll();
|
||||
|
||||
// The lane mask is simply the union of all sub-indices.
|
||||
unsigned M = 0;
|
||||
LaneBitmask M;
|
||||
for (const auto &C : Composed)
|
||||
M |= C.second->computeLaneMask();
|
||||
assert(M && "Missing lane mask, sub-register cycle?");
|
||||
assert(!M.none() && "Missing lane mask, sub-register cycle?");
|
||||
LaneMask = M;
|
||||
return LaneMask;
|
||||
}
|
||||
@ -678,8 +678,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
||||
: TheDef(R),
|
||||
Name(R->getName()),
|
||||
TopoSigs(RegBank.getNumTopoSigs()),
|
||||
EnumValue(-1),
|
||||
LaneMask(0) {
|
||||
EnumValue(-1) {
|
||||
// Rename anonymous register classes.
|
||||
if (R->getName().size() > 9 && R->getName()[9] == '.') {
|
||||
static unsigned AnonCounter = 0;
|
||||
@ -1193,7 +1192,7 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
// First assign individual bits to all the leaf indices.
|
||||
unsigned Bit = 0;
|
||||
// Determine mask of lanes that cover their registers.
|
||||
CoveringLanes = ~0u;
|
||||
CoveringLanes = LaneBitmask::getAll();
|
||||
for (auto &Idx : SubRegIndices) {
|
||||
if (Idx.getComposites().empty()) {
|
||||
if (Bit > 32) {
|
||||
@ -1201,10 +1200,10 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
Twine("Ran out of lanemask bits to represent subregister ")
|
||||
+ Idx.getName());
|
||||
}
|
||||
Idx.LaneMask = 1u << Bit;
|
||||
Idx.LaneMask = LaneBitmask(1 << Bit);
|
||||
++Bit;
|
||||
} else {
|
||||
Idx.LaneMask = 0;
|
||||
Idx.LaneMask = LaneBitmask::getNone();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1223,9 +1222,12 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
// Moving from a class with no subregisters we just had a single lane:
|
||||
// The subregister must be a leaf subregister and only occupies 1 bit.
|
||||
// Move the bit from the class without subregisters into that position.
|
||||
unsigned DstBit = Log2_32(Idx.LaneMask);
|
||||
assert(Idx.LaneMask == 1u << DstBit && "Must be a leaf subregister");
|
||||
MaskRolPair MaskRol = { 1, (uint8_t)DstBit };
|
||||
static_assert(sizeof(Idx.LaneMask.getAsInteger()) == 4,
|
||||
"Change Log2_32 to a proper one");
|
||||
unsigned DstBit = Log2_32(Idx.LaneMask.getAsInteger());
|
||||
assert(Idx.LaneMask == LaneBitmask(1 << DstBit) &&
|
||||
"Must be a leaf subregister");
|
||||
MaskRolPair MaskRol = { LaneBitmask(1), (uint8_t)DstBit };
|
||||
LaneTransforms.push_back(MaskRol);
|
||||
} else {
|
||||
// Go through all leaf subregisters and find the ones that compose with
|
||||
@ -1239,8 +1241,8 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
continue;
|
||||
// Replicate the behaviour from the lane mask generation loop above.
|
||||
unsigned SrcBit = NextBit;
|
||||
unsigned SrcMask = 1u << SrcBit;
|
||||
if (NextBit < 31)
|
||||
LaneBitmask SrcMask = LaneBitmask(1 << SrcBit);
|
||||
if (NextBit < LaneBitmask::BitWidth-1)
|
||||
++NextBit;
|
||||
assert(Idx2.LaneMask == SrcMask);
|
||||
|
||||
@ -1253,16 +1255,19 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
assert(Composite->getComposites().empty());
|
||||
|
||||
// Create Mask+Rotate operation and merge with existing ops if possible.
|
||||
unsigned DstBit = Log2_32(Composite->LaneMask);
|
||||
static_assert(sizeof(Composite->LaneMask.getAsInteger()) == 4,
|
||||
"Change Log2_32 to a proper one");
|
||||
unsigned DstBit = Log2_32(Composite->LaneMask.getAsInteger());
|
||||
int Shift = DstBit - SrcBit;
|
||||
uint8_t RotateLeft = Shift >= 0 ? (uint8_t)Shift : 32+Shift;
|
||||
uint8_t RotateLeft = Shift >= 0 ? (uint8_t)Shift
|
||||
: LaneBitmask::BitWidth + Shift;
|
||||
for (auto &I : LaneTransforms) {
|
||||
if (I.RotateLeft == RotateLeft) {
|
||||
I.Mask |= SrcMask;
|
||||
SrcMask = 0;
|
||||
SrcMask = LaneBitmask::getNone();
|
||||
}
|
||||
}
|
||||
if (SrcMask != 0) {
|
||||
if (!SrcMask.none()) {
|
||||
MaskRolPair MaskRol = { SrcMask, RotateLeft };
|
||||
LaneTransforms.push_back(MaskRol);
|
||||
}
|
||||
@ -1273,13 +1278,13 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
// 0xffffffff (including some irrelevant invalid bits) so that it should
|
||||
// merge with more entries later while compressing the table.
|
||||
if (LaneTransforms.size() == 1)
|
||||
LaneTransforms[0].Mask = ~0u;
|
||||
LaneTransforms[0].Mask = LaneBitmask::getAll();
|
||||
|
||||
// Further compression optimization: For invalid compositions resulting
|
||||
// in a sequence with 0 entries we can just pick any other. Choose
|
||||
// Mask 0xffffffff with Rotation 0.
|
||||
if (LaneTransforms.size() == 0) {
|
||||
MaskRolPair P = { ~0u, 0 };
|
||||
MaskRolPair P = { LaneBitmask::getAll(), 0 };
|
||||
LaneTransforms.push_back(P);
|
||||
}
|
||||
}
|
||||
@ -1289,7 +1294,7 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
|
||||
// Inherit lanes from composites.
|
||||
for (const auto &Idx : SubRegIndices) {
|
||||
unsigned Mask = Idx.computeLaneMask();
|
||||
LaneBitmask Mask = Idx.computeLaneMask();
|
||||
// If some super-registers without CoveredBySubRegs use this index, we can
|
||||
// no longer assume that the lanes are covering their registers.
|
||||
if (!Idx.AllSuperRegsCovered)
|
||||
@ -1298,7 +1303,7 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
|
||||
// Compute lane mask combinations for register classes.
|
||||
for (auto &RegClass : RegClasses) {
|
||||
unsigned LaneMask = 0;
|
||||
LaneBitmask LaneMask;
|
||||
for (const auto &SubRegIndex : SubRegIndices) {
|
||||
if (RegClass.getSubClassWithSubReg(&SubRegIndex) == nullptr)
|
||||
continue;
|
||||
@ -1307,8 +1312,8 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
|
||||
|
||||
// For classes without any subregisters set LaneMask to 1 instead of 0.
|
||||
// This makes it easier for client code to handle classes uniformly.
|
||||
if (LaneMask == 0)
|
||||
LaneMask = 1;
|
||||
if (LaneMask.none())
|
||||
LaneMask = LaneBitmask(1);
|
||||
|
||||
RegClass.LaneMask = LaneMask;
|
||||
}
|
||||
@ -1807,7 +1812,8 @@ void CodeGenRegBank::computeRegUnitLaneMasks() {
|
||||
for (auto &Register : Registers) {
|
||||
// Create an initial lane mask for all register units.
|
||||
const auto &RegUnits = Register.getRegUnits();
|
||||
CodeGenRegister::RegUnitLaneMaskList RegUnitLaneMasks(RegUnits.count(), 0);
|
||||
CodeGenRegister::RegUnitLaneMaskList
|
||||
RegUnitLaneMasks(RegUnits.count(), LaneBitmask::getNone());
|
||||
// Iterate through SubRegisters.
|
||||
typedef CodeGenRegister::SubRegMap SubRegMap;
|
||||
const SubRegMap &SubRegs = Register.getSubRegs();
|
||||
@ -1820,7 +1826,7 @@ void CodeGenRegBank::computeRegUnitLaneMasks() {
|
||||
continue;
|
||||
CodeGenSubRegIndex *SubRegIndex = S->first;
|
||||
const CodeGenRegister *SubRegister = S->second;
|
||||
unsigned LaneMask = SubRegIndex->LaneMask;
|
||||
LaneBitmask LaneMask = SubRegIndex->LaneMask;
|
||||
// Distribute LaneMask to Register Units touched.
|
||||
for (unsigned SUI : SubRegister->getRegUnits()) {
|
||||
bool Found = false;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/CodeGen/MachineValueType.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
#include "llvm/TableGen/SetTheory.h"
|
||||
@ -47,7 +48,7 @@ namespace llvm {
|
||||
/// Mask the bits specified in Mask, then rotate them Rol bits to the left
|
||||
/// assuming a wraparound at 32bits.
|
||||
struct MaskRolPair {
|
||||
unsigned Mask;
|
||||
LaneBitmask Mask;
|
||||
uint8_t RotateLeft;
|
||||
|
||||
bool operator==(const MaskRolPair Other) const {
|
||||
@ -68,7 +69,7 @@ namespace llvm {
|
||||
uint16_t Size;
|
||||
uint16_t Offset;
|
||||
const unsigned EnumValue;
|
||||
mutable unsigned LaneMask;
|
||||
mutable LaneBitmask LaneMask;
|
||||
mutable SmallVector<MaskRolPair,1> CompositionLaneMaskTransform;
|
||||
|
||||
// Are all super-registers containing this SubRegIndex covered by their
|
||||
@ -120,7 +121,7 @@ namespace llvm {
|
||||
const CompMap &getComposites() const { return Composed; }
|
||||
|
||||
// Compute LaneMask from Composed. Return LaneMask.
|
||||
unsigned computeLaneMask() const;
|
||||
LaneBitmask computeLaneMask() const;
|
||||
|
||||
private:
|
||||
CompMap Composed;
|
||||
@ -206,7 +207,7 @@ namespace llvm {
|
||||
|
||||
// List of register units in ascending order.
|
||||
typedef SparseBitVector<> RegUnitList;
|
||||
typedef SmallVector<unsigned, 16> RegUnitLaneMaskList;
|
||||
typedef SmallVector<LaneBitmask, 16> RegUnitLaneMaskList;
|
||||
|
||||
// How many entries in RegUnitList are native?
|
||||
RegUnitList NativeRegUnits;
|
||||
@ -215,7 +216,7 @@ namespace llvm {
|
||||
// This is only valid after computeSubRegs() completes.
|
||||
const RegUnitList &getRegUnits() const { return RegUnits; }
|
||||
|
||||
ArrayRef<unsigned> getRegUnitLaneMasks() const {
|
||||
ArrayRef<LaneBitmask> getRegUnitLaneMasks() const {
|
||||
return makeArrayRef(RegUnitLaneMasks).slice(0, NativeRegUnits.count());
|
||||
}
|
||||
|
||||
@ -316,7 +317,7 @@ namespace llvm {
|
||||
std::string AltOrderSelect;
|
||||
uint8_t AllocationPriority;
|
||||
/// Contains the combination of the lane masks of all subregisters.
|
||||
unsigned LaneMask;
|
||||
LaneBitmask LaneMask;
|
||||
/// True if there are at least 2 subregisters which do not interfere.
|
||||
bool HasDisjunctSubRegs;
|
||||
bool CoveredBySubRegs;
|
||||
@ -733,7 +734,7 @@ namespace llvm {
|
||||
// Bit mask of lanes that cover their registers. A sub-register index whose
|
||||
// LaneMask is contained in CoveringLanes will be completely covered by
|
||||
// another sub-register with the same or larger lane mask.
|
||||
unsigned CoveringLanes;
|
||||
LaneBitmask CoveringLanes;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -578,7 +578,7 @@ static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
|
||||
// 0 differential which means we can't encode repeated elements.
|
||||
|
||||
typedef SmallVector<uint16_t, 4> DiffVec;
|
||||
typedef SmallVector<unsigned, 4> MaskVec;
|
||||
typedef SmallVector<LaneBitmask, 4> MaskVec;
|
||||
|
||||
// Differentially encode a sequence of numbers into V. The starting value and
|
||||
// terminating 0 are not added to V, so it will have the same size as List.
|
||||
@ -611,8 +611,8 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) {
|
||||
OS << Val;
|
||||
}
|
||||
|
||||
static void printMask(raw_ostream &OS, unsigned Val) {
|
||||
OS << format("0x%08X", Val);
|
||||
static void printMask(raw_ostream &OS, LaneBitmask Val) {
|
||||
OS << "LaneBitmask(0x" << PrintLaneMask(Val) << ')';
|
||||
}
|
||||
|
||||
// Try to combine Idx's compose map into Vec if it is compatible.
|
||||
@ -739,7 +739,7 @@ RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
|
||||
}
|
||||
|
||||
OS << " struct MaskRolOp {\n"
|
||||
" unsigned Mask;\n"
|
||||
" LaneBitmask Mask;\n"
|
||||
" uint8_t RotateLeft;\n"
|
||||
" };\n"
|
||||
" static const MaskRolOp LaneMaskComposeSequences[] = {\n";
|
||||
@ -749,9 +749,10 @@ RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
|
||||
const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
|
||||
for (size_t p = 0, pe = Sequence.size(); p != pe; ++p) {
|
||||
const MaskRolPair &P = Sequence[p];
|
||||
OS << format("{ 0x%08X, %2u }, ", P.Mask, P.RotateLeft);
|
||||
printMask(OS << "{ ", P.Mask);
|
||||
OS << format(", %2u }, ", P.RotateLeft);
|
||||
}
|
||||
OS << "{ 0, 0 }";
|
||||
OS << "{ LaneBitmask::getNone(), 0 }";
|
||||
if (s+1 != se)
|
||||
OS << ", ";
|
||||
OS << " // Sequence " << Idx << "\n";
|
||||
@ -774,12 +775,11 @@ RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
|
||||
" const {\n"
|
||||
" --IdxA; assert(IdxA < " << SubRegIndices.size()
|
||||
<< " && \"Subregister index out of bounds\");\n"
|
||||
" LaneBitmask Result = 0;\n"
|
||||
" for (const MaskRolOp *Ops = CompositeSequences[IdxA]; Ops->Mask != 0; ++Ops)"
|
||||
" {\n"
|
||||
" LaneBitmask Masked = LaneMask & Ops->Mask;\n"
|
||||
" Result |= (Masked << Ops->RotateLeft) & 0xFFFFFFFF;\n"
|
||||
" Result |= (Masked >> ((32 - Ops->RotateLeft) & 0x1F));\n"
|
||||
" LaneBitmask Result;\n"
|
||||
" for (const MaskRolOp *Ops = CompositeSequences[IdxA]; !Ops->Mask.none(); ++Ops) {\n"
|
||||
" LaneBitmask::Type M = LaneMask.getAsInteger() & Ops->Mask.getAsInteger();\n"
|
||||
" unsigned S = Ops->RotateLeft;\n"
|
||||
" Result |= LaneBitmask((M << S) | (M >> (LaneBitmask::BitWidth - S)));\n"
|
||||
" }\n"
|
||||
" return Result;\n"
|
||||
"}\n\n";
|
||||
@ -790,12 +790,11 @@ RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
|
||||
" LaneMask &= getSubRegIndexLaneMask(IdxA);\n"
|
||||
" --IdxA; assert(IdxA < " << SubRegIndices.size()
|
||||
<< " && \"Subregister index out of bounds\");\n"
|
||||
" LaneBitmask Result = 0;\n"
|
||||
" for (const MaskRolOp *Ops = CompositeSequences[IdxA]; Ops->Mask != 0; ++Ops)"
|
||||
" {\n"
|
||||
" LaneBitmask Rotated = (LaneMask >> Ops->RotateLeft) |\n"
|
||||
" ((LaneMask << ((32 - Ops->RotateLeft) & 0x1F)) & 0xFFFFFFFF);\n"
|
||||
" Result |= Rotated & Ops->Mask;\n"
|
||||
" LaneBitmask Result;\n"
|
||||
" for (const MaskRolOp *Ops = CompositeSequences[IdxA]; !Ops->Mask.none(); ++Ops) {\n"
|
||||
" LaneBitmask::Type M = LaneMask.getAsInteger();\n"
|
||||
" unsigned S = Ops->RotateLeft;\n"
|
||||
" Result |= LaneBitmask((M >> S) | (M << (LaneBitmask::BitWidth - S)));\n"
|
||||
" }\n"
|
||||
" return Result;\n"
|
||||
"}\n\n";
|
||||
@ -894,8 +893,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
LaneMaskVec.insert(LaneMaskVec.begin(), RUMasks.begin(), RUMasks.end());
|
||||
// Terminator mask should not be used inside of the list.
|
||||
#ifndef NDEBUG
|
||||
for (unsigned M : LaneMaskVec) {
|
||||
assert(M != ~0u && "terminator mask should not be part of the list");
|
||||
for (LaneBitmask M : LaneMaskVec) {
|
||||
assert(!M.all() && "terminator mask should not be part of the list");
|
||||
}
|
||||
#endif
|
||||
LaneMaskSeqs.add(LaneMaskVec);
|
||||
@ -916,8 +915,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the shared table of regunit lane mask sequences.
|
||||
OS << "extern const unsigned " << TargetName << "LaneMaskLists[] = {\n";
|
||||
LaneMaskSeqs.emit(OS, printMask, "~0u");
|
||||
OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[] = {\n";
|
||||
LaneMaskSeqs.emit(OS, printMask, "LaneBitmask::getAll()");
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the table of sub-register indexes.
|
||||
@ -1197,9 +1196,10 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << "\" };\n\n";
|
||||
|
||||
// Emit SubRegIndex lane masks, including 0.
|
||||
OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n";
|
||||
OS << "\nstatic const LaneBitmask SubRegIndexLaneMaskTable[] = {\n LaneBitmask::getAll(),\n";
|
||||
for (const auto &Idx : SubRegIndices) {
|
||||
OS << format(" 0x%08x, // ", Idx.LaneMask) << Idx.getName() << '\n';
|
||||
printMask(OS << " ", Idx.LaneMask);
|
||||
OS << ", // " << Idx.getName() << '\n';
|
||||
}
|
||||
OS << " };\n\n";
|
||||
|
||||
@ -1317,9 +1317,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
|
||||
<< "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName()
|
||||
<< "SubClassMask,\n SuperRegIdxSeqs + "
|
||||
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n "
|
||||
<< format("0x%08x,\n ", RC.LaneMask)
|
||||
<< (unsigned)RC.AllocationPriority << ",\n "
|
||||
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n ";
|
||||
printMask(OS, RC.LaneMask);
|
||||
OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
|
||||
<< (RC.HasDisjunctSubRegs?"true":"false")
|
||||
<< ", /* HasDisjunctSubRegs */\n "
|
||||
<< (RC.CoveredBySubRegs?"true":"false")
|
||||
@ -1408,7 +1408,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// Emit the constructor of the class...
|
||||
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
|
||||
OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
|
||||
OS << "extern const unsigned " << TargetName << "LaneMaskLists[];\n";
|
||||
OS << "extern const LaneBitmask " << TargetName << "LaneMaskLists[];\n";
|
||||
OS << "extern const char " << TargetName << "RegStrings[];\n";
|
||||
OS << "extern const char " << TargetName << "RegClassStrings[];\n";
|
||||
OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
|
||||
@ -1423,8 +1423,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
|
||||
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
|
||||
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
||||
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x";
|
||||
OS.write_hex(RegBank.CoveringLanes);
|
||||
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable, ";
|
||||
printMask(OS, RegBank.CoveringLanes);
|
||||
OS << ") {\n"
|
||||
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size() + 1
|
||||
<< ", RA, PC,\n " << TargetName
|
||||
|
Loading…
Reference in New Issue
Block a user