summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp')
-rw-r--r--contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp319
1 files changed, 202 insertions, 117 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp b/contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp
index e74c4bf..83e8968 100644
--- a/contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp
+++ b/contrib/llvm/lib/Target/Hexagon/RDFLiveness.cpp
@@ -23,19 +23,23 @@
// and Embedded Architectures and Compilers", 8 (4),
// <10.1145/2086696.2086706>. <hal-00647369>
//
-#include "RDFGraph.h"
#include "RDFLiveness.h"
+#include "RDFGraph.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominanceFrontier.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
using namespace rdf;
+static cl::opt<unsigned> MaxRecNest("rdf-liveness-max-rec", cl::init(25),
+ cl::Hidden, cl::desc("Maximum recursion level"));
+
namespace llvm {
namespace rdf {
template<>
@@ -85,7 +89,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 +110,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
@@ -119,7 +129,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
// Stop at the covering/overwriting def of the initial register reference.
RegisterRef RR = TA.Addr->getRegRef(DFG);
if (!DFG.IsPreservingDef(TA))
- if (RegisterAggr::isCoverOf(RR, RefRR, TRI))
+ if (RegisterAggr::isCoverOf(RR, RefRR, PRI))
continue;
// Get the next level of reaching defs. This will include multiple
// reaching defs for shadows.
@@ -134,7 +144,7 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
for (NodeId N : DefQ) {
auto TA = DFG.addr<DefNode*>(N);
bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
- if (!IsPhi && !DFG.alias(RefRR, TA.Addr->getRegRef(DFG)))
+ if (!IsPhi && !PRI.alias(RefRR, TA.Addr->getRegRef(DFG)))
continue;
Defs.insert(TA.Id);
Owners.insert(TA.Addr->getOwner(DFG).Id);
@@ -241,20 +251,30 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
}
-NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR,
- NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) {
+std::pair<NodeSet,bool>
+Liveness::getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
+ NodeSet &Visited, const NodeSet &Defs) {
+ return getAllReachingDefsRecImpl(RefRR, RefA, Visited, Defs, 0, MaxRecNest);
+}
+
+
+std::pair<NodeSet,bool>
+Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
+ NodeSet &Visited, const NodeSet &Defs, unsigned Nest, unsigned MaxNest) {
+ if (Nest > MaxNest)
+ return { NodeSet(), false };
// Collect all defined registers. Do not consider phis to be defining
// anything, only collect "real" definitions.
- RegisterAggr DefRRs(TRI);
+ RegisterAggr DefRRs(PRI);
for (NodeId D : Defs) {
const auto DA = DFG.addr<const DefNode*>(D);
if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef))
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;
+ return { Defs, true };
// Make a copy of the preexisting definitions and add the newly found ones.
NodeSet TmpDefs = Defs;
@@ -273,12 +293,74 @@ NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR,
Visited.insert(PA.Id);
// Go over all phi uses and get the reaching defs for each use.
for (auto U : PA.Addr->members_if(DFG.IsRef<NodeAttrs::Use>, DFG)) {
- const auto &T = getAllReachingDefsRec(RefRR, U, Visited, TmpDefs);
- Result.insert(T.begin(), T.end());
+ const auto &T = getAllReachingDefsRecImpl(RefRR, U, Visited, TmpDefs,
+ Nest+1, MaxNest);
+ if (!T.second)
+ return { T.first, false };
+ Result.insert(T.first.begin(), T.first.end());
}
}
- return Result;
+ return { Result, true };
+}
+
+/// Find the nearest ref node aliased to RefRR, going upwards in the data
+/// flow, starting from the instruction immediately preceding Inst.
+NodeAddr<RefNode*> Liveness::getNearestAliasedRef(RegisterRef RefRR,
+ NodeAddr<InstrNode*> IA) {
+ NodeAddr<BlockNode*> BA = IA.Addr->getOwner(DFG);
+ NodeList Ins = BA.Addr->members(DFG);
+ NodeId FindId = IA.Id;
+ auto E = Ins.rend();
+ auto B = std::find_if(Ins.rbegin(), E,
+ [FindId] (const NodeAddr<InstrNode*> T) {
+ return T.Id == FindId;
+ });
+ // Do not scan IA (which is what B would point to).
+ if (B != E)
+ ++B;
+
+ do {
+ // Process the range of instructions from B to E.
+ for (NodeAddr<InstrNode*> I : make_range(B, E)) {
+ NodeList Refs = I.Addr->members(DFG);
+ NodeAddr<RefNode*> Clob, Use;
+ // Scan all the refs in I aliased to RefRR, and return the one that
+ // is the closest to the output of I, i.e. def > clobber > use.
+ for (NodeAddr<RefNode*> R : Refs) {
+ if (!PRI.alias(R.Addr->getRegRef(DFG), RefRR))
+ continue;
+ if (DFG.IsDef(R)) {
+ // If it's a non-clobbering def, just return it.
+ if (!(R.Addr->getFlags() & NodeAttrs::Clobbering))
+ return R;
+ Clob = R;
+ } else {
+ Use = R;
+ }
+ }
+ if (Clob.Id != 0)
+ return Clob;
+ if (Use.Id != 0)
+ return Use;
+ }
+
+ // Go up to the immediate dominator, if any.
+ MachineBasicBlock *BB = BA.Addr->getCode();
+ BA = NodeAddr<BlockNode*>();
+ if (MachineDomTreeNode *N = MDT.getNode(BB)) {
+ if ((N = N->getIDom()))
+ BA = DFG.findBlock(N->getBlock());
+ }
+ if (!BA.Id)
+ break;
+
+ Ins = BA.Addr->members(DFG);
+ B = Ins.rbegin();
+ E = Ins.rend();
+ } while (true);
+
+ return NodeAddr<RefNode*>();
}
@@ -299,7 +381,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
auto UA = DFG.addr<UseNode*>(U);
if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
RegisterRef UR = UA.Addr->getRegRef(DFG);
- if (DFG.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
+ if (PRI.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
Uses.insert(U);
}
U = UA.Addr->getSibling();
@@ -312,7 +394,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
RegisterRef DR = DA.Addr->getRegRef(DFG);
// If this def is already covered, it cannot reach anything new.
// Similarly, skip it if it is not aliased to the interesting register.
- if (DefRRs.hasCoverOf(DR) || !DFG.alias(RefRR, DR))
+ if (DefRRs.hasCoverOf(DR) || !PRI.alias(RefRR, DR))
continue;
NodeSet T;
if (DFG.IsPreservingDef(DA)) {
@@ -343,6 +425,7 @@ void Liveness::computePhiInfo() {
// phi use -> (map: reaching phi -> set of registers defined in between)
std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
std::vector<NodeId> PhiUQ; // Work list of phis for upward propagation.
+ std::map<NodeId,RegisterAggr> PhiDRs; // Phi -> registers defined by it.
// Go over all phis.
for (NodeAddr<PhiNode*> PhiA : Phis) {
@@ -355,12 +438,15 @@ void Liveness::computePhiInfo() {
// For each def, add to the queue all reached (non-phi) defs.
SetVector<NodeId> DefQ;
NodeSet PhiDefs;
+ RegisterAggr DRs(PRI);
for (NodeAddr<RefNode*> R : PhiRefs) {
if (!DFG.IsRef<NodeAttrs::Def>(R))
continue;
+ DRs.insert(R.Addr->getRegRef(DFG));
DefQ.insert(R.Id);
PhiDefs.insert(R.Id);
}
+ PhiDRs.insert(std::make_pair(PhiA.Id, DRs));
// Collect the super-set of all possible reached uses. This set will
// contain all uses reached from this phi, either directly from the
@@ -377,9 +463,9 @@ 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 = DFG.normalizeRef(getRestrictedRegRef(A));
+ RegisterRef R = PRI.normalize(A.Addr->getRegRef(DFG));
RealUses[R.Reg].insert({A.Id,R.Mask});
- }
+ }
UN = A.Addr->getSibling();
}
// Visit all reached defs, and add them to the queue. These defs may
@@ -411,30 +497,33 @@ void Liveness::computePhiInfo() {
// = R1:0 u6 Not reached by d1 (covered collectively
// by d3 and d5), but following reached
// defs and uses from d1 will lead here.
- auto InPhiDefs = [&PhiDefs] (NodeAddr<DefNode*> DA) -> bool {
- return PhiDefs.count(DA.Id);
- };
for (auto UI = RealUses.begin(), UE = RealUses.end(); UI != UE; ) {
// For each reached register UI->first, there is a set UI->second, of
// uses of it. For each such use, check if it is reached by this phi,
// i.e. check if the set of its reaching uses intersects the set of
// this phi's defs.
- NodeRefSet &Uses = UI->second;
- for (auto I = Uses.begin(), E = Uses.end(); I != E; ) {
- auto UA = DFG.addr<UseNode*>(I->first);
+ NodeRefSet Uses = UI->second;
+ UI->second.clear();
+ for (std::pair<NodeId,LaneBitmask> I : Uses) {
+ auto UA = DFG.addr<UseNode*>(I.first);
// Undef flag is checked above.
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);
+ RegisterRef R(UI->first, I.second);
+ // Calculate the exposed part of the reached use.
+ RegisterAggr Covered(PRI);
+ for (NodeAddr<DefNode*> DA : getAllReachingDefs(R, UA)) {
+ if (PhiDefs.count(DA.Id))
+ break;
+ Covered.insert(DA.Addr->getRegRef(DFG));
+ }
+ if (RegisterRef RC = Covered.clearIn(R)) {
+ // We are updating the map for register UI->first, so we need
+ // to map RC to be expressed in terms of that register.
+ RegisterRef S = PRI.mapTo(RC, UI->first);
+ UI->second.insert({I.first, S.Mask});
+ }
}
- if (Uses.empty())
- UI = RealUses.erase(UI);
- else
- ++UI;
+ UI = UI->second.empty() ? RealUses.erase(UI) : std::next(UI);
}
// If this phi reaches some "real" uses, add it to the queue for upward
@@ -452,32 +541,29 @@ void Liveness::computePhiInfo() {
for (auto I : PhiRefs) {
if (!DFG.IsRef<NodeAttrs::Use>(I) || SeenUses.count(I.Id))
continue;
- NodeAddr<UseNode*> UA = I;
-
- // 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.
-
- for (NodeAddr<UseNode*> VA : DFG.getRelatedRefs(PhiA, UA)) {
- SeenUses.insert(VA.Id);
- RegisterAggr DefRRs(TRI);
- 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));
+ NodeAddr<PhiUseNode*> PUA = I;
+ if (PUA.Addr->getReachingDef() == 0)
+ continue;
+
+ RegisterRef UR = PUA.Addr->getRegRef(DFG);
+ NodeList Ds = getAllReachingDefs(UR, PUA, true, false, NoRegs);
+ RegisterAggr DefRRs(PRI);
+
+ 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 +608,7 @@ void Liveness::computePhiInfo() {
for (NodeAddr<UseNode*> UA : PUs) {
std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
- RegisterRef UR = DFG.normalizeRef(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;
@@ -540,14 +626,19 @@ void Liveness::computePhiInfo() {
// then add (R-MidDefs,U) to RealUseMap[P]
//
for (const std::pair<RegisterId,NodeRefSet> &T : RUM) {
- RegisterRef R = DFG.restrictRef(RegisterRef(T.first), UR);
- if (!R)
+ RegisterRef R(T.first);
+ // The current phi (PA) could be a phi for a regmask. It could
+ // reach a whole variety of uses that are not related to the
+ // specific upward phi (P.first).
+ const RegisterAggr &DRs = PhiDRs.at(P.first);
+ if (!DRs.hasAliasOf(R))
continue;
+ R = PRI.mapTo(DRs.intersectWith(R), T.first);
for (std::pair<NodeId,LaneBitmask> V : T.second) {
- RegisterRef S = DFG.restrictRef(RegisterRef(R.Reg, V.second), R);
- if (!S)
+ LaneBitmask M = R.Mask & V.second;
+ if (M.none())
continue;
- if (RegisterRef SS = MidDefs.clearIn(S)) {
+ if (RegisterRef SS = MidDefs.clearIn(RegisterRef(R.Reg, M))) {
NodeRefSet &RS = RealUseMap[P.first][SS.Reg];
Changed |= RS.insert({V.first,SS.Mask}).second;
}
@@ -645,30 +736,48 @@ 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 = DFG.normalizeRef(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) {
+ // Calculate the mask corresponding to the visited def.
+ RegisterAggr TA(PRI);
+ TA.insert(D.Addr->getRegRef(DFG)).intersect(S);
+ LaneBitmask TM = TA.makeRegRef().Mask;
+ LOX[S.Reg].insert({D.Id, TM});
+ }
+ }
}
+
+ for (NodeAddr<PhiUseNode*> T : DFG.getRelatedRefs(PA, PUA))
+ SeenUses.insert(T.Id);
} // for U : phi uses
} // for P : Phis
} // for B : Blocks
@@ -684,9 +793,7 @@ void Liveness::computeLiveIns() {
traverse(&MF.front(), LiveIn);
// Add function live-ins to the live-in set of the function entry block.
- auto &EntryIn = LiveMap[&MF.front()];
- for (auto I = MRI.livein_begin(), E = MRI.livein_end(); I != E; ++I)
- EntryIn.insert(RegisterRef(I->first));
+ LiveMap[&MF.front()].insert(DFG.getLiveIns());
if (Trace) {
// Dump the liveness map
@@ -702,19 +809,9 @@ void Liveness::computeLiveIns() {
//dbgs() << "\tcomp = " << Print<RegisterAggr>(LiveMap[&B], DFG) << '\n';
LV.clear();
- for (std::pair<RegisterId,LaneBitmask> P : LiveMap[&B]) {
- MCSubRegIndexIterator S(P.first, &TRI);
- if (!S.isValid()) {
- LV.push_back(RegisterRef(P.first));
- continue;
- }
- do {
- LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
- if ((M & P.second).any())
- LV.push_back(RegisterRef(S.getSubReg()));
- ++S;
- } while (S.isValid());
- }
+ const RegisterAggr &LG = LiveMap[&B];
+ for (auto I = LG.rr_begin(), E = LG.rr_end(); I != E; ++I)
+ LV.push_back(*I);
std::sort(LV.begin(), LV.end());
dbgs() << "\tcomp = {";
for (auto I : LV)
@@ -735,9 +832,10 @@ void Liveness::resetLiveIns() {
for (auto I : T)
B.removeLiveIn(I);
// Add the newly computed live-ins.
- auto &LiveIns = LiveMap[&B];
- for (auto I : LiveIns) {
- B.addLiveIn({MCPhysReg(I.first), I.second});
+ const RegisterAggr &LiveIns = LiveMap[&B];
+ for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
+ RegisterRef R = *I;
+ B.addLiveIn({MCPhysReg(R.Reg), R.Mask});
}
}
}
@@ -791,7 +889,7 @@ void Liveness::resetKills(MachineBasicBlock *B) {
Live.reset(*SR);
}
for (auto &Op : MI->operands()) {
- if (!Op.isReg() || !Op.isUse())
+ if (!Op.isReg() || !Op.isUse() || Op.isUndef())
continue;
unsigned R = Op.getReg();
if (!TargetRegisterInfo::isPhysicalRegister(R))
@@ -803,9 +901,8 @@ void Liveness::resetKills(MachineBasicBlock *B) {
IsLive = true;
break;
}
- if (IsLive)
- continue;
- Op.setIsKill(true);
+ if (!IsLive)
+ Op.setIsKill(true);
for (MCSubRegIterator SR(R, &TRI, true); SR.isValid(); ++SR)
Live.set(*SR);
}
@@ -813,17 +910,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 {
@@ -921,7 +1007,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
// propagated upwards. This only applies to non-preserving defs,
// and to the parts of the register actually covered by those defs.
// (Note that phi defs should always be preserving.)
- RegisterAggr RRs(TRI);
+ RegisterAggr RRs(PRI);
LRef.Mask = OR.second;
if (!DFG.IsPreservingDef(DA)) {
@@ -949,10 +1035,9 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
// registers are not covering LRef. The first def from the
// upward chain will be live.
// Subtract all accumulated defs (RRs) from LRef.
- RegisterAggr L(TRI);
- L.insert(LRef).clear(RRs);
- assert(!L.empty());
- NewDefs.insert({TA.Id,L.begin()->second});
+ RegisterRef T = RRs.clearIn(LRef);
+ assert(T);
+ NewDefs.insert({TA.Id,T.Mask});
break;
}
@@ -983,7 +1068,7 @@ void Liveness::traverse(MachineBasicBlock *B, RefMap &LiveIn) {
for (NodeAddr<UseNode*> UA : IA.Addr->members_if(DFG.IsUse, DFG)) {
if (UA.Addr->getFlags() & NodeAttrs::Undef)
continue;
- RegisterRef RR = DFG.normalizeRef(UA.Addr->getRegRef(DFG));
+ RegisterRef RR = PRI.normalize(UA.Addr->getRegRef(DFG));
for (NodeAddr<DefNode*> D : getAllReachingDefs(UA))
if (getBlockWithRef(D.Id) != B)
LiveIn[RR.Reg].insert({D.Id,RR.Mask});
OpenPOWER on IntegriCloud