[llvm] r280851 - [RDF] Introduce "undef" flag for ref nodes

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 7 13:10:56 PDT 2016


Author: kparzysz
Date: Wed Sep  7 15:10:56 2016
New Revision: 280851

URL: http://llvm.org/viewvc/llvm-project?rev=280851&view=rev
Log:
[RDF] Introduce "undef" flag for ref nodes

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=280851&r1=280850&r2=280851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Wed Sep  7 15:10:56 2016
@@ -62,6 +62,8 @@ raw_ostream &operator<< (raw_ostream &OS
       }
       break;
     case NodeAttrs::Ref:
+      if (Flags & NodeAttrs::Undef)
+        OS << '/';
       if (Flags & NodeAttrs::Preserving)
         OS << '+';
       if (Flags & NodeAttrs::Clobbering)
@@ -1189,6 +1191,19 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     return false;
   };
 
+  auto isDefUndef = [this] (const MachineInstr &In, RegisterRef DR) -> bool {
+    // This instruction defines DR. Check if there is a use operand that
+    // would make DR live on entry to the instruction.
+    for (const MachineOperand &UseOp : In.operands()) {
+      if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
+        continue;
+      RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() };
+      if (RAI.alias(DR, UR))
+        return false;
+    }
+    return true;
+  };
+
   // Collect a set of registers that this instruction implicitly uses
   // or defines. Implicit operands from an instruction will be ignored
   // unless they are listed here.
@@ -1216,8 +1231,12 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       continue;
     RegisterRef RR = { Op.getReg(), Op.getSubReg() };
     uint16_t Flags = NodeAttrs::None;
-    if (TOI.isPreserving(In, OpN))
+    if (TOI.isPreserving(In, OpN)) {
       Flags |= NodeAttrs::Preserving;
+      // If the def is preserving, check if it is also undefined.
+      if (isDefUndef(In, RR))
+        Flags |= NodeAttrs::Undef;
+    }
     if (TOI.isClobbering(In, OpN))
       Flags |= NodeAttrs::Clobbering;
     if (TOI.isFixedReg(In, OpN))
@@ -1239,8 +1258,12 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     if (DoneDefs.count(RR))
       continue;
     uint16_t Flags = NodeAttrs::None;
-    if (TOI.isPreserving(In, OpN))
+    if (TOI.isPreserving(In, OpN)) {
       Flags |= NodeAttrs::Preserving;
+      // If the def is preserving, check if it is also undefined.
+      if (isDefUndef(In, RR))
+        Flags |= NodeAttrs::Undef;
+    }
     if (TOI.isClobbering(In, OpN))
       Flags |= NodeAttrs::Clobbering;
     if (TOI.isFixedReg(In, OpN))
@@ -1252,7 +1275,7 @@ void DataFlowGraph::buildStmt(NodeAddr<B
 
   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
     MachineOperand &Op = In.getOperand(OpN);
-    if (!Op.isReg() || !Op.isUse() || Op.isUndef())
+    if (!Op.isReg() || !Op.isUse())
       continue;
     RegisterRef RR = { Op.getReg(), Op.getSubReg() };
     // Add implicit uses on return and call instructions, and on predicated
@@ -1263,6 +1286,8 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     if (Implicit && !TakeImplicit && !ImpUses.count(RR))
       continue;
     uint16_t Flags = NodeAttrs::None;
+    if (Op.isUndef())
+      Flags |= NodeAttrs::Undef;
     if (TOI.isFixedReg(In, OpN))
       Flags |= NodeAttrs::Fixed;
     NodeAddr<UseNode*> UA = newUse(SA, Op, Flags);

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=280851&r1=280850&r2=280851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Wed Sep  7 15:10:56 2016
@@ -175,7 +175,22 @@
 // - Clobbering: applied only to defs, indicates that the value generated
 //   by this def is unspecified. A typical example would be volatile registers
 //   after function calls.
-//
+// - Fixed: the register in this def/use cannot be replaced with any other
+//   register. A typical case would be a parameter register to a call, or
+//   the register with the return value from a function.
+// - Undef: the register in this reference the register is assumed to have
+//   no pre-existing value, even if it appears to be reached by some def.
+//   This is typically used to prevent keeping registers artificially live
+//   in cases when they are defined via predicated instructions. For example:
+//     r0 = add-if-true cond, r10, r11                (1)
+//     r0 = add-if-false cond, r12, r13, r0<imp-use>  (2)
+//     ... = r0                                       (3)
+//   Before (1), r0 is not intended to be live, and the use of r0 in (3) is
+//   not meant to be reached by any def preceding (1). However, since the
+//   defs in (1) and (2) are both preserving, these properties alone would
+//   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.
 //
 // *** Shadow references
 //
@@ -244,13 +259,14 @@ namespace rdf {
       Block         = 0x0005 << 2,  // 101
       Func          = 0x0006 << 2,  // 110
 
-      // Flags: 5 bits for now
-      FlagMask      = 0x001F << 5,
-      Shadow        = 0x0001 << 5,  // 00001, Has extra reaching defs.
-      Clobbering    = 0x0002 << 5,  // 00010, Produces unspecified values.
-      PhiRef        = 0x0004 << 5,  // 00100, Member of PhiNode.
-      Preserving    = 0x0008 << 5,  // 01000, Def can keep original bits.
-      Fixed         = 0x0010 << 5,  // 10000, Fixed register.
+      // 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.
     };
 
     static uint16_t type(uint16_t T)  { return T & TypeMask; }
@@ -742,6 +758,10 @@ namespace rdf {
       return BA.Addr->getType() == NodeAttrs::Code &&
              BA.Addr->getKind() == NodeAttrs::Phi;
     }
+    static bool IsPreservingDef(const NodeAddr<DefNode*> DA) {
+      uint16_t Flags = DA.Addr->getFlags();
+      return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
+    }
 
   private:
     void reset();

Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=280851&r1=280850&r2=280851&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Wed Sep  7 15:10:56 2016
@@ -109,11 +109,9 @@ NodeList Liveness::getAllReachingDefs(Re
       continue;
     // Stop at the covering/overwriting def of the initial register reference.
     RegisterRef RR = TA.Addr->getRegRef();
-    if (RAI.covers(RR, RefRR)) {
-      uint16_t Flags = TA.Addr->getFlags();
-      if (!(Flags & NodeAttrs::Preserving))
+    if (RAI.covers(RR, RefRR))
+      if (!DFG.IsPreservingDef(TA))
         continue;
-    }
     // Get the next level of reaching defs. This will include multiple
     // reaching defs for shadows.
     for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
@@ -221,7 +219,7 @@ NodeList Liveness::getAllReachingDefs(Re
       // defs to actually define a register.
       uint16_t Flags = DA.Addr->getFlags();
       if (!FullChain || !(Flags & NodeAttrs::PhiRef))
-        if (!(Flags & NodeAttrs::Preserving))
+        if (!(Flags & NodeAttrs::Preserving)) // Don't care about Undef here.
           RRs.insert(DA.Addr->getRegRef());
     }
   }
@@ -291,9 +289,11 @@ NodeSet Liveness::getAllReachedUses(Regi
   NodeId U = DefA.Addr->getReachedUse();
   while (U != 0) {
     auto UA = DFG.addr<UseNode*>(U);
-    auto UR = UA.Addr->getRegRef();
-    if (RAI.alias(RefRR, UR) && !RAI.covers(DefRRs, UR))
-      Uses.insert(U);
+    if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
+      auto UR = UA.Addr->getRegRef();
+      if (RAI.alias(RefRR, UR) && !RAI.covers(DefRRs, UR))
+        Uses.insert(U);
+    }
     U = UA.Addr->getSibling();
   }
 
@@ -307,7 +307,7 @@ NodeSet Liveness::getAllReachedUses(Regi
     if (RAI.covers(DefRRs, DR) || !RAI.alias(RefRR, DR))
       continue;
     NodeSet T;
-    if (DA.Addr->getFlags() & NodeAttrs::Preserving) {
+    if (DFG.IsPreservingDef(DA)) {
       // If it is a preserving def, do not update the set of intervening defs.
       T = getAllReachedUses(RefRR, DA, DefRRs);
     } else {
@@ -358,7 +358,8 @@ void Liveness::computePhiInfo() {
       NodeId UN = DA.Addr->getReachedUse();
       while (UN != 0) {
         NodeAddr<UseNode*> A = DFG.addr<UseNode*>(UN);
-        if (!(A.Addr->getFlags() & NodeAttrs::PhiRef))
+        uint16_t F = A.Addr->getFlags();
+        if ((F & (NodeAttrs::Undef | NodeAttrs::PhiRef)) == 0)
           RealUses[getRestrictedRegRef(A)].insert(A.Id);
         UN = A.Addr->getSibling();
       }
@@ -847,14 +848,16 @@ void Liveness::traverse(MachineBasicBloc
       if (B != BA.Addr->getCode())
         Defs.insert(R);
       else {
-        bool IsPreserving = DA.Addr->getFlags() & NodeAttrs::Preserving;
+        bool IsPreserving = DFG.IsPreservingDef(DA);
         if (IA.Addr->getKind() != NodeAttrs::Phi && !IsPreserving) {
           bool Covering = RAI.covers(DDR, I.first);
           NodeId U = DA.Addr->getReachedUse();
           while (U && Covering) {
             auto DUA = DFG.addr<UseNode*>(U);
-            RegisterRef Q = DUA.Addr->getRegRef();
-            Covering = RAI.covers(DA.Addr->getRegRef(), Q);
+            if (!(DUA.Addr->getFlags() & NodeAttrs::Undef)) {
+              RegisterRef Q = DUA.Addr->getRegRef();
+              Covering = RAI.covers(DA.Addr->getRegRef(), Q);
+            }
             U = DUA.Addr->getSibling();
           }
           if (!Covering)
@@ -898,6 +901,8 @@ void Liveness::traverse(MachineBasicBloc
       continue;
     for (NodeAddr<UseNode*> UA : IA.Addr->members_if(DFG.IsUse, DFG)) {
       RegisterRef RR = UA.Addr->getRegRef();
+      if (UA.Addr->getFlags() & NodeAttrs::Undef)
+        continue;
       for (auto D : getAllReachingDefs(UA))
         if (getBlockWithRef(D.Id) != B)
           LiveIn[RR].insert(D.Id);




More information about the llvm-commits mailing list