Skip to content

Commit 29e93f3

Browse files
author
Krzysztof Parzyszek
committed
[RDF] Add initial support for lane masks in the DFG
Use lane masks for calculating covering and aliasing of register references. llvm-svn: 282194
1 parent e68df59 commit 29e93f3

File tree

5 files changed

+163
-62
lines changed

5 files changed

+163
-62
lines changed

llvm/lib/Target/Hexagon/HexagonRDF.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
using namespace llvm;
1717
using namespace rdf;
1818

19-
bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
19+
bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
20+
const DataFlowGraph &DFG) const {
2021
if (RA == RB)
2122
return true;
2223

@@ -31,30 +32,33 @@ bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
3132
}
3233
}
3334

34-
return RegisterAliasInfo::covers(RA, RB);
35+
return RegisterAliasInfo::covers(RA, RB, DFG);
3536
}
3637

37-
bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR)
38-
const {
38+
bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
39+
const DataFlowGraph &DFG) const {
3940
if (RRs.count(RR))
4041
return true;
4142

42-
if (!TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
43-
assert(TargetRegisterInfo::isVirtualRegister(RR.Reg));
44-
// Check if both covering subregisters are present.
43+
// The exact reference RR is not in the set.
44+
45+
if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
46+
// Check if the there are references in RRs of the same register,
47+
// with both covering subregisters.
4548
bool HasLo = RRs.count({RR.Reg, Hexagon::subreg_loreg});
4649
bool HasHi = RRs.count({RR.Reg, Hexagon::subreg_hireg});
4750
if (HasLo && HasHi)
4851
return true;
4952
}
5053

51-
if (RR.Sub == 0) {
52-
// Check if both covering subregisters are present.
54+
if (TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
55+
// Check if both covering subregisters are present with full
56+
// lane masks.
5357
unsigned Lo = TRI.getSubReg(RR.Reg, Hexagon::subreg_loreg);
5458
unsigned Hi = TRI.getSubReg(RR.Reg, Hexagon::subreg_hireg);
5559
if (RRs.count({Lo, 0}) && RRs.count({Hi, 0}))
5660
return true;
5761
}
5862

59-
return RegisterAliasInfo::covers(RRs, RR);
63+
return RegisterAliasInfo::covers(RRs, RR, DFG);
6064
}

llvm/lib/Target/Hexagon/HexagonRDF.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ namespace rdf {
1818
struct HexagonRegisterAliasInfo : public RegisterAliasInfo {
1919
HexagonRegisterAliasInfo(const TargetRegisterInfo &TRI)
2020
: RegisterAliasInfo(TRI) {}
21-
bool covers(RegisterRef RA, RegisterRef RR) const override;
22-
bool covers(const RegisterSet &RRs, RegisterRef RR) const override;
21+
bool covers(RegisterRef RA, RegisterRef RR,
22+
const DataFlowGraph &DFG) const override;
23+
bool covers(const RegisterSet &RRs, RegisterRef RR,
24+
const DataFlowGraph &DFG) const override;
2325
};
2426
} // namespace rdf
2527
} // namespace llvm

llvm/lib/Target/Hexagon/RDFGraph.cpp

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,47 @@ NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) {
580580

581581
// Register aliasing information.
582582
//
583-
// In theory, the lane information could be used to determine register
584-
// covering (and aliasing), but depending on the sub-register structure,
585-
// the lane mask information may be missing. The covering information
586-
// must be available for this framework to work, so relying solely on
587-
// the lane data is not sufficient.
583+
584+
LaneBitmask RegisterAliasInfo::getLaneMask(RegisterRef RR,
585+
const DataFlowGraph &DFG) const {
586+
assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
587+
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(RR.Reg);
588+
return (RR.Sub != 0) ? DFG.getLaneMaskForIndex(RR.Sub) : RC->LaneMask;
589+
}
590+
591+
RegisterAliasInfo::CommonRegister::CommonRegister(
592+
unsigned RegA, LaneBitmask LA, unsigned RegB, LaneBitmask LB,
593+
const TargetRegisterInfo &TRI) {
594+
if (RegA == RegB) {
595+
SuperReg = RegA;
596+
MaskA = LA;
597+
MaskB = LB;
598+
return;
599+
}
600+
601+
// Find a common super-register.
602+
SuperReg = 0;
603+
for (MCSuperRegIterator SA(RegA, &TRI, true); SA.isValid(); ++SA) {
604+
if (!TRI.isSubRegisterEq(*SA, RegB))
605+
continue;
606+
SuperReg = *SA;
607+
break;
608+
}
609+
if (SuperReg == 0)
610+
return;
611+
612+
if (unsigned SubA = TRI.getSubRegIndex(SuperReg, RegA))
613+
LA = TRI.composeSubRegIndexLaneMask(SubA, LA);
614+
if (unsigned SubB = TRI.getSubRegIndex(SuperReg, RegB))
615+
LB = TRI.composeSubRegIndexLaneMask(SubB, LB);
616+
617+
MaskA = LA;
618+
MaskB = LB;
619+
}
588620

589621
// Determine whether RA covers RB.
590-
bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
622+
bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
623+
const DataFlowGraph &DFG) const {
591624
if (RA == RB)
592625
return true;
593626
if (TargetRegisterInfo::isVirtualRegister(RA.Reg)) {
@@ -601,13 +634,17 @@ bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB) const {
601634

602635
assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg) &&
603636
TargetRegisterInfo::isPhysicalRegister(RB.Reg));
604-
uint32_t A = RA.Sub != 0 ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg;
605-
uint32_t B = RB.Sub != 0 ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg;
606-
return TRI.isSubRegister(A, B);
637+
638+
CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
639+
RB.Reg, getLaneMask(RB, DFG), TRI);
640+
if (CR.SuperReg == 0)
641+
return false;
642+
return (CR.MaskA & CR.MaskB) == CR.MaskB;
607643
}
608644

609645
// Determine whether RR is covered by the set of references RRs.
610-
bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR) const {
646+
bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
647+
const DataFlowGraph &DFG) const {
611648
if (RRs.count(RR))
612649
return true;
613650

@@ -630,7 +667,7 @@ bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR) const {
630667
return false;
631668
}
632669

633-
// Get the list of references aliased to RR.
670+
// Get the list of references aliased to RR. Lane masks are ignored.
634671
std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
635672
// Do not include RR in the alias set. For virtual registers return an
636673
// empty set.
@@ -648,16 +685,17 @@ std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
648685
}
649686

650687
// Check whether RA and RB are aliased.
651-
bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
652-
bool VirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
653-
bool VirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
654-
bool PhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
655-
bool PhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
656-
657-
if (VirtA != VirtB)
688+
bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB,
689+
const DataFlowGraph &DFG) const {
690+
bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
691+
bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
692+
bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
693+
bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
694+
695+
if (IsVirtA != IsVirtB)
658696
return false;
659697

660-
if (VirtA) {
698+
if (IsVirtA) {
661699
if (RA.Reg != RB.Reg)
662700
return false;
663701
// RA and RB refer to the same register. If any of them refer to the
@@ -675,14 +713,14 @@ bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
675713
return false;
676714
}
677715

678-
assert(PhysA && PhysB);
679-
(void)PhysA, (void)PhysB;
680-
uint32_t A = RA.Sub ? TRI.getSubReg(RA.Reg, RA.Sub) : RA.Reg;
681-
uint32_t B = RB.Sub ? TRI.getSubReg(RB.Reg, RB.Sub) : RB.Reg;
682-
for (MCRegAliasIterator I(A, &TRI, true); I.isValid(); ++I)
683-
if (B == *I)
684-
return true;
685-
return false;
716+
assert(IsPhysA && IsPhysB);
717+
(void)IsPhysA, (void)IsPhysB;
718+
719+
CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
720+
RB.Reg, getLaneMask(RB, DFG), TRI);
721+
if (CR.SuperReg == 0)
722+
return false;
723+
return (CR.MaskA & CR.MaskB) != 0;
686724
}
687725

688726

@@ -1213,7 +1251,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
12131251
if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
12141252
continue;
12151253
RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() };
1216-
if (RAI.alias(DR, UR))
1254+
if (RAI.alias(DR, UR, *this))
12171255
return false;
12181256
}
12191257
return true;
@@ -1398,7 +1436,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,
13981436

13991437
auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
14001438
for (auto I : RRs)
1401-
if (I != RR && RAI.covers(I, RR))
1439+
if (I != RR && RAI.covers(I, RR, *this))
14021440
RR = I;
14031441
return RR;
14041442
};
@@ -1425,7 +1463,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,
14251463
auto Aliased = [this,&MaxRefs](RegisterRef RR,
14261464
std::vector<unsigned> &Closure) -> bool {
14271465
for (auto I : Closure)
1428-
if (RAI.alias(RR, MaxRefs[I]))
1466+
if (RAI.alias(RR, MaxRefs[I], *this))
14291467
return true;
14301468
return false;
14311469
};
@@ -1544,9 +1582,9 @@ void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA,
15441582
for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
15451583
RegisterRef QR = I->Addr->getRegRef();
15461584
auto AliasQR = [QR,this] (RegisterRef RR) -> bool {
1547-
return RAI.alias(QR, RR);
1585+
return RAI.alias(QR, RR, *this);
15481586
};
1549-
bool PrecUp = RAI.covers(QR, RR);
1587+
bool PrecUp = RAI.covers(QR, RR, *this);
15501588
// Skip all defs that are aliased to any of the defs that we have already
15511589
// seen. If we encounter a covering def, stop the stack traversal early.
15521590
if (any_of(Defs, AliasQR)) {

llvm/lib/Target/Hexagon/RDFGraph.h

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
#include "llvm/Support/Debug.h"
222222
#include "llvm/Support/raw_ostream.h"
223223
#include "llvm/Support/Timer.h"
224+
#include "llvm/Target/TargetRegisterInfo.h"
224225

225226
#include <functional>
226227
#include <map>
@@ -236,11 +237,12 @@ namespace llvm {
236237
class MachineDominanceFrontier;
237238
class MachineDominatorTree;
238239
class TargetInstrInfo;
239-
class TargetRegisterInfo;
240240

241241
namespace rdf {
242242
typedef uint32_t NodeId;
243243

244+
struct DataFlowGraph;
245+
244246
struct NodeAttrs {
245247
enum : uint16_t {
246248
None = 0x0000, // Nothing
@@ -384,6 +386,15 @@ namespace rdf {
384386
};
385387

386388
struct RegisterRef {
389+
// For virtual registers, Reg and Sub have the usual meanings.
390+
//
391+
// Physical registers are assumed not to have any subregisters, and for
392+
// them, Sub is the key of the LaneBitmask in the lane mask map in DFG.
393+
// The case of Sub = 0 is treated as 'all lanes', i.e. lane mask of ~0.
394+
// Use an key/map to access lane masks, since we only have uint32_t
395+
// for it, and the LaneBitmask type can grow in the future.
396+
//
397+
// The case when Reg = 0 and Sub = 0 is reserved to mean "no register".
387398
uint32_t Reg, Sub;
388399

389400
// No non-trivial constructors, since this will be a member of a union.
@@ -407,11 +418,25 @@ namespace rdf {
407418
virtual ~RegisterAliasInfo() {}
408419

409420
virtual std::vector<RegisterRef> getAliasSet(RegisterRef RR) const;
410-
virtual bool alias(RegisterRef RA, RegisterRef RB) const;
411-
virtual bool covers(RegisterRef RA, RegisterRef RB) const;
412-
virtual bool covers(const RegisterSet &RRs, RegisterRef RR) const;
421+
virtual bool alias(RegisterRef RA, RegisterRef RB,
422+
const DataFlowGraph &DFG) const;
423+
virtual bool covers(RegisterRef RA, RegisterRef RB,
424+
const DataFlowGraph &DFG) const;
425+
virtual bool covers(const RegisterSet &RRs, RegisterRef RR,
426+
const DataFlowGraph &DFG) const;
413427

414428
const TargetRegisterInfo &TRI;
429+
430+
protected:
431+
LaneBitmask getLaneMask(RegisterRef RR, const DataFlowGraph &DFG) const;
432+
433+
struct CommonRegister {
434+
CommonRegister(unsigned RegA, LaneBitmask LA,
435+
unsigned RegB, LaneBitmask LB,
436+
const TargetRegisterInfo &TRI);
437+
unsigned SuperReg;
438+
LaneBitmask MaskA, MaskB;
439+
};
415440
};
416441

417442
struct TargetOperandInfo {
@@ -424,8 +449,31 @@ namespace rdf {
424449
const TargetInstrInfo &TII;
425450
};
426451

452+
// Template class for a map translating uint32_t into arbitrary types.
453+
// The map will act like an indexed set: upon insertion of a new object,
454+
// it will automatically assign a new index to it. Index of 0 is treated
455+
// as invalid and is never allocated.
456+
template <typename T, unsigned N = 32>
457+
struct IndexedSet {
458+
IndexedSet() : Map(N) {}
459+
const T get(uint32_t Idx) const {
460+
// Index Idx corresponds to Map[Idx-1].
461+
assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
462+
return Map[Idx-1];
463+
}
464+
uint32_t insert(T Val) {
465+
// Linear search.
466+
auto F = find(Map, Val);
467+
if (F != Map.end())
468+
return *F;
469+
Map.push_back(Val);
470+
return Map.size(); // Return actual_index + 1.
471+
}
472+
473+
private:
474+
std::vector<T> Map;
475+
};
427476

428-
struct DataFlowGraph;
429477

430478
struct NodeBase {
431479
public:
@@ -648,6 +696,13 @@ namespace rdf {
648696
return RAI;
649697
}
650698

699+
LaneBitmask getLaneMaskForIndex(uint32_t K) const {
700+
return LMMap.get(K);
701+
}
702+
uint32_t getIndexForLaneMask(LaneBitmask LM) {
703+
return LMMap.insert(LM);
704+
}
705+
651706
struct DefStack {
652707
DefStack() = default;
653708
bool empty() const { return Stack.empty() || top() == bottom(); }
@@ -820,6 +875,8 @@ namespace rdf {
820875
NodeAllocator Memory;
821876
// Local map: MachineBasicBlock -> NodeAddr<BlockNode*>
822877
std::map<MachineBasicBlock*,NodeAddr<BlockNode*>> BlockNodes;
878+
// Lane mask map.
879+
IndexedSet<LaneBitmask> LMMap;
823880

824881
MachineFunction &MF;
825882
const TargetInstrInfo &TII;

0 commit comments

Comments
 (0)