1,201 changes: 592 additions & 609 deletions llvm/include/llvm/CodeGen/RDFGraph.h

Large diffs are not rendered by default.

213 changes: 102 additions & 111 deletions llvm/include/llvm/CodeGen/RDFLiveness.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,117 +56,108 @@ template <> struct hash<llvm::rdf::detail::NodeRef> {
namespace llvm {
namespace rdf {

struct Liveness {
public:
// This is really a std::map, except that it provides a non-trivial
// default constructor to the element accessed via [].
struct LiveMapType {
LiveMapType(const PhysicalRegisterInfo &pri) : Empty(pri) {}

RegisterAggr &operator[] (MachineBasicBlock *B) {
return Map.emplace(B, Empty).first->second;
}

private:
RegisterAggr Empty;
std::map<MachineBasicBlock*,RegisterAggr> Map;
};

using NodeRef = detail::NodeRef;
using NodeRefSet = std::unordered_set<NodeRef>;
using RefMap = std::unordered_map<RegisterId, NodeRefSet>;

Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
: DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
MDF(g.getDF()), LiveMap(g.getPRI()), Empty(), NoRegs(g.getPRI()) {}

NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
bool TopShadows, bool FullChain, const RegisterAggr &DefRRs);

NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false,
false, NoRegs);
}

NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
return getAllReachingDefs(RefRR, RefA, false, false, NoRegs);
}

NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
const RegisterAggr &DefRRs);

NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
return getAllReachedUses(RefRR, DefA, NoRegs);
}

std::pair<NodeSet,bool> getAllReachingDefsRec(RegisterRef RefRR,
NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs);

NodeAddr<RefNode*> getNearestAliasedRef(RegisterRef RefRR,
NodeAddr<InstrNode*> IA);

LiveMapType &getLiveMap() { return LiveMap; }
const LiveMapType &getLiveMap() const { return LiveMap; }

const RefMap &getRealUses(NodeId P) const {
auto F = RealUseMap.find(P);
return F == RealUseMap.end() ? Empty : F->second;
}

void computePhiInfo();
void computeLiveIns();
void resetLiveIns();
void resetKills();
void resetKills(MachineBasicBlock *B);

void trace(bool T) { Trace = T; }

private:
const DataFlowGraph &DFG;
const TargetRegisterInfo &TRI;
const PhysicalRegisterInfo &PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
LiveMapType LiveMap;
const RefMap Empty;
const RegisterAggr NoRegs;
bool Trace = false;

// Cache of mapping from node ids (for RefNodes) to the containing
// basic blocks. Not computing it each time for each node reduces
// the liveness calculation time by a large fraction.
DenseMap<NodeId, MachineBasicBlock *> NBMap;

// Phi information:
//
// RealUseMap
// map: NodeId -> (map: RegisterId -> NodeRefSet)
// phi id -> (map: register -> set of reached non-phi uses)
DenseMap<NodeId, RefMap> RealUseMap;

// Inverse iterated dominance frontier.
std::map<MachineBasicBlock*,std::set<MachineBasicBlock*>> IIDF;

// Live on entry.
std::map<MachineBasicBlock*,RefMap> PhiLON;

// Phi uses are considered to be located at the end of the block that
// they are associated with. The reaching def of a phi use dominates the
// block that the use corresponds to, but not the block that contains
// the phi itself. To include these uses in the liveness propagation (up
// the dominator tree), create a map: block -> set of uses live on exit.
std::map<MachineBasicBlock*,RefMap> PhiLOX;

MachineBasicBlock *getBlockWithRef(NodeId RN) const;
void traverse(MachineBasicBlock *B, RefMap &LiveIn);
void emptify(RefMap &M);

std::pair<NodeSet,bool> getAllReachingDefsRecImpl(RegisterRef RefRR,
NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs,
unsigned Nest, unsigned MaxNest);
};

raw_ostream &operator<<(raw_ostream &OS, const Print<Liveness::RefMap> &P);
struct Liveness {
public:
using LiveMapType = RegisterAggrMap<MachineBasicBlock *>;
using NodeRef = detail::NodeRef;
using NodeRefSet = std::unordered_set<NodeRef>;
using RefMap = std::unordered_map<RegisterId, NodeRefSet>;

Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
: DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
MDF(g.getDF()), LiveMap(g.getPRI()), Empty(), NoRegs(g.getPRI()) {}

NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode *> RefA,
bool TopShadows, bool FullChain,
const RegisterAggr &DefRRs);

NodeList getAllReachingDefs(NodeAddr<RefNode *> RefA) {
return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false, false,
NoRegs);
}

NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode *> RefA) {
return getAllReachingDefs(RefRR, RefA, false, false, NoRegs);
}

NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode *> DefA,
const RegisterAggr &DefRRs);

NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode *> DefA) {
return getAllReachedUses(RefRR, DefA, NoRegs);
}

std::pair<NodeSet, bool> getAllReachingDefsRec(RegisterRef RefRR,
NodeAddr<RefNode *> RefA,
NodeSet &Visited,
const NodeSet &Defs);

NodeAddr<RefNode *> getNearestAliasedRef(RegisterRef RefRR,
NodeAddr<InstrNode *> IA);

LiveMapType &getLiveMap() { return LiveMap; }
const LiveMapType &getLiveMap() const { return LiveMap; }

const RefMap &getRealUses(NodeId P) const {
auto F = RealUseMap.find(P);
return F == RealUseMap.end() ? Empty : F->second;
}

void computePhiInfo();
void computeLiveIns();
void resetLiveIns();
void resetKills();
void resetKills(MachineBasicBlock *B);

void trace(bool T) { Trace = T; }

private:
const DataFlowGraph &DFG;
const TargetRegisterInfo &TRI;
const PhysicalRegisterInfo &PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
LiveMapType LiveMap;
const RefMap Empty;
const RegisterAggr NoRegs;
bool Trace = false;

// Cache of mapping from node ids (for RefNodes) to the containing
// basic blocks. Not computing it each time for each node reduces
// the liveness calculation time by a large fraction.
DenseMap<NodeId, MachineBasicBlock *> NBMap;

// Phi information:
//
// RealUseMap
// map: NodeId -> (map: RegisterId -> NodeRefSet)
// phi id -> (map: register -> set of reached non-phi uses)
DenseMap<NodeId, RefMap> RealUseMap;

// Inverse iterated dominance frontier.
std::map<MachineBasicBlock *, std::set<MachineBasicBlock *>> IIDF;

// Live on entry.
std::map<MachineBasicBlock *, RefMap> PhiLON;

// Phi uses are considered to be located at the end of the block that
// they are associated with. The reaching def of a phi use dominates the
// block that the use corresponds to, but not the block that contains
// the phi itself. To include these uses in the liveness propagation (up
// the dominator tree), create a map: block -> set of uses live on exit.
std::map<MachineBasicBlock *, RefMap> PhiLOX;

MachineBasicBlock *getBlockWithRef(NodeId RN) const;
void traverse(MachineBasicBlock *B, RefMap &LiveIn);
void emptify(RefMap &M);

std::pair<NodeSet, bool>
getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode *> RefA,
NodeSet &Visited, const NodeSet &Defs,
unsigned Nest, unsigned MaxNest);
};

raw_ostream &operator<<(raw_ostream &OS, const Print<Liveness::RefMap> &P);

} // end namespace rdf

Expand Down
417 changes: 217 additions & 200 deletions llvm/include/llvm/CodeGen/RDFRegisters.h

Large diffs are not rendered by default.

729 changes: 343 additions & 386 deletions llvm/lib/CodeGen/RDFGraph.cpp

Large diffs are not rendered by default.

288 changes: 147 additions & 141 deletions llvm/lib/CodeGen/RDFLiveness.cpp

Large diffs are not rendered by default.

33 changes: 16 additions & 17 deletions llvm/lib/CodeGen/RDFRegisters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using namespace llvm;
using namespace rdf;

PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
const MachineFunction &mf)
const MachineFunction &mf)
: TRI(tri) {
RegInfos.resize(TRI.getNumRegs());

Expand Down Expand Up @@ -57,7 +57,7 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
UnitInfos[U].Reg = F;
} else {
for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
std::pair<uint32_t,LaneBitmask> P = *I;
std::pair<uint32_t, LaneBitmask> P = *I;
UnitInfo &UI = UnitInfos[P.first];
UI.Reg = F;
if (P.second.any()) {
Expand All @@ -80,7 +80,7 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
if (Op.isRegMask())
RegMasks.insert(Op.getRegMask());

MaskInfos.resize(RegMasks.size()+1);
MaskInfos.resize(RegMasks.size() + 1);
for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
BitVector PU(TRI.getNumRegUnits());
const uint32_t *MB = RegMasks.get(M);
Expand Down Expand Up @@ -111,7 +111,7 @@ std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
// XXX SLOW
const uint32_t *MB = getRegMaskBits(Reg);
for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
if (MB[i/32] & (1u << (i%32)))
if (MB[i / 32] & (1u << (i % 32)))
continue;
AS.insert(i);
}
Expand Down Expand Up @@ -142,13 +142,13 @@ bool PhysicalRegisterInfo::aliasRR(RegisterRef RA, RegisterRef RB) const {
// Reg units are returned in the numerical order.
while (UMA.isValid() && UMB.isValid()) {
// Skip units that are masked off in RA.
std::pair<RegisterId,LaneBitmask> PA = *UMA;
std::pair<RegisterId, LaneBitmask> PA = *UMA;
if (PA.second.any() && (PA.second & RA.Mask).none()) {
++UMA;
continue;
}
// Skip units that are masked off in RB.
std::pair<RegisterId,LaneBitmask> PB = *UMB;
std::pair<RegisterId, LaneBitmask> PB = *UMB;
if (PB.second.any() && (PB.second & RB.Mask).none()) {
++UMB;
continue;
Expand All @@ -167,7 +167,7 @@ bool PhysicalRegisterInfo::aliasRR(RegisterRef RA, RegisterRef RB) const {
bool PhysicalRegisterInfo::aliasRM(RegisterRef RR, RegisterRef RM) const {
assert(Register::isPhysicalRegister(RR.Reg) && isRegMaskId(RM.Reg));
const uint32_t *MB = getRegMaskBits(RM.Reg);
bool Preserved = MB[RR.Reg/32] & (1u << (RR.Reg%32));
bool Preserved = MB[RR.Reg / 32] & (1u << (RR.Reg % 32));
// If the lane mask information is "full", e.g. when the given lane mask
// is a superset of the lane mask from the register class, check the regmask
// bit directly.
Expand All @@ -188,7 +188,7 @@ bool PhysicalRegisterInfo::aliasRM(RegisterRef RR, RegisterRef RM) const {
if ((SM & RR.Mask).none())
continue;
unsigned SR = SI.getSubReg();
if (!(MB[SR/32] & (1u << (SR%32))))
if (!(MB[SR / 32] & (1u << (SR % 32))))
continue;
// The subregister SR is preserved.
M &= ~SM;
Expand All @@ -205,7 +205,7 @@ bool PhysicalRegisterInfo::aliasMM(RegisterRef RM, RegisterRef RN) const {
const uint32_t *BM = getRegMaskBits(RM.Reg);
const uint32_t *BN = getRegMaskBits(RN.Reg);

for (unsigned w = 0, nw = NumRegs/32; w != nw; ++w) {
for (unsigned w = 0, nw = NumRegs / 32; w != nw; ++w) {
// Intersect the negations of both words. Disregard reg=0,
// i.e. 0th bit in the 0th word.
uint32_t C = ~BM[w] & ~BN[w];
Expand Down Expand Up @@ -234,8 +234,8 @@ RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) {
const RegInfo &RI = RegInfos[R];
LaneBitmask RCM = RI.RegClass ? RI.RegClass->LaneMask
: LaneBitmask::getAll();
LaneBitmask RCM =
RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll();
LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
return RegisterRef(R, M & RCM);
}
Expand All @@ -247,7 +247,7 @@ bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
return Units.anyCommon(PRI.getMaskUnits(RR.Reg));

for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
std::pair<uint32_t,LaneBitmask> P = *U;
std::pair<uint32_t, LaneBitmask> P = *U;
if (P.second.none() || (P.second & RR.Mask).any())
if (Units.test(P.first))
return true;
Expand All @@ -262,7 +262,7 @@ bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
}

for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
std::pair<uint32_t,LaneBitmask> P = *U;
std::pair<uint32_t, LaneBitmask> P = *U;
if (P.second.none() || (P.second & RR.Mask).any())
if (!Units.test(P.first))
return false;
Expand All @@ -277,7 +277,7 @@ RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
}

for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
std::pair<uint32_t,LaneBitmask> P = *U;
std::pair<uint32_t, LaneBitmask> P = *U;
if (P.second.none() || (P.second & RR.Mask).any())
Units.set(P.first);
}
Expand Down Expand Up @@ -350,7 +350,7 @@ RegisterRef RegisterAggr::makeRegRef() const {

LaneBitmask M;
for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
std::pair<uint32_t,LaneBitmask> P = *I;
std::pair<uint32_t, LaneBitmask> P = *I;
if (Units.test(P.first))
M |= P.second.none() ? LaneBitmask::getAll() : P.second;
}
Expand All @@ -364,8 +364,7 @@ void RegisterAggr::print(raw_ostream &OS) const {
OS << " }";
}

RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG,
bool End)
RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG, bool End)
: Owner(&RG) {
for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
RegisterRef R = RG.PRI.getRefForUnit(U);
Expand Down
6 changes: 4 additions & 2 deletions llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,8 +320,10 @@ bool HexagonRDFOpt::runOnMachineFunction(MachineFunction &MF) {
Changed |= DCE.run();

if (Changed) {
if (RDFDump)
dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n';
if (RDFDump) {
dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n'
<< PrintNode<FuncNode*>(G.getFunc(), G) << '\n';
}
Liveness LV(*MRI, G);
LV.trace(RDFDump);
LV.computeLiveIns();
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/Hexagon/newify-crash.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: llc -march=hexagon < %s | FileCheck %s
;
; Check that this testcase doesn't crash.
; CHECK: vadd
; CHECK: jump f0

target triple = "hexagon"

Expand Down