aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-03-10 22:42:17 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2017-03-10 22:42:17 +0000
commit0b8f184d12abfd7366389302ce29167bcee265cd (patch)
tree3a80f6d95864066291c469ac3d04baf5ed236191
parent128a10a41d881d94ace4fcc6fea503e9159ba150 (diff)
downloadllvm-0b8f184d12abfd7366389302ce29167bcee265cd.zip
llvm-0b8f184d12abfd7366389302ce29167bcee265cd.tar.gz
llvm-0b8f184d12abfd7366389302ce29167bcee265cd.tar.bz2
[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. llvm-svn: 297524
-rw-r--r--llvm/lib/Target/Hexagon/RDFGraph.h8
-rw-r--r--llvm/lib/Target/Hexagon/RDFLiveness.cpp59
-rw-r--r--llvm/lib/Target/Hexagon/RDFLiveness.h3
3 files changed, 66 insertions, 4 deletions
diff --git a/llvm/lib/Target/Hexagon/RDFGraph.h b/llvm/lib/Target/Hexagon/RDFGraph.h
index bf4018b..d5faca4 100644
--- a/llvm/lib/Target/Hexagon/RDFGraph.h
+++ b/llvm/lib/Target/Hexagon/RDFGraph.h
@@ -761,6 +761,10 @@ namespace rdf {
NodeList getRelatedRefs(NodeAddr<InstrNode*> IA,
NodeAddr<RefNode*> RA) const;
+ NodeAddr<BlockNode*> findBlock(MachineBasicBlock *BB) const {
+ return BlockNodes.at(BB);
+ }
+
void unlinkUse(NodeAddr<UseNode*> UA, bool RemoveFromOwner) {
unlinkUseDF(UA);
if (RemoveFromOwner)
@@ -860,10 +864,6 @@ namespace rdf {
IA.Addr->removeMember(RA, *this);
}
- NodeAddr<BlockNode*> findBlock(MachineBasicBlock *BB) {
- return BlockNodes[BB];
- }
-
MachineFunction &MF;
const TargetInstrInfo &TII;
const TargetRegisterInfo &TRI;
diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.cpp b/llvm/lib/Target/Hexagon/RDFLiveness.cpp
index 46537d5..25a4c5f 100644
--- a/llvm/lib/Target/Hexagon/RDFLiveness.cpp
+++ b/llvm/lib/Target/Hexagon/RDFLiveness.cpp
@@ -304,6 +304,65 @@ Liveness::getAllReachingDefsRecImpl(RegisterRef RefRR, NodeAddr<RefNode*> 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<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*>();
+}
+
NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs) {
diff --git a/llvm/lib/Target/Hexagon/RDFLiveness.h b/llvm/lib/Target/Hexagon/RDFLiveness.h
index edb9e19..6f2615b 100644
--- a/llvm/lib/Target/Hexagon/RDFLiveness.h
+++ b/llvm/lib/Target/Hexagon/RDFLiveness.h
@@ -71,6 +71,9 @@ namespace rdf {
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 {