Skip to content

Commit 91b5cf8

Browse files
author
Krzysztof Parzyszek
committed
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
1 parent 2f7f0e7 commit 91b5cf8

40 files changed

+421
-326
lines changed

llvm/include/llvm/CodeGen/LiveIntervalAnalysis.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ extern cl::opt<bool> UseSegmentSetForPhysRegs;
459459
void repairOldRegInRange(MachineBasicBlock::iterator Begin,
460460
MachineBasicBlock::iterator End,
461461
const SlotIndex endIdx, LiveRange &LR,
462-
unsigned Reg, LaneBitmask LaneMask = ~0u);
462+
unsigned Reg,
463+
LaneBitmask LaneMask = LaneBitmask::getAll());
463464

464465
class HMEditor;
465466
};

llvm/include/llvm/CodeGen/MachineBasicBlock.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
2020
#include "llvm/CodeGen/MachineInstr.h"
2121
#include "llvm/Support/BranchProbability.h"
22+
#include "llvm/MC/LaneBitmask.h"
2223
#include "llvm/MC/MCRegisterInfo.h"
2324
#include "llvm/Support/DataTypes.h"
2425
#include <functional>
@@ -35,9 +36,6 @@ class StringRef;
3536
class raw_ostream;
3637
class MachineBranchProbabilityInfo;
3738

38-
// Forward declaration to avoid circular include problem with TargetRegisterInfo
39-
typedef unsigned LaneBitmask;
40-
4139
template <> struct ilist_traits<MachineInstr> {
4240
private:
4341
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
@@ -278,7 +276,8 @@ class MachineBasicBlock
278276
/// Adds the specified register as a live in. Note that it is an error to add
279277
/// the same register to the same set more than once unless the intention is
280278
/// to call sortUniqueLiveIns after all registers are added.
281-
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask = ~0u) {
279+
void addLiveIn(MCPhysReg PhysReg,
280+
LaneBitmask LaneMask = LaneBitmask::getAll()) {
282281
LiveIns.push_back(RegisterMaskPair(PhysReg, LaneMask));
283282
}
284283
void addLiveIn(const RegisterMaskPair &RegMaskPair) {
@@ -296,10 +295,12 @@ class MachineBasicBlock
296295
unsigned addLiveIn(MCPhysReg PhysReg, const TargetRegisterClass *RC);
297296

298297
/// Remove the specified register from the live in set.
299-
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u);
298+
void removeLiveIn(MCPhysReg Reg,
299+
LaneBitmask LaneMask = LaneBitmask::getAll());
300300

301301
/// Return true if the specified register is in the live in set.
302-
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask = ~0u) const;
302+
bool isLiveIn(MCPhysReg Reg,
303+
LaneBitmask LaneMask = LaneBitmask::getAll()) const;
303304

304305
// Iteration support for live in sets. These sets are kept in sorted
305306
// order by their register number.

llvm/include/llvm/CodeGen/RegisterPressure.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class LiveRegSet {
278278
unsigned SparseIndex = getSparseIndexFromReg(Reg);
279279
RegSet::const_iterator I = Regs.find(SparseIndex);
280280
if (I == Regs.end())
281-
return 0;
281+
return LaneBitmask::getNone();
282282
return I->LaneMask;
283283
}
284284

@@ -288,11 +288,11 @@ class LiveRegSet {
288288
unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
289289
auto InsertRes = Regs.insert(IndexMaskPair(SparseIndex, Pair.LaneMask));
290290
if (!InsertRes.second) {
291-
unsigned PrevMask = InsertRes.first->LaneMask;
291+
LaneBitmask PrevMask = InsertRes.first->LaneMask;
292292
InsertRes.first->LaneMask |= Pair.LaneMask;
293293
return PrevMask;
294294
}
295-
return 0;
295+
return LaneBitmask::getNone();
296296
}
297297

298298
/// Clears the \p Pair.LaneMask lanes of \p Pair.Reg (mark them as dead).
@@ -301,8 +301,8 @@ class LiveRegSet {
301301
unsigned SparseIndex = getSparseIndexFromReg(Pair.RegUnit);
302302
RegSet::iterator I = Regs.find(SparseIndex);
303303
if (I == Regs.end())
304-
return 0;
305-
unsigned PrevMask = I->LaneMask;
304+
return LaneBitmask::getNone();
305+
LaneBitmask PrevMask = I->LaneMask;
306306
I->LaneMask &= ~Pair.LaneMask;
307307
return PrevMask;
308308
}
@@ -315,7 +315,7 @@ class LiveRegSet {
315315
void appendTo(ContainerT &To) const {
316316
for (const IndexMaskPair &P : Regs) {
317317
unsigned Reg = getRegFromSparseIndex(P.Index);
318-
if (P.LaneMask != 0)
318+
if (!P.LaneMask.none())
319319
To.push_back(RegisterMaskPair(Reg, P.LaneMask));
320320
}
321321
}

llvm/include/llvm/CodeGen/RegisterScavenging.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class RegScavenger {
164164
}
165165

166166
/// Tell the scavenger a register is used.
167-
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = ~0u);
167+
void setRegUsed(unsigned Reg, LaneBitmask LaneMask = LaneBitmask::getAll());
168168
private:
169169
/// Returns true if a register is reserved. It is never "unused".
170170
bool isReserved(unsigned Reg) const { return MRI->isReserved(Reg); }

llvm/include/llvm/MC/LaneBitmask.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//===-- llvm/MC/LaneBitmask.h -----------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
///
10+
/// \file
11+
/// A common definition of LaneBitmask for use in TableGen and CodeGen.
12+
///
13+
/// A lane mask is a bitmask representing the covering of a register with
14+
/// sub-registers.
15+
///
16+
/// This is typically used to track liveness at sub-register granularity.
17+
/// Lane masks for sub-register indices are similar to register units for
18+
/// physical registers. The individual bits in a lane mask can't be assigned
19+
/// any specific meaning. They can be used to check if two sub-register
20+
/// indices overlap.
21+
///
22+
/// Iff the target has a register such that:
23+
///
24+
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
25+
///
26+
/// then:
27+
///
28+
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
29+
30+
#ifndef LLVM_MC_LANEBITMASK_H
31+
#define LLVM_MC_LANEBITMASK_H
32+
33+
#include "llvm/Support/Format.h"
34+
#include "llvm/Support/Printable.h"
35+
#include "llvm/Support/raw_ostream.h"
36+
37+
namespace llvm {
38+
struct LaneBitmask {
39+
// When changing the underlying type, change the format string as well.
40+
typedef unsigned Type;
41+
enum : unsigned { BitWidth = 8*sizeof(Type) };
42+
constexpr static const char *const FormatStr = "%08X";
43+
44+
constexpr LaneBitmask() = default;
45+
explicit constexpr LaneBitmask(Type V) : Mask(V) {}
46+
47+
constexpr bool operator== (LaneBitmask M) const { return Mask == M.Mask; }
48+
constexpr bool operator!= (LaneBitmask M) const { return Mask != M.Mask; }
49+
constexpr bool operator< (LaneBitmask M) const { return Mask < M.Mask; }
50+
constexpr bool none() const { return Mask == 0; }
51+
constexpr bool all() const { return ~Mask == 0; }
52+
53+
constexpr LaneBitmask operator~() const {
54+
return LaneBitmask(~Mask);
55+
}
56+
constexpr LaneBitmask operator|(LaneBitmask M) const {
57+
return LaneBitmask(Mask | M.Mask);
58+
}
59+
constexpr LaneBitmask operator&(LaneBitmask M) const {
60+
return LaneBitmask(Mask & M.Mask);
61+
}
62+
LaneBitmask &operator|=(LaneBitmask M) {
63+
Mask |= M.Mask;
64+
return *this;
65+
}
66+
LaneBitmask &operator&=(LaneBitmask M) {
67+
Mask &= M.Mask;
68+
return *this;
69+
}
70+
71+
constexpr Type getAsInteger() const { return Mask; }
72+
73+
static LaneBitmask getNone() { return LaneBitmask(0); }
74+
static LaneBitmask getAll() { return ~LaneBitmask(0); }
75+
76+
private:
77+
Type Mask = 0;
78+
};
79+
80+
/// Create Printable object to print LaneBitmasks on a \ref raw_ostream.
81+
static LLVM_ATTRIBUTE_UNUSED Printable PrintLaneMask(LaneBitmask LaneMask) {
82+
return Printable([LaneMask](raw_ostream &OS) {
83+
OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger());
84+
});
85+
}
86+
}
87+
88+
#endif // LLVM_MC_LANEBITMASK_H

llvm/include/llvm/MC/MCRegisterInfo.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define LLVM_MC_MCREGISTERINFO_H
1818

1919
#include "llvm/ADT/DenseMap.h"
20+
#include "llvm/MC/LaneBitmask.h"
2021
#include "llvm/Support/ErrorHandling.h"
2122
#include <cassert>
2223

@@ -161,7 +162,7 @@ class MCRegisterInfo {
161162
unsigned NumRegUnits; // Number of regunits.
162163
const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table.
163164
const MCPhysReg *DiffLists; // Pointer to the difflists array
164-
const unsigned *RegUnitMaskSequences; // Pointer to lane mask sequences
165+
const LaneBitmask *RegUnitMaskSequences; // Pointer to lane mask sequences
165166
// for register units.
166167
const char *RegStrings; // Pointer to the string table.
167168
const char *RegClassStrings; // Pointer to the class strings.
@@ -248,7 +249,7 @@ class MCRegisterInfo {
248249
const MCPhysReg (*RURoots)[2],
249250
unsigned NRU,
250251
const MCPhysReg *DL,
251-
const unsigned *RUMS,
252+
const LaneBitmask *RUMS,
252253
const char *Strings,
253254
const char *ClassStrings,
254255
const uint16_t *SubIndices,
@@ -584,7 +585,7 @@ class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
584585
/// numerical order.
585586
class MCRegUnitMaskIterator {
586587
MCRegUnitIterator RUIter;
587-
const unsigned *MaskListIter;
588+
const LaneBitmask *MaskListIter;
588589
public:
589590
MCRegUnitMaskIterator() {}
590591
/// Constructs an iterator that traverses the register units and their
@@ -596,7 +597,7 @@ class MCRegUnitMaskIterator {
596597
}
597598

598599
/// Returns a (RegUnit, LaneMask) pair.
599-
std::pair<unsigned,unsigned> operator*() const {
600+
std::pair<unsigned,LaneBitmask> operator*() const {
600601
return std::make_pair(*RUIter, *MaskListIter);
601602
}
602603

llvm/include/llvm/Target/TargetRegisterInfo.h

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,6 @@ class VirtRegMap;
3636
class raw_ostream;
3737
class LiveRegMatrix;
3838

39-
/// A bitmask representing the covering of a register with sub-registers.
40-
///
41-
/// This is typically used to track liveness at sub-register granularity.
42-
/// Lane masks for sub-register indices are similar to register units for
43-
/// physical registers. The individual bits in a lane mask can't be assigned
44-
/// any specific meaning. They can be used to check if two sub-register
45-
/// indices overlap.
46-
///
47-
/// Iff the target has a register such that:
48-
///
49-
/// getSubReg(Reg, A) overlaps getSubReg(Reg, B)
50-
///
51-
/// then:
52-
///
53-
/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
54-
typedef unsigned LaneBitmask;
55-
5639
class TargetRegisterClass {
5740
public:
5841
typedef const MCPhysReg* iterator;
@@ -269,15 +252,15 @@ class TargetRegisterInfo : public MCRegisterInfo {
269252
const LaneBitmask *SubRegIndexLaneMasks;
270253

271254
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
272-
unsigned CoveringLanes;
255+
LaneBitmask CoveringLanes;
273256

274257
protected:
275258
TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
276259
regclass_iterator RegClassBegin,
277260
regclass_iterator RegClassEnd,
278261
const char *const *SRINames,
279262
const LaneBitmask *SRILaneMasks,
280-
unsigned CoveringLanes);
263+
LaneBitmask CoveringLanes);
281264
virtual ~TargetRegisterInfo();
282265
public:
283266

@@ -1141,9 +1124,6 @@ Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI);
11411124
/// registers on a \ref raw_ostream.
11421125
Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI);
11431126

1144-
/// Create Printable object to print LaneBitmasks on a \ref raw_ostream.
1145-
Printable PrintLaneMask(LaneBitmask LaneMask);
1146-
11471127
} // End llvm namespace
11481128

11491129
#endif

llvm/lib/CodeGen/DetectDeadLanes.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ void DetectDeadLanes::addUsedLanesOnOperand(const MachineOperand &MO,
210210
VRegInfo &MORegInfo = VRegInfos[MORegIdx];
211211
LaneBitmask PrevUsedLanes = MORegInfo.UsedLanes;
212212
// Any change at all?
213-
if ((UsedLanes & ~PrevUsedLanes) == 0)
213+
if ((UsedLanes & ~PrevUsedLanes).none())
214214
return;
215215

216216
// Set UsedLanes and remember instruction for further propagation.
@@ -303,7 +303,7 @@ void DetectDeadLanes::transferDefinedLanesStep(const MachineOperand &Use,
303303
VRegInfo &RegInfo = VRegInfos[DefRegIdx];
304304
LaneBitmask PrevDefinedLanes = RegInfo.DefinedLanes;
305305
// Any change at all?
306-
if ((DefinedLanes & ~PrevDefinedLanes) == 0)
306+
if ((DefinedLanes & ~PrevDefinedLanes).none())
307307
return;
308308

309309
RegInfo.DefinedLanes = PrevDefinedLanes | DefinedLanes;
@@ -356,7 +356,7 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
356356
// Live-In or unused registers have no definition but are considered fully
357357
// defined.
358358
if (!MRI->hasOneDef(Reg))
359-
return ~0u;
359+
return LaneBitmask::getAll();
360360

361361
const MachineOperand &Def = *MRI->def_begin(Reg);
362362
const MachineInstr &DefMI = *Def.getParent();
@@ -368,15 +368,15 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
368368
PutInWorklist(RegIdx);
369369

370370
if (Def.isDead())
371-
return 0;
371+
return LaneBitmask::getNone();
372372

373373
// COPY/PHI can copy across unrelated register classes (example: float/int)
374374
// with incompatible subregister structure. Do not include these in the
375375
// dataflow analysis since we cannot transfer lanemasks in a meaningful way.
376376
const TargetRegisterClass *DefRC = MRI->getRegClass(Reg);
377377

378378
// Determine initially DefinedLanes.
379-
LaneBitmask DefinedLanes = 0;
379+
LaneBitmask DefinedLanes;
380380
for (const MachineOperand &MO : DefMI.uses()) {
381381
if (!MO.isReg() || !MO.readsReg())
382382
continue;
@@ -386,9 +386,9 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
386386

387387
LaneBitmask MODefinedLanes;
388388
if (TargetRegisterInfo::isPhysicalRegister(MOReg)) {
389-
MODefinedLanes = ~0u;
389+
MODefinedLanes = LaneBitmask::getAll();
390390
} else if (isCrossCopy(*MRI, DefMI, DefRC, MO)) {
391-
MODefinedLanes = ~0u;
391+
MODefinedLanes = LaneBitmask::getAll();
392392
} else {
393393
assert(TargetRegisterInfo::isVirtualRegister(MOReg));
394394
if (MRI->hasOneDef(MOReg)) {
@@ -410,15 +410,15 @@ LaneBitmask DetectDeadLanes::determineInitialDefinedLanes(unsigned Reg) {
410410
return DefinedLanes;
411411
}
412412
if (DefMI.isImplicitDef() || Def.isDead())
413-
return 0;
413+
return LaneBitmask::getNone();
414414

415415
assert(Def.getSubReg() == 0 &&
416416
"Should not have subregister defs in machine SSA phase");
417417
return MRI->getMaxLaneMaskForVReg(Reg);
418418
}
419419

420420
LaneBitmask DetectDeadLanes::determineInitialUsedLanes(unsigned Reg) {
421-
LaneBitmask UsedLanes = 0;
421+
LaneBitmask UsedLanes = LaneBitmask::getNone();
422422
for (const MachineOperand &MO : MRI->use_nodbg_operands(Reg)) {
423423
if (!MO.readsReg())
424424
continue;
@@ -462,7 +462,7 @@ bool DetectDeadLanes::isUndefRegAtInput(const MachineOperand &MO,
462462
const VRegInfo &RegInfo) const {
463463
unsigned SubReg = MO.getSubReg();
464464
LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
465-
return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask) == 0;
465+
return (RegInfo.DefinedLanes & RegInfo.UsedLanes & Mask).none();
466466
}
467467

468468
bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
@@ -482,7 +482,7 @@ bool DetectDeadLanes::isUndefInput(const MachineOperand &MO,
482482

483483
const VRegInfo &DefRegInfo = VRegInfos[DefRegIdx];
484484
LaneBitmask UsedLanes = transferUsedLanes(MI, DefRegInfo.UsedLanes, MO);
485-
if (UsedLanes != 0)
485+
if (!UsedLanes.none())
486486
return false;
487487

488488
unsigned MOReg = MO.getReg();
@@ -546,7 +546,7 @@ bool DetectDeadLanes::runOnce(MachineFunction &MF) {
546546
continue;
547547
unsigned RegIdx = TargetRegisterInfo::virtReg2Index(Reg);
548548
const VRegInfo &RegInfo = VRegInfos[RegIdx];
549-
if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes == 0) {
549+
if (MO.isDef() && !MO.isDead() && RegInfo.UsedLanes.none()) {
550550
DEBUG(dbgs() << "Marking operand '" << MO << "' as dead in " << MI);
551551
MO.setIsDead();
552552
}

0 commit comments

Comments
 (0)