Skip to content

Commit

Permalink
[RDF] Extract the physical register information into a separate class
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293510 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Krzysztof Parzyszek committed Jan 30, 2017
1 parent 78e51c0 commit 91c16f1
Show file tree
Hide file tree
Showing 7 changed files with 344 additions and 254 deletions.
1 change: 1 addition & 0 deletions lib/Target/Hexagon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ add_llvm_target(HexagonCodeGen
RDFDeadCode.cpp
RDFGraph.cpp
RDFLiveness.cpp
RDFRegisters.cpp
)

add_subdirectory(AsmParser)
Expand Down
167 changes: 6 additions & 161 deletions lib/Target/Hexagon/RDFGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,117 +654,15 @@ bool TargetOperandInfo::isFixedReg(const MachineInstr &In, unsigned OpNum)
return false;
}

RegisterRef RegisterAggr::normalize(RegisterRef RR) const {
RegisterId SuperReg = RR.Reg;
while (true) {
MCSuperRegIterator SR(SuperReg, &TRI, false);
if (!SR.isValid())
break;
SuperReg = *SR;
}

const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg);
LaneBitmask Common = RR.Mask & RC.LaneMask;
uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
LaneBitmask SuperMask = TRI.composeSubRegIndexLaneMask(Sub, Common);
return RegisterRef(SuperReg, SuperMask);
}

bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
RegisterRef NR = normalize(RR);
auto F = Masks.find(NR.Reg);
if (F != Masks.end()) {
if ((F->second & NR.Mask).any())
return true;
}
if (CheckUnits) {
for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U)
if (ExpAliasUnits.test(*U))
return true;
}
return false;
}

bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
// Always have a cover for empty lane mask.
RegisterRef NR = normalize(RR);
if (NR.Mask.none())
return true;
auto F = Masks.find(NR.Reg);
if (F == Masks.end())
return false;
return (NR.Mask & F->second) == NR.Mask;
}

RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
RegisterRef NR = normalize(RR);
auto F = Masks.find(NR.Reg);
if (F == Masks.end())
Masks.insert({NR.Reg, NR.Mask});
else
F->second |= NR.Mask;

// Visit all register units to see if there are any that were created
// by explicit aliases. Add those that were to the bit vector.
for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U) {
MCRegUnitRootIterator R(*U, &TRI);
++R;
if (!R.isValid())
continue;
ExpAliasUnits.set(*U);
CheckUnits = true;
}
return *this;
}

RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
insert(RegisterRef(P.first, P.second));
return *this;
}

RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
RegisterRef NR = normalize(RR);
auto F = Masks.find(NR.Reg);
if (F == Masks.end())
return *this;
LaneBitmask NewM = F->second & ~NR.Mask;
if (NewM.none())
Masks.erase(F);
else
F->second = NewM;
return *this;
}

RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
clear(RegisterRef(P.first, P.second));
return *this;
}

RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
RegisterAggr T(TRI);
T.insert(RR).clear(*this);
if (T.empty())
return RegisterRef();
return RegisterRef(T.begin()->first, T.begin()->second);
}

void RegisterAggr::print(raw_ostream &OS) const {
OS << '{';
for (auto I : Masks)
OS << ' ' << PrintReg(I.first, &TRI) << PrintLaneMaskOpt(I.second);
OS << " }";
}

//
// The data flow graph construction.
//

DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
: MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi), LiveIns(TRI) {
: MF(mf), TII(tii), TRI(tri), PRI(tri, mf), MDT(mdt), MDF(mdf), TOI(toi),
LiveIns(PRI) {
}

// The implementation of the definition stack.
Expand Down Expand Up @@ -1211,59 +1109,6 @@ NodeList DataFlowGraph::getRelatedRefs(NodeAddr<InstrNode*> IA,
return Refs;
}

// Return true if RA and RB overlap, false otherwise.
bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg));
assert(TargetRegisterInfo::isPhysicalRegister(RB.Reg));

MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
MCRegUnitMaskIterator UMB(RB.Reg, &TRI);
// Reg units are returned in the numerical order.
while (UMA.isValid() && UMB.isValid()) {
std::pair<uint32_t,LaneBitmask> PA = *UMA;
std::pair<uint32_t,LaneBitmask> PB = *UMB;
if (PA.first == PB.first) {
// Lane mask of 0 (given by the iterator) should be treated as "full".
// This can happen when the register has only one unit, or when the
// unit corresponds to explicit aliasing. In such cases, the lane mask
// from RegisterRef should be ignored.
if (PA.second.none() || PB.second.none())
return true;

// At this point the common unit corresponds to a subregister. The lane
// masks correspond to the lane mask of that unit within the original
// register, for example assuming register quadruple q0 = r3:0, and
// a register pair d1 = r3:2, the lane mask of r2 in q0 may be 0b0100,
// while the lane mask of r2 in d1 may be 0b0001.
LaneBitmask LA = PA.second & RA.Mask;
LaneBitmask LB = PB.second & RB.Mask;
if (LA.any() && LB.any()) {
unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
// If register units were guaranteed to only have 1 bit in any lane
// mask, the code below would not be necessary. This is because LA
// and LB would have at most 1 bit set each, and that bit would be
// guaranteed to correspond to the given register unit.
uint32_t SubA = TRI.getSubRegIndex(RA.Reg, Root);
uint32_t SubB = TRI.getSubRegIndex(RB.Reg, Root);
const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Root);
LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
if ((MaskA & MaskB & RC.LaneMask).any())
return true;
}

++UMA;
++UMB;
continue;
}
if (PA.first < PB.first)
++UMA;
else if (PB.first < PA.first)
++UMB;
}
return false;
}

// Clear all information in the graph.
void DataFlowGraph::reset() {
Memory.clear();
Expand Down Expand Up @@ -1392,7 +1237,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
continue;
RegisterRef UR = makeRegRef(UseOp.getReg(), UseOp.getSubReg());
if (alias(DR, UR))
if (PRI.alias(DR, UR))
return false;
}
return true;
Expand Down Expand Up @@ -1578,7 +1423,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,

auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
for (RegisterRef I : RRs)
if (I != RR && RegisterAggr::isCoverOf(I, RR, TRI))
if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
RR = I;
return RR;
};
Expand All @@ -1605,7 +1450,7 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, BlockRefsMap &RefM,
auto Aliased = [this,&MaxRefs](RegisterRef RR,
std::vector<unsigned> &Closure) -> bool {
for (unsigned I : Closure)
if (alias(RR, MaxRefs[I]))
if (PRI.alias(RR, MaxRefs[I]))
return true;
return false;
};
Expand Down Expand Up @@ -1716,7 +1561,7 @@ void DataFlowGraph::linkRefUp(NodeAddr<InstrNode*> IA, NodeAddr<T> TA,
NodeAddr<T> TAP;

// References from the def stack that have been examined so far.
RegisterAggr Defs(TRI);
RegisterAggr Defs(PRI);

for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
RegisterRef QR = I->Addr->getRegRef(*this);
Expand Down
94 changes: 13 additions & 81 deletions lib/Target/Hexagon/RDFGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
#define LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H

#include "RDFRegisters.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/LaneBitmask.h"
Expand Down Expand Up @@ -260,7 +261,6 @@ namespace llvm {
namespace rdf {

typedef uint32_t NodeId;
typedef uint32_t RegisterId;

struct DataFlowGraph;

Expand Down Expand Up @@ -412,25 +412,6 @@ namespace rdf {
AllocatorTy MemPool;
};

struct RegisterRef {
RegisterId Reg;
LaneBitmask Mask;

RegisterRef() : RegisterRef(0) {}
explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
: Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}

operator bool() const { return Reg != 0 && Mask.any(); }
bool operator== (const RegisterRef &RR) const {
return Reg == RR.Reg && Mask == RR.Mask;
}
bool operator!= (const RegisterRef &RR) const {
return !operator==(RR);
}
bool operator< (const RegisterRef &RR) const {
return Reg < RR.Reg || (Reg == RR.Reg && Mask < RR.Mask);
}
};
typedef std::set<RegisterRef> RegisterSet;

struct TargetOperandInfo {
Expand Down Expand Up @@ -497,55 +478,6 @@ namespace rdf {
assert(LM.any());
return LM.all() ? 0 : find(LM);
}

PackedRegisterRef pack(RegisterRef RR) {
return { RR.Reg, getIndexForLaneMask(RR.Mask) };
}
PackedRegisterRef pack(RegisterRef RR) const {
return { RR.Reg, getIndexForLaneMask(RR.Mask) };
}

RegisterRef unpack(PackedRegisterRef PR) const {
return RegisterRef(PR.Reg, getLaneMaskForIndex(PR.MaskId));
}
};

struct RegisterAggr {
RegisterAggr(const TargetRegisterInfo &tri)
: ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false), TRI(tri) {}
RegisterAggr(const RegisterAggr &RG) = default;

bool empty() const { return Masks.empty(); }
bool hasAliasOf(RegisterRef RR) const;
bool hasCoverOf(RegisterRef RR) const;
static bool isCoverOf(RegisterRef RA, RegisterRef RB,
const TargetRegisterInfo &TRI) {
return RegisterAggr(TRI).insert(RA).hasCoverOf(RB);
}

RegisterAggr &insert(RegisterRef RR);
RegisterAggr &insert(const RegisterAggr &RG);
RegisterAggr &clear(RegisterRef RR);
RegisterAggr &clear(const RegisterAggr &RG);

RegisterRef clearIn(RegisterRef RR) const;

void print(raw_ostream &OS) const;

private:
typedef std::unordered_map<RegisterId, LaneBitmask> MapType;

public:
typedef MapType::const_iterator iterator;
iterator begin() const { return Masks.begin(); }
iterator end() const { return Masks.end(); }
RegisterRef normalize(RegisterRef RR) const;

private:
MapType Masks;
BitVector ExpAliasUnits; // Register units for explicit aliases.
bool CheckUnits;
const TargetRegisterInfo &TRI;
};

struct NodeBase {
Expand Down Expand Up @@ -761,6 +693,7 @@ namespace rdf {
MachineFunction &getMF() const { return MF; }
const TargetInstrInfo &getTII() const { return TII; }
const TargetRegisterInfo &getTRI() const { return TRI; }
const PhysicalRegisterInfo &getPRI() const { return PRI; }
const MachineDominatorTree &getDT() const { return MDT; }
const MachineDominanceFrontier &getDF() const { return MDF; }
const RegisterAggr &getLiveIns() const { return LiveIns; }
Expand Down Expand Up @@ -833,9 +766,16 @@ namespace rdf {
void markBlock(NodeId B, DefStackMap &DefM);
void releaseBlock(NodeId B, DefStackMap &DefM);

PackedRegisterRef pack(RegisterRef RR) { return LMI.pack(RR); }
PackedRegisterRef pack(RegisterRef RR) const { return LMI.pack(RR); }
RegisterRef unpack(PackedRegisterRef PR) const { return LMI.unpack(PR); }
PackedRegisterRef pack(RegisterRef RR) {
return { RR.Reg, LMI.getIndexForLaneMask(RR.Mask) };
}
PackedRegisterRef pack(RegisterRef RR) const {
return { RR.Reg, LMI.getIndexForLaneMask(RR.Mask) };
}
RegisterRef unpack(PackedRegisterRef PR) const {
return RegisterRef(PR.Reg, LMI.getLaneMaskForIndex(PR.MaskId));
}

RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const;
RegisterRef normalizeRef(RegisterRef RR) const;
RegisterRef restrictRef(RegisterRef AR, RegisterRef BR) const;
Expand Down Expand Up @@ -899,9 +839,6 @@ namespace rdf {
return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
}

// Register aliasing.
bool alias(RegisterRef RA, RegisterRef RB) const;

private:
void reset();

Expand Down Expand Up @@ -961,6 +898,7 @@ namespace rdf {
MachineFunction &MF;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
const PhysicalRegisterInfo PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
const TargetOperandInfo &TOI;
Expand Down Expand Up @@ -1015,12 +953,6 @@ namespace rdf {
return MM;
}

// Optionally print the lane mask, if it is not ~0.
struct PrintLaneMaskOpt {
PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
LaneBitmask Mask;
};
raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P);

template <typename T> struct Print;
template <typename T>
Expand Down
Loading

0 comments on commit 91c16f1

Please sign in to comment.