]> granicus.if.org Git - llvm/commitdiff
[RDF] Implement Liveness::getNearestAliasedRef(Reg, Inst)
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 10 Mar 2017 22:42:17 +0000 (22:42 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 10 Mar 2017 22:42:17 +0000 (22:42 +0000)
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

lib/Target/Hexagon/RDFGraph.h
lib/Target/Hexagon/RDFLiveness.cpp
lib/Target/Hexagon/RDFLiveness.h

index bf4018ba7fcd0e05a0eed3d10d5fa4e36b5a25e3..d5faca4cd6f4b5be0321e25055a5076e637fa210 100644 (file)
@@ -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;
index 46537d55be32e938da478ed806f05be19f595048..25a4c5f7058d58ad6c0fad59c69297bfba4195cb 100644 (file)
@@ -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) {
index edb9e198fb885b1616e18540e658c0fceb5245cc..6f2615b7c4f37ca91494fac13a368d87a77340b5 100644 (file)
@@ -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 {