Index: include/llvm/CodeGen/LiveIntervalAnalysis.h =================================================================== --- include/llvm/CodeGen/LiveIntervalAnalysis.h +++ include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -459,7 +459,8 @@ 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; }; Index: include/llvm/CodeGen/MachineBasicBlock.h =================================================================== --- include/llvm/CodeGen/MachineBasicBlock.h +++ include/llvm/CodeGen/MachineBasicBlock.h @@ -21,6 +21,7 @@ #include "llvm/Support/BranchProbability.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/LaneBitmask.h" #include namespace llvm { @@ -35,9 +36,6 @@ class raw_ostream; class MachineBranchProbabilityInfo; -// Forward declaration to avoid circular include problem with TargetRegisterInfo -typedef unsigned LaneBitmask; - template <> struct ilist_traits { private: friend class MachineBasicBlock; // Set by the owning MachineBasicBlock. @@ -278,7 +276,8 @@ /// 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 @@ 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. Index: include/llvm/CodeGen/RegisterPressure.h =================================================================== --- include/llvm/CodeGen/RegisterPressure.h +++ include/llvm/CodeGen/RegisterPressure.h @@ -278,7 +278,7 @@ 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 @@ 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 @@ 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 @@ 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)); } } Index: include/llvm/CodeGen/RegisterScavenging.h =================================================================== --- include/llvm/CodeGen/RegisterScavenging.h +++ include/llvm/CodeGen/RegisterScavenging.h @@ -164,7 +164,7 @@ } /// 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); } Index: include/llvm/MC/MCRegisterInfo.h =================================================================== --- include/llvm/MC/MCRegisterInfo.h +++ include/llvm/MC/MCRegisterInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LaneBitmask.h" #include namespace llvm { @@ -161,7 +162,7 @@ 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 @@ 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 @@ /// 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 @@ } /// Returns a (RegUnit, LaneMask) pair. - std::pair operator*() const { + std::pair operator*() const { return std::make_pair(*RUIter, *MaskListIter); } Index: include/llvm/Support/LaneBitmask.h =================================================================== --- /dev/null +++ include/llvm/Support/LaneBitmask.h @@ -0,0 +1,103 @@ +//===-- llvm/Support/LaneBitmask.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// 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_SUPPORT_LANEBITMASK_H +#define LLVM_SUPPORT_LANEBITMASK_H + +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + struct LaneBitmask { + // When changing the underlying type, change the format string in + // the "porint" function as well. + typedef unsigned Type; + + LaneBitmask() : Mask(0) {} + bool operator== (LaneBitmask M) const { return Mask == M.Mask; } + bool operator!= (LaneBitmask M) const { return Mask != M.Mask; } + bool operator< (LaneBitmask M) const { return Mask < M.Mask; } + bool none() const { return Mask == 0; } + bool all() const { return ~Mask == 0; } + + LaneBitmask operator~() const { + return LaneBitmask(~Mask); + } + LaneBitmask operator|(LaneBitmask M) const { + return LaneBitmask(Mask | M.Mask); + } + LaneBitmask operator&(LaneBitmask M) const { + return LaneBitmask(Mask & M.Mask); + } + LaneBitmask operator<<(unsigned S) const { + return LaneBitmask(Mask << S); + } + LaneBitmask operator>>(unsigned S) const { + return LaneBitmask(Mask >> S); + } + LaneBitmask &operator|=(LaneBitmask M) { + Mask |= M.Mask; + return *this; + } + LaneBitmask &operator&=(LaneBitmask M) { + Mask &= M.Mask; + return *this; + } + + static LaneBitmask rol(LaneBitmask M, unsigned S) { + assert(S < 8*sizeof(Type)); + if (S == 0) + return M; + Type V = M.getAsInteger(); + return get((V << S) | (V >> (8*sizeof(Type) - S))); + } + static LaneBitmask ror(LaneBitmask M, unsigned S) { + assert(S < 8*sizeof(Type)); + if (S == 0) + return M; + Type V = M.getAsInteger(); + return get((V >> S) | (V << (8*sizeof(Type) - S))); + } + + Type getAsInteger() const { return Mask; } + + static LaneBitmask getNone() { return LaneBitmask(0); } + static LaneBitmask getAll() { return ~LaneBitmask(0); } + static LaneBitmask get(Type V) { return LaneBitmask(V); } + + void print(raw_ostream &OS) const { + OS << format("%08X", Mask); + } + + private: + explicit LaneBitmask(Type V) : Mask(V) {} + + Type Mask; + }; +} + +#endif // LLVM_SUPPORT_LANEBITMASK_H Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -23,6 +23,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Printable.h" +#include "llvm/Support/LaneBitmask.h" #include #include @@ -36,23 +37,6 @@ 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 +253,7 @@ const LaneBitmask *SubRegIndexLaneMasks; regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses - unsigned CoveringLanes; + LaneBitmask CoveringLanes; protected: TargetRegisterInfo(const TargetRegisterInfoDesc *ID, @@ -277,7 +261,7 @@ regclass_iterator RegClassEnd, const char *const *SRINames, const LaneBitmask *SRILaneMasks, - unsigned CoveringLanes); + LaneBitmask CoveringLanes); virtual ~TargetRegisterInfo(); public: Index: lib/CodeGen/DetectDeadLanes.cpp =================================================================== --- lib/CodeGen/DetectDeadLanes.cpp +++ lib/CodeGen/DetectDeadLanes.cpp @@ -210,7 +210,7 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 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 @@ 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::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 @@ 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 @@ 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 @@ 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(); } Index: lib/CodeGen/LiveInterval.cpp =================================================================== --- lib/CodeGen/LiveInterval.cpp +++ lib/CodeGen/LiveInterval.cpp @@ -876,7 +876,7 @@ 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 @@ 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 @@ 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()); Index: lib/CodeGen/LiveIntervalAnalysis.cpp =================================================================== --- lib/CodeGen/LiveIntervalAnalysis.cpp +++ lib/CodeGen/LiveIntervalAnalysis.cpp @@ -514,7 +514,7 @@ 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 @@ 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 @@ DefinedLanesMask |= SR.LaneMask; } } else - DefinedLanesMask = ~0u; + DefinedLanesMask = LaneBitmask::getAll(); bool IsFullWrite = false; for (const MachineOperand &MO : MI->operands()) { @@ -740,7 +740,7 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ unsigned SubReg = MO.getSubReg(); LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg); - if ((Mask & LaneMask) == 0) + if ((Mask & LaneMask).none()) continue; if (MO.isDef()) { Index: lib/CodeGen/LivePhysRegs.cpp =================================================================== --- lib/CodeGen/LivePhysRegs.cpp +++ lib/CodeGen/LivePhysRegs.cpp @@ -144,13 +144,15 @@ 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()); + } } } Index: lib/CodeGen/LiveRangeCalc.h =================================================================== --- lib/CodeGen/LiveRangeCalc.h +++ lib/CodeGen/LiveRangeCalc.h @@ -160,7 +160,8 @@ /// all uses must be jointly dominated by the definitions from @p LR /// together with definitions of other lanes where @p LR becomes undefined /// (via 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 @@ /// 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. Index: lib/CodeGen/LiveRangeCalc.cpp =================================================================== --- lib/CodeGen/LiveRangeCalc.cpp +++ lib/CodeGen/LiveRangeCalc.cpp @@ -79,11 +79,12 @@ 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 @@ 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 @@ constructMainRangeFromSubranges(LI); } else { resetLiveOutMap(); - extendToUses(LI, Reg, ~0u); + extendToUses(LI, Reg, LaneBitmask::getAll()); } } @@ -143,7 +144,7 @@ } } 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 @@ 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 @@ if (MO.isDef()) SLM = ~SLM; // Ignore uses not reading the current (sub)range. - if ((SLM & Mask) == 0) + if ((SLM & Mask).none()) continue; } Index: lib/CodeGen/LiveRangeEdit.cpp =================================================================== --- lib/CodeGen/LiveRangeEdit.cpp +++ lib/CodeGen/LiveRangeEdit.cpp @@ -236,7 +236,7 @@ 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; Index: lib/CodeGen/LiveRegMatrix.cpp =================================================================== --- lib/CodeGen/LiveRegMatrix.cpp +++ lib/CodeGen/LiveRegMatrix.cpp @@ -79,7 +79,7 @@ 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; Index: lib/CodeGen/MIRParser/MIParser.cpp =================================================================== --- lib/CodeGen/MIRParser/MIParser.cpp +++ lib/CodeGen/MIRParser/MIParser.cpp @@ -456,15 +456,18 @@ 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::get(V); lex(); } MBB.addLiveIn(Reg, Mask); Index: lib/CodeGen/MIRPrinter.cpp =================================================================== --- lib/CodeGen/MIRPrinter.cpp +++ lib/CodeGen/MIRPrinter.cpp @@ -498,7 +498,7 @@ OS << ", "; First = false; printReg(LI.PhysReg, OS, TRI); - if (LI.LaneMask != ~0u) + if (!LI.LaneMask.all()) OS << ":0x" << PrintLaneMask(LI.LaneMask); } OS << "\n"; Index: lib/CodeGen/MachineBasicBlock.cpp =================================================================== --- lib/CodeGen/MachineBasicBlock.cpp +++ lib/CodeGen/MachineBasicBlock.cpp @@ -291,7 +291,7 @@ 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 @@ 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() { Index: lib/CodeGen/MachinePipeliner.cpp =================================================================== --- lib/CodeGen/MachinePipeliner.cpp +++ lib/CodeGen/MachinePipeliner.cpp @@ -1742,11 +1742,13 @@ 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); Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -894,7 +894,7 @@ break; } if (UI == VRegUses.end()) - VRegUses.insert(VReg2SUnit(Reg, 0, &SU)); + VRegUses.insert(VReg2SUnit(Reg, LaneBitmask::getNone(), &SU)); } } @@ -1040,7 +1040,7 @@ // 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 @@ ); } } 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 Index: lib/CodeGen/MachineVerifier.cpp =================================================================== --- lib/CodeGen/MachineVerifier.cpp +++ lib/CodeGen/MachineVerifier.cpp @@ -229,10 +229,10 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ ? 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 @@ !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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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); } Index: lib/CodeGen/PeepholeOptimizer.cpp =================================================================== --- lib/CodeGen/PeepholeOptimizer.cpp +++ lib/CodeGen/PeepholeOptimizer.cpp @@ -1823,8 +1823,8 @@ // 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. Index: lib/CodeGen/RegisterCoalescer.cpp =================================================================== --- lib/CodeGen/RegisterCoalescer.cpp +++ lib/CodeGen/RegisterCoalescer.cpp @@ -815,14 +815,14 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ }); } - ShrinkMask = 0; + ShrinkMask = LaneBitmask::getNone(); ShrinkMainRange = false; // Okay, attempt to join these two intervals. On failure, this returns false. @@ -1516,10 +1516,10 @@ 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 @@ /// 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 @@ 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 @@ 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 @@ 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 @@ 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::get(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::get(1); if (DefMI->isImplicitDef()) { - V.ValidLanes = 0; + V.ValidLanes = LaneBitmask::getNone(); V.ErasableImplicitDef = true; } } else { @@ -2106,7 +2107,7 @@ // 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 @@ // 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 @@ // // 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 @@ // 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 @@ 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 @@ TaintedLanes &= ~OV.WriteLanes; if (!OV.RedefVNI) break; - } while (TaintedLanes); + } while (!TaintedLanes.none()); return true; } @@ -2334,8 +2335,8 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ // 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 } Index: lib/CodeGen/RegisterPressure.cpp =================================================================== --- lib/CodeGen/RegisterPressure.cpp +++ lib/CodeGen/RegisterPressure.cpp @@ -26,8 +26,8 @@ static void increaseSetPressure(std::vector &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 decreaseSetPressure(std::vector &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 @@ 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 @@ 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 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 @@ 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 @@ return Other.RegUnit == RegUnit; }); if (I == RegUnits.end()) - return 0; + return LaneBitmask::getNone(); return I->LaneMask; } static void addRegLanes(SmallVectorImpl &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 @@ 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 &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 @@ 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 @@ // 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 @@ 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 @@ void pushReg(unsigned Reg, SmallVectorImpl &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 @@ 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 @@ // 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 @@ 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 @@ 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::discoverLiveInOrOut(RegisterMaskPair Pair, SmallVectorImpl &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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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::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 @@ 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 @@ SlotIndex CurrIdx = getCurrSlot(); LastUseMask = findUseBetween(Reg, LastUseMask, CurrIdx, SlotIdx, *MRI, LIS); - if (LastUseMask == 0) + if (LastUseMask.none()) continue; LaneBitmask LiveMask = LiveRegs.contains(Reg); Index: lib/CodeGen/RegisterScavenging.cpp =================================================================== --- lib/CodeGen/RegisterScavenging.cpp +++ lib/CodeGen/RegisterScavenging.cpp @@ -34,7 +34,7 @@ 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); } } Index: lib/CodeGen/RenameIndependentSubregs.cpp =================================================================== --- lib/CodeGen/RenameIndependentSubregs.cpp +++ lib/CodeGen/RenameIndependentSubregs.cpp @@ -184,7 +184,7 @@ 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 @@ 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) Index: lib/CodeGen/ScheduleDAGInstrs.cpp =================================================================== --- lib/CodeGen/ScheduleDAGInstrs.cpp +++ lib/CodeGen/ScheduleDAGInstrs.cpp @@ -398,7 +398,7 @@ // 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 @@ DefLaneMask = getLaneMaskForMO(MO); // If we have a 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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; Index: lib/CodeGen/SplitKit.cpp =================================================================== --- lib/CodeGen/SplitKit.cpp +++ lib/CodeGen/SplitKit.cpp @@ -412,7 +412,7 @@ // 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 @@ } } for (LiveInterval::SubRange &S : LI.subranges()) - if (S.LaneMask & LM) + if (!(S.LaneMask & LM).none()) S.createDeadDef(Def, LIS.getVNInfoAllocator()); } } @@ -1102,8 +1102,8 @@ 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(PLI); + LiveRange &PSR = !LM.all() ? getSubRangeForMask(LM, PLI) + : static_cast(PLI); if (PSR.liveAt(LastUse)) LRC.extend(LR, End, /*PhysReg=*/0, Undefs); } @@ -1126,7 +1126,7 @@ 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 Undefs; @@ -1229,7 +1229,7 @@ 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: Index: lib/CodeGen/TargetRegisterInfo.cpp =================================================================== --- lib/CodeGen/TargetRegisterInfo.cpp +++ lib/CodeGen/TargetRegisterInfo.cpp @@ -30,8 +30,8 @@ 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), @@ -129,7 +129,7 @@ Printable PrintLaneMask(LaneBitmask LaneMask) { return Printable([LaneMask](raw_ostream &OS) { - OS << format("%08X", LaneMask); + LaneMask.print(OS); }); } Index: lib/CodeGen/VirtRegMap.cpp =================================================================== --- lib/CodeGen/VirtRegMap.cpp +++ lib/CodeGen/VirtRegMap.cpp @@ -266,7 +266,7 @@ 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 @@ 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 @@ 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; Index: lib/Target/AMDGPU/SIRegisterInfo.cpp =================================================================== --- lib/Target/AMDGPU/SIRegisterInfo.cpp +++ lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -1011,7 +1011,8 @@ 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: Index: lib/Target/Hexagon/HexagonBlockRanges.cpp =================================================================== --- lib/Target/Hexagon/HexagonBlockRanges.cpp +++ lib/Target/Hexagon/HexagonBlockRanges.cpp @@ -246,13 +246,13 @@ 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}); } } Index: lib/Target/Hexagon/HexagonExpandCondsets.cpp =================================================================== --- lib/Target/Hexagon/HexagonExpandCondsets.cpp +++ lib/Target/Hexagon/HexagonExpandCondsets.cpp @@ -356,7 +356,7 @@ 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 Index: lib/Target/Hexagon/RDFGraph.h =================================================================== --- lib/Target/Hexagon/RDFGraph.h +++ lib/Target/Hexagon/RDFGraph.h @@ -403,9 +403,9 @@ 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 @@ 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 Map; @@ -468,15 +468,15 @@ 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) }; Index: lib/Target/Hexagon/RDFGraph.cpp =================================================================== --- lib/Target/Hexagon/RDFGraph.cpp +++ lib/Target/Hexagon/RDFGraph.cpp @@ -30,7 +30,7 @@ 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 @@ 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::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 @@ 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::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); @@ -1210,7 +1210,8 @@ // (or the lane mask from the given register ref should be ignored). // This can happen when a register has only one unit. if (PA.first == PB.first) { - if (!PA.second || !PB.second || (PA.second & PB.second)) + if (PA.second.none() || PB.second.none() || + !(PA.second & PB.second).none()) return true; ++UMA; ++UMB; Index: lib/Target/Hexagon/RDFLiveness.cpp =================================================================== --- lib/Target/Hexagon/RDFLiveness.cpp +++ lib/Target/Hexagon/RDFLiveness.cpp @@ -659,7 +659,7 @@ RegisterRef UR = DFG.normalizeRef(getRestrictedRegRef(PUA)); for (const std::pair &T : RUs) { // Check if T.first aliases UR? - LaneBitmask M = 0; + LaneBitmask M; for (std::pair P : T.second) M |= P.second; @@ -710,7 +710,7 @@ } 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 @@ } 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 @@ 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)); Index: utils/TableGen/CodeGenRegisters.h =================================================================== --- utils/TableGen/CodeGenRegisters.h +++ utils/TableGen/CodeGenRegisters.h @@ -27,6 +27,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/CodeGen/MachineValueType.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LaneBitmask.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/SetTheory.h" #include @@ -47,7 +48,7 @@ /// 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 @@ uint16_t Size; uint16_t Offset; const unsigned EnumValue; - mutable unsigned LaneMask; + mutable LaneBitmask LaneMask; mutable SmallVector CompositionLaneMaskTransform; // Are all super-registers containing this SubRegIndex covered by their @@ -120,7 +121,7 @@ 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 @@ // List of register units in ascending order. typedef SparseBitVector<> RegUnitList; - typedef SmallVector RegUnitLaneMaskList; + typedef SmallVector RegUnitLaneMaskList; // How many entries in RegUnitList are native? RegUnitList NativeRegUnits; @@ -215,7 +216,7 @@ // This is only valid after computeSubRegs() completes. const RegUnitList &getRegUnits() const { return RegUnits; } - ArrayRef getRegUnitLaneMasks() const { + ArrayRef getRegUnitLaneMasks() const { return makeArrayRef(RegUnitLaneMasks).slice(0, NativeRegUnits.count()); } @@ -316,7 +317,7 @@ 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 @@ // 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 Index: utils/TableGen/CodeGenRegisters.cpp =================================================================== --- utils/TableGen/CodeGenRegisters.cpp +++ utils/TableGen/CodeGenRegisters.cpp @@ -51,7 +51,7 @@ //===----------------------------------------------------------------------===// CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) - : TheDef(R), EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) { + : TheDef(R), EnumValue(Enum), LaneMask(), AllSuperRegsCovered(true) { Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); @@ -62,7 +62,7 @@ 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), LaneMask(), AllSuperRegsCovered(true) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -102,19 +102,19 @@ } } -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; } @@ -679,7 +679,7 @@ Name(R->getName()), TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), - LaneMask(0) { + LaneMask() { // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; @@ -1193,7 +1193,7 @@ // 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 +1201,10 @@ Twine("Ran out of lanemask bits to represent subregister ") + Idx.getName()); } - Idx.LaneMask = 1u << Bit; + Idx.LaneMask = LaneBitmask::get(1) << Bit; ++Bit; } else { - Idx.LaneMask = 0; + Idx.LaneMask = LaneBitmask::getNone(); } } @@ -1223,9 +1223,12 @@ // 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::get(1) << DstBit && + "Must be a leaf subregister"); + MaskRolPair MaskRol = { LaneBitmask::get(1), (uint8_t)DstBit }; LaneTransforms.push_back(MaskRol); } else { // Go through all leaf subregisters and find the ones that compose with @@ -1239,7 +1242,7 @@ continue; // Replicate the behaviour from the lane mask generation loop above. unsigned SrcBit = NextBit; - unsigned SrcMask = 1u << SrcBit; + LaneBitmask SrcMask = LaneBitmask::get(1) << SrcBit; if (NextBit < 31) ++NextBit; assert(Idx2.LaneMask == SrcMask); @@ -1253,16 +1256,18 @@ 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; 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 @@ // 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 @@ // 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 @@ // 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 @@ // 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::get(1); RegClass.LaneMask = LaneMask; } @@ -1807,7 +1812,8 @@ 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 @@ 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; Index: utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- utils/TableGen/RegisterInfoEmitter.cpp +++ utils/TableGen/RegisterInfoEmitter.cpp @@ -578,7 +578,7 @@ // 0 differential which means we can't encode repeated elements. typedef SmallVector DiffVec; -typedef SmallVector MaskVec; +typedef SmallVector 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,10 @@ 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::get(0x"; + Val.print(OS); + OS << ')'; } // Try to combine Idx's compose map into Vec if it is compatible. @@ -739,7 +741,7 @@ } OS << " struct MaskRolOp {\n" - " unsigned Mask;\n" + " LaneBitmask Mask;\n" " uint8_t RotateLeft;\n" " };\n" " static const MaskRolOp LaneMaskComposeSequences[] = {\n"; @@ -749,9 +751,10 @@ const SmallVectorImpl &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,13 +777,9 @@ " 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" - " }\n" + " LaneBitmask Result;\n" + " for (const MaskRolOp *Ops = CompositeSequences[IdxA]; !Ops->Mask.none(); ++Ops)\n" + " Result |= LaneBitmask::rol(LaneMask & Ops->Mask, Ops->RotateLeft);\n" " return Result;\n" "}\n\n"; @@ -790,13 +789,9 @@ " 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" - " }\n" + " LaneBitmask Result;\n" + " for (const MaskRolOp *Ops = CompositeSequences[IdxA]; !Ops->Mask.none(); ++Ops)\n" + " Result |= LaneBitmask::ror(LaneMask, Ops->RotateLeft) & Ops->Mask;\n" " return Result;\n" "}\n\n"; } @@ -894,8 +889,8 @@ 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 +911,8 @@ 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 +1192,10 @@ 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 +1313,9 @@ << "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 +1404,7 @@ // 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 +1419,8 @@ << "(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