1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

[RDF] Aggregate shadow phi uses into one cluster when propagating live info

llvm-svn: 295366
This commit is contained in:
Krzysztof Parzyszek 2017-02-16 19:28:06 +00:00
parent 3a35241da1
commit ab89d5b8e5
2 changed files with 66 additions and 68 deletions

View File

@ -85,7 +85,8 @@ namespace rdf {
// the data-flow.
NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
NodeAddr<RefNode*> RefA, bool FullChain, const RegisterAggr &DefRRs) {
NodeAddr<RefNode*> RefA, bool TopShadows, bool FullChain,
const RegisterAggr &DefRRs) {
NodeList RDefs; // Return value.
SetVector<NodeId> DefQ;
SetVector<NodeId> Owners;
@ -105,6 +106,11 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
auto SNA = DFG.addr<RefNode*>(Start);
if (NodeId RD = SNA.Addr->getReachingDef())
DefQ.insert(RD);
if (TopShadows) {
for (auto S : DFG.getRelatedRefs(RefA.Addr->getOwner(DFG), RefA))
if (NodeId RD = NodeAddr<RefNode*>(S).Addr->getReachingDef())
DefQ.insert(RD);
}
// Collect all the reaching defs, going up until a phi node is encountered,
// or there are no more reaching defs. From this set, the actual set of
@ -252,7 +258,7 @@ NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR,
DefRRs.insert(DA.Addr->getRegRef(DFG));
}
NodeList RDs = getAllReachingDefs(RefRR, RefA, true, DefRRs);
NodeList RDs = getAllReachingDefs(RefRR, RefA, false, true, DefRRs);
if (RDs.empty())
return Defs;
@ -377,7 +383,7 @@ void Liveness::computePhiInfo() {
NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
uint16_t F = A.Addr->getFlags();
if ((F & (NodeAttrs::Undef | NodeAttrs::PhiRef)) == 0) {
RegisterRef R = PRI.normalize(getRestrictedRegRef(A));
RegisterRef R = PRI.normalize(A.Addr->getRegRef(DFG));
RealUses[R.Reg].insert({A.Id,R.Mask});
}
UN = A.Addr->getSibling();
@ -426,15 +432,11 @@ void Liveness::computePhiInfo() {
assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0);
RegisterRef R(UI->first, I->second);
NodeList RDs = getAllReachingDefs(R, UA);
if (any_of(RDs, InPhiDefs))
++I;
else
I = Uses.erase(I);
// If none of the reaching defs of R are from this phi, remove this
// use of R.
I = any_of(RDs, InPhiDefs) ? std::next(I) : Uses.erase(I);
}
if (Uses.empty())
UI = RealUses.erase(UI);
else
++UI;
UI = Uses.empty() ? RealUses.erase(UI) : std::next(UI);
}
// If this phi reaches some "real" uses, add it to the queue for upward
@ -452,32 +454,29 @@ void Liveness::computePhiInfo() {
for (auto I : PhiRefs) {
if (!DFG.IsRef<NodeAttrs::Use>(I) || SeenUses.count(I.Id))
continue;
NodeAddr<UseNode*> UA = I;
NodeAddr<PhiUseNode*> PUA = I;
if (PUA.Addr->getReachingDef() == 0)
continue;
// Given a phi use UA, traverse all related phi uses (including UA).
// The related phi uses may reach different phi nodes or may reach the
// same phi node. If multiple uses reach the same phi P, the intervening
// defs must be accumulated for all such uses. To group all such uses
// into one set, map their node ids to the first use id that reaches P.
std::map<NodeId,NodeId> FirstUse; // Phi reached up -> first phi use.
RegisterRef UR = PUA.Addr->getRegRef(DFG);
NodeList Ds = getAllReachingDefs(UR, PUA, true, false, NoRegs);
RegisterAggr DefRRs(PRI);
for (NodeAddr<UseNode*> VA : DFG.getRelatedRefs(PhiA, UA)) {
SeenUses.insert(VA.Id);
RegisterAggr DefRRs(PRI);
for (NodeAddr<DefNode*> DA : getAllReachingDefs(VA)) {
if (DA.Addr->getFlags() & NodeAttrs::PhiRef) {
NodeId RP = DA.Addr->getOwner(DFG).Id;
NodeId FU = FirstUse.insert({RP,VA.Id}).first->second;
std::map<NodeId,RegisterAggr> &M = PhiUp[FU];
auto F = M.find(RP);
if (F == M.end())
M.insert(std::make_pair(RP, DefRRs));
else
F->second.insert(DefRRs);
}
DefRRs.insert(DA.Addr->getRegRef(DFG));
for (NodeAddr<DefNode*> D : Ds) {
if (D.Addr->getFlags() & NodeAttrs::PhiRef) {
NodeId RP = D.Addr->getOwner(DFG).Id;
std::map<NodeId,RegisterAggr> &M = PhiUp[PUA.Id];
auto F = M.find(RP);
if (F == M.end())
M.insert(std::make_pair(RP, DefRRs));
else
F->second.insert(DefRRs);
}
DefRRs.insert(D.Addr->getRegRef(DFG));
}
for (NodeAddr<PhiUseNode*> T : DFG.getRelatedRefs(PhiA, PUA))
SeenUses.insert(T.Id);
}
}
@ -522,7 +521,7 @@ void Liveness::computePhiInfo() {
for (NodeAddr<UseNode*> UA : PUs) {
std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
RegisterRef UR = PRI.normalize(getRestrictedRegRef(UA));
RegisterRef UR = PRI.normalize(UA.Addr->getRegRef(DFG));
for (const std::pair<NodeId,RegisterAggr> &P : PUM) {
bool Changed = false;
const RegisterAggr &MidDefs = P.second;
@ -645,30 +644,43 @@ void Liveness::computeLiveIns() {
if (RUs.empty())
continue;
NodeSet SeenUses;
for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) {
if (!SeenUses.insert(U.Id).second)
continue;
NodeAddr<PhiUseNode*> PUA = U;
if (PUA.Addr->getReachingDef() == 0)
continue;
// Mark all reached "real" uses of P as live on exit in the
// predecessor.
// Remap all the RUs so that they have a correct reaching def.
// Each phi has some set (possibly empty) of reached "real" uses,
// that is, uses that are part of the compiled program. Such a use
// may be located in some farther block, but following a chain of
// reaching defs will eventually lead to this phi.
// Any chain of reaching defs may fork at a phi node, but there
// will be a path upwards that will lead to this phi. Now, this
// chain will need to fork at this phi, since some of the reached
// uses may have definitions joining in from multiple predecessors.
// For each reached "real" use, identify the set of reaching defs
// coming from each predecessor P, and add them to PhiLOX[P].
//
auto PrA = DFG.addr<BlockNode*>(PUA.Addr->getPredecessor());
RefMap &LOX = PhiLOX[PrA.Addr->getCode()];
RegisterRef UR = PRI.normalize(getRestrictedRegRef(PUA));
for (const std::pair<RegisterId,NodeRefSet> &T : RUs) {
// Check if T.first aliases UR?
LaneBitmask M;
for (std::pair<NodeId,LaneBitmask> P : T.second)
M |= P.second;
RegisterRef S = DFG.restrictRef(RegisterRef(T.first, M), UR);
if (!S)
continue;
for (NodeAddr<DefNode*> D : getAllReachingDefs(S, PUA))
LOX[S.Reg].insert({D.Id, S.Mask});
for (const std::pair<RegisterId,NodeRefSet> &RS : RUs) {
// We need to visit each individual use.
for (std::pair<NodeId,LaneBitmask> P : RS.second) {
// Create a register ref corresponding to the use, and find
// all reaching defs starting from the phi use, and treating
// all related shadows as a single use cluster.
RegisterRef S(RS.first, P.second);
NodeList Ds = getAllReachingDefs(S, PUA, true, false, NoRegs);
for (NodeAddr<DefNode*> D : Ds)
LOX[S.Reg].insert({D.Id, S.Mask});
}
}
for (NodeAddr<PhiUseNode*> T : DFG.getRelatedRefs(PA, PUA))
SeenUses.insert(T.Id);
} // for U : phi uses
} // for P : Phis
} // for B : Blocks
@ -810,17 +822,6 @@ void Liveness::resetKills(MachineBasicBlock *B) {
}
RegisterRef Liveness::getRestrictedRegRef(NodeAddr<RefNode*> RA) const {
assert(DFG.IsRef<NodeAttrs::Use>(RA));
if (RA.Addr->getFlags() & NodeAttrs::Shadow) {
NodeId RD = RA.Addr->getReachingDef();
assert(RD);
RA = DFG.addr<DefNode*>(RD);
}
return RA.Addr->getRegRef(DFG);
}
// Helper function to obtain the basic block containing the reaching def
// of the given use.
MachineBasicBlock *Liveness::getBlockWithRef(NodeId RN) const {

View File

@ -50,16 +50,17 @@ namespace rdf {
Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
: DFG(g), TRI(g.getTRI()), PRI(g.getPRI()), MDT(g.getDT()),
MDF(g.getDF()), MRI(mri), LiveMap(g.getPRI()), Empty(),
MDF(g.getDF()), LiveMap(g.getPRI()), Empty(),
NoRegs(g.getPRI()), Trace(false) {}
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
bool FullChain, const RegisterAggr &DefRRs);
bool TopShadows, bool FullChain, const RegisterAggr &DefRRs);
NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false, NoRegs);
return getAllReachingDefs(RefA.Addr->getRegRef(DFG), RefA, false,
false, NoRegs);
}
NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
return getAllReachingDefs(RefRR, RefA, false, NoRegs);
return getAllReachingDefs(RefRR, RefA, false, false, NoRegs);
}
NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
NodeSet &Visited, const NodeSet &Defs);
@ -90,7 +91,6 @@ namespace rdf {
const PhysicalRegisterInfo &PRI;
const MachineDominatorTree &MDT;
const MachineDominanceFrontier &MDF;
MachineRegisterInfo &MRI;
LiveMapType LiveMap;
const RefMap Empty;
const RegisterAggr NoRegs;
@ -122,9 +122,6 @@ namespace rdf {
// the dominator tree), create a map: block -> set of uses live on exit.
std::map<MachineBasicBlock*,RefMap> PhiLOX;
bool isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
RegisterRef RR) const;
RegisterRef getRestrictedRegRef(NodeAddr<RefNode*> RA) const;
MachineBasicBlock *getBlockWithRef(NodeId RN) const;
void traverse(MachineBasicBlock *B, RefMap &LiveIn);
void emptify(RefMap &M);