[llvm] r282520 - [RDF] Add "dead" flag to node attributes

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 27 11:24:34 PDT 2016


Author: kparzysz
Date: Tue Sep 27 13:24:33 2016
New Revision: 282520

URL: http://llvm.org/viewvc/llvm-project?rev=282520&view=rev
Log:
[RDF] Add "dead" flag to node attributes

Modified:
    llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
    llvm/trunk/lib/Target/Hexagon/RDFGraph.h
    llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=282520&r1=282519&r2=282520&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Tue Sep 27 13:24:33 2016
@@ -65,6 +65,8 @@ raw_ostream &operator<< (raw_ostream &OS
     case NodeAttrs::Ref:
       if (Flags & NodeAttrs::Undef)
         OS << '/';
+      if (Flags & NodeAttrs::Dead)
+        OS << '\\';
       if (Flags & NodeAttrs::Preserving)
         OS << '+';
       if (Flags & NodeAttrs::Clobbering)
@@ -1316,7 +1318,8 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     while (uint16_t R = *ImpU++)
       ImpUses.insert({R, 0});
 
-  bool NeedsImplicit = isCall(In) || In.isInlineAsm() || In.isReturn();
+  bool IsCall = isCall(In);
+  bool NeedsImplicit = IsCall || In.isInlineAsm() || In.isReturn();
   bool IsPredicated = TII.isPredicated(In);
   unsigned NumOps = In.getNumOperands();
 
@@ -1342,6 +1345,8 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       Flags |= NodeAttrs::Clobbering;
     if (TOI.isFixedReg(In, OpN))
       Flags |= NodeAttrs::Fixed;
+    if (IsCall && Op.isDead())
+      Flags |= NodeAttrs::Dead;
     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
     SA.Addr->addMember(DA, *this);
     DoneDefs.insert(RR);
@@ -1369,6 +1374,8 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       Flags |= NodeAttrs::Clobbering;
     if (TOI.isFixedReg(In, OpN))
       Flags |= NodeAttrs::Fixed;
+    if (IsCall && Op.isDead())
+      Flags |= NodeAttrs::Dead;
     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
     SA.Addr->addMember(DA, *this);
     DoneDefs.insert(RR);

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=282520&r1=282519&r2=282520&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Tue Sep 27 13:24:33 2016
@@ -191,6 +191,13 @@
 //   imply that the use in (3) may indeed be reached by some prior def.
 //   Adding Undef flag to the def in (1) prevents that. The Undef flag
 //   may be applied to both defs and uses.
+// - Dead: applies only to defs. The value coming out of a "dead" def is
+//   assumed to be unused, even if the def appears to be reaching other defs
+//   or uses. The motivation for this flag comes from dead defs on function
+//   calls: there is no way to determine if such a def is dead without
+//   analyzing the target's ABI. Hence the graph should contain this info,
+//   as it is unavailable otherwise. On the other hand, a def without any
+//   uses on a typical instruction is not the intended target for this flag.
 //
 // *** Shadow references
 //
@@ -261,14 +268,15 @@ namespace rdf {
       Block         = 0x0005 << 2,  // 101
       Func          = 0x0006 << 2,  // 110
 
-      // Flags: 6 bits for now
-      FlagMask      = 0x003F << 5,
-      Shadow        = 0x0001 << 5,  // 000001, Has extra reaching defs.
-      Clobbering    = 0x0002 << 5,  // 000010, Produces unspecified values.
-      PhiRef        = 0x0004 << 5,  // 000100, Member of PhiNode.
-      Preserving    = 0x0008 << 5,  // 001000, Def can keep original bits.
-      Fixed         = 0x0010 << 5,  // 010000, Fixed register.
-      Undef         = 0x0020 << 5,  // 100000, Has no pre-existing value.
+      // Flags: 7 bits for now
+      FlagMask      = 0x007F << 5,
+      Shadow        = 0x0001 << 5,  // 0000001, Has extra reaching defs.
+      Clobbering    = 0x0002 << 5,  // 0000010, Produces unspecified values.
+      PhiRef        = 0x0004 << 5,  // 0000100, Member of PhiNode.
+      Preserving    = 0x0008 << 5,  // 0001000, Def can keep original bits.
+      Fixed         = 0x0010 << 5,  // 0010000, Fixed register.
+      Undef         = 0x0020 << 5,  // 0100000, Has no pre-existing value.
+      Dead          = 0x0040 << 5,  // 1000000, Does not define a value.
     };
 
     static uint16_t type(uint16_t T)  { return T & TypeMask; }

Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=282520&r1=282519&r2=282520&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Tue Sep 27 13:24:33 2016
@@ -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(Re
   //                     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(Re
     }
   }
 
+  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(Regi
     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(Regi
     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;




More information about the llvm-commits mailing list