diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/RDFLiveness.cpp')
-rw-r--r-- | llvm/lib/Target/Hexagon/RDFLiveness.cpp | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.cpp b/llvm/lib/Target/Hexagon/RDFLiveness.cpp index 48de9a6dbea..7e1c39df9b8 100644 --- a/llvm/lib/Target/Hexagon/RDFLiveness.cpp +++ b/llvm/lib/Target/Hexagon/RDFLiveness.cpp @@ -86,9 +86,18 @@ namespace rdf { NodeList Liveness::getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA, bool FullChain, const RegisterSet &DefRRs) { + NodeList RDefs; // Return value. SetVector<NodeId> DefQ; SetVector<NodeId> Owners; + // Dead defs will be treated as if they were live, since they are actually + // on the data-flow path. They cannot be ignored because even though they + // do not generate meaningful values, they still modify registers. + + // If the reference is undefined, there is nothing to do. + if (RefA.Addr->getFlags() & NodeAttrs::Undef) + return RDefs; + // The initial queue should not have reaching defs for shadows. The // whole point of a shadow is that it will have a reaching def that // is not aliased to the reaching defs of the related shadows. @@ -186,7 +195,6 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR, // covered if we added A first, and A would be covered // if we added B first. - NodeList RDefs; RegisterSet RRs = DefRRs; auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool { @@ -223,6 +231,11 @@ NodeList Liveness::getAllReachingDefs(RegisterRef RefRR, } } + auto DeadP = [](const NodeAddr<DefNode*> DA) -> bool { + return DA.Addr->getFlags() & NodeAttrs::Dead; + }; + RDefs.resize(std::distance(RDefs.begin(), remove_if(RDefs, DeadP))); + return RDefs; } @@ -285,7 +298,9 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR, return Uses; // Add all directly reached uses. - NodeId U = DefA.Addr->getReachedUse(); + // If the def is dead, it does not provide a value for any use. + bool IsDead = DefA.Addr->getFlags() & NodeAttrs::Dead; + NodeId U = !IsDead ? DefA.Addr->getReachedUse() : 0; while (U != 0) { auto UA = DFG.addr<UseNode*>(U); if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) { @@ -296,7 +311,7 @@ NodeSet Liveness::getAllReachedUses(RegisterRef RefRR, U = UA.Addr->getSibling(); } - // Traverse all reached defs. + // Traverse all reached defs. This time dead defs cannot be ignored. for (NodeId D = DefA.Addr->getReachedDef(), NextD; D != 0; D = NextD) { auto DA = DFG.addr<DefNode*>(D); NextD = DA.Addr->getSibling(); @@ -360,8 +375,10 @@ void Liveness::computePhiInfo() { // are actually reached by the phi defs. for (unsigned i = 0; i < DefQ.size(); ++i) { NodeAddr<DefNode*> DA = DFG.addr<DefNode*>(DefQ[i]); - // Visit all reached uses. - NodeId UN = DA.Addr->getReachedUse(); + // Visit all reached uses. Phi defs should not really have the "dead" + // flag set, but check it anyway for consistency. + bool IsDead = DA.Addr->getFlags() & NodeAttrs::Dead; + NodeId UN = !IsDead ? DA.Addr->getReachedUse() : 0; while (UN != 0) { NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN); uint16_t F = A.Addr->getFlags(); @@ -409,6 +426,8 @@ void Liveness::computePhiInfo() { NodeSet &Uses = UI->second; for (auto I = Uses.begin(), E = Uses.end(); I != E; ) { auto UA = DFG.addr<UseNode*>(*I); + // Undef flag is checked above. + assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0); NodeList RDs = getAllReachingDefs(UI->first, UA); if (any_of(RDs, InPhiDefs)) ++I; |