From: Krzysztof Parzyszek Date: Fri, 10 Mar 2017 22:42:17 +0000 (+0000) Subject: [RDF] Implement Liveness::getNearestAliasedRef(Reg, Inst) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=590c4ddc3fac086bc166c40ed9de625b1ad6584f;p=llvm [RDF] Implement Liveness::getNearestAliasedRef(Reg, Inst) This function will find the closest ref node aliased to Reg that is in an instruction preceding Inst. This could be used to identify the hypothetical reaching def of Reg, if Reg was a member of Inst. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297524 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/Hexagon/RDFGraph.h b/lib/Target/Hexagon/RDFGraph.h index bf4018ba7fc..d5faca4cd6f 100644 --- a/lib/Target/Hexagon/RDFGraph.h +++ b/lib/Target/Hexagon/RDFGraph.h @@ -761,6 +761,10 @@ namespace rdf { NodeList getRelatedRefs(NodeAddr IA, NodeAddr RA) const; + NodeAddr findBlock(MachineBasicBlock *BB) const { + return BlockNodes.at(BB); + } + void unlinkUse(NodeAddr UA, bool RemoveFromOwner) { unlinkUseDF(UA); if (RemoveFromOwner) @@ -860,10 +864,6 @@ namespace rdf { IA.Addr->removeMember(RA, *this); } - NodeAddr findBlock(MachineBasicBlock *BB) { - return BlockNodes[BB]; - } - MachineFunction &MF; const TargetInstrInfo &TII; const TargetRegisterInfo &TRI; diff --git a/lib/Target/Hexagon/RDFLiveness.cpp b/lib/Target/Hexagon/RDFLiveness.cpp index 46537d55be3..25a4c5f7058 100644 --- a/lib/Target/Hexagon/RDFLiveness.cpp +++ b/lib/Target/Hexagon/RDFLiveness.cpp @@ -304,6 +304,65 @@ Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr RefA, 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 Liveness::getNearestAliasedRef(RegisterRef RefRR, + NodeAddr IA) { + NodeAddr 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 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 I : make_range(B, E)) { + NodeList Refs = I.Addr->members(DFG); + NodeAddr 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 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(); + 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(); +} + NodeSet Liveness::getAllReachedUses(RegisterRef RefRR, NodeAddr DefA, const RegisterAggr &DefRRs) { diff --git a/lib/Target/Hexagon/RDFLiveness.h b/lib/Target/Hexagon/RDFLiveness.h index edb9e198fb8..6f2615b7c4f 100644 --- a/lib/Target/Hexagon/RDFLiveness.h +++ b/lib/Target/Hexagon/RDFLiveness.h @@ -71,6 +71,9 @@ namespace rdf { std::pair getAllReachingDefsRec(RegisterRef RefRR, NodeAddr RefA, NodeSet &Visited, const NodeSet &Defs); + NodeAddr getNearestAliasedRef(RegisterRef RefRR, + NodeAddr IA); + LiveMapType &getLiveMap() { return LiveMap; } const LiveMapType &getLiveMap() const { return LiveMap; } const RefMap &getRealUses(NodeId P) const {