[llvm] c6ddd04 - [RDF] Create individual phi for each indivisible register

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 8 11:08:32 PDT 2023


Author: Krzysztof Parzyszek
Date: 2023-06-08T11:07:57-07:00
New Revision: c6ddd04d73c31d970176df3e52edfd7a58e91d86

URL: https://github.com/llvm/llvm-project/commit/c6ddd04d73c31d970176df3e52edfd7a58e91d86
DIFF: https://github.com/llvm/llvm-project/commit/c6ddd04d73c31d970176df3e52edfd7a58e91d86.diff

LOG: [RDF] Create individual phi for each indivisible register

This isn't quite using register units, but it's getting close. The phi
generation is driven by register units, but each phi still contains a
reference to a register, potentially with a mask that amounts to a unit.
In cases of explicit register aliasing this may still create phis with
references that are aliased, whereas separate phis would ideally contain
disjoint references (this is all within a single basic block).

Previously phis used maximal registers, now they use minimal. This is a
step towards both, using register units directly, and a simpler liveness
calculation algorithm. The idea is that a phi cannot reach a reference
to anything smaller than the phi itself represents. Before there could
be a phi for R1_R0, now there will be two for this case (assuming R0 and
R1 have one unit each).

Added: 
    

Modified: 
    llvm/lib/CodeGen/RDFGraph.cpp
    llvm/lib/CodeGen/RDFLiveness.cpp
    llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
    llvm/test/CodeGen/Hexagon/newify-crash.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/RDFGraph.cpp b/llvm/lib/CodeGen/RDFGraph.cpp
index 14f9c1167bb43..801113479852e 100644
--- a/llvm/lib/CodeGen/RDFGraph.cpp
+++ b/llvm/lib/CodeGen/RDFGraph.cpp
@@ -1433,87 +1433,24 @@ void DataFlowGraph::buildPhis(BlockRefsMap &PhiM, RegisterSet &AllRefs,
   if (HasDF == PhiM.end() || HasDF->second.empty())
     return;
 
-  // First, remove all R in Refs in such that there exists T in Refs
-  // such that T covers R. In other words, only leave those refs that
-  // are not covered by another ref (i.e. maximal with respect to covering).
-
-  auto MaxCoverIn = [this](RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
-    for (RegisterRef I : RRs)
-      if (I != RR && RegisterAggr::isCoverOf(I, RR, PRI))
-        RR = I;
-    return RR;
-  };
-
-  RegisterSet MaxDF, DefsDF;
-  for (auto I = HasDF->second.rr_begin(), E = HasDF->second.rr_end(); I != E;
-       ++I) {
-    DefsDF.insert(*I);
-  }
-  for (RegisterRef I : DefsDF)
-    MaxDF.insert(MaxCoverIn(I, DefsDF));
-
-  std::vector<RegisterRef> MaxRefs;
-  for (RegisterRef I : MaxDF)
-    MaxRefs.push_back(MaxCoverIn(I, AllRefs));
-
-  // Now, for each R in MaxRefs, get the alias closure of R. If the closure
-  // only has R in it, create a phi a def for R. Otherwise, create a phi,
-  // and add a def for each S in the closure.
-
-  // Sort the refs so that the phis will be created in a deterministic order.
-  llvm::sort(MaxRefs);
-  // Remove duplicates.
-  auto NewEnd = std::unique(MaxRefs.begin(), MaxRefs.end());
-  MaxRefs.erase(NewEnd, MaxRefs.end());
-
-  auto Aliased = [this, &MaxRefs](RegisterRef RR,
-                                  std::vector<unsigned> &Closure) -> bool {
-    for (unsigned I : Closure)
-      if (PRI.alias(RR, MaxRefs[I]))
-        return true;
-    return false;
-  };
-
   // Prepare a list of NodeIds of the block's predecessors.
   NodeList Preds;
   const MachineBasicBlock *MBB = BA.Addr->getCode();
   for (MachineBasicBlock *PB : MBB->predecessors())
     Preds.push_back(findBlock(PB));
 
-  while (!MaxRefs.empty()) {
-    // Put the first element in the closure, and then add all subsequent
-    // elements from MaxRefs to it, if they alias at least one element
-    // already in the closure.
-    // ClosureIdx: vector of indices in MaxRefs of members of the closure.
-    std::vector<unsigned> ClosureIdx = {0};
-    for (unsigned i = 1; i != MaxRefs.size(); ++i)
-      if (Aliased(MaxRefs[i], ClosureIdx))
-        ClosureIdx.push_back(i);
-
-    // Build a phi for the closure.
-    unsigned CS = ClosureIdx.size();
+  const RegisterAggr &Defs = PhiM[BA.Id];
+  uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
+
+  for (auto I = Defs.rr_begin(), E = Defs.rr_end(); I != E; ++I) {
+    RegisterRef RR = *I;
     NodeAddr<PhiNode *> PA = newPhi(BA);
+    PA.Addr->addMember(newDef(PA, RR, PhiFlags), *this);
 
-    // Add defs.
-    for (unsigned X = 0; X != CS; ++X) {
-      RegisterRef RR = MaxRefs[ClosureIdx[X]];
-      uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
-      NodeAddr<DefNode *> DA = newDef(PA, RR, PhiFlags);
-      PA.Addr->addMember(DA, *this);
-    }
     // Add phi uses.
     for (NodeAddr<BlockNode *> PBA : Preds) {
-      for (unsigned X = 0; X != CS; ++X) {
-        RegisterRef RR = MaxRefs[ClosureIdx[X]];
-        NodeAddr<PhiUseNode *> PUA = newPhiUse(PA, RR, PBA);
-        PA.Addr->addMember(PUA, *this);
-      }
+      PA.Addr->addMember(newPhiUse(PA, RR, PBA), *this);
     }
-
-    // Erase from MaxRefs all elements in the closure.
-    auto Begin = MaxRefs.begin();
-    for (unsigned Idx : llvm::reverse(ClosureIdx))
-      MaxRefs.erase(Begin + Idx);
   }
 }
 

diff  --git a/llvm/lib/CodeGen/RDFLiveness.cpp b/llvm/lib/CodeGen/RDFLiveness.cpp
index 484ab6e5739e5..c3ef9ed23be08 100644
--- a/llvm/lib/CodeGen/RDFLiveness.cpp
+++ b/llvm/lib/CodeGen/RDFLiveness.cpp
@@ -560,7 +560,11 @@ void Liveness::computePhiInfo() {
         auto UA = DFG.addr<UseNode *>(I.first);
         // Undef flag is checked above.
         assert((UA.Addr->getFlags() & NodeAttrs::Undef) == 0);
-        RegisterRef R(UI->first, I.second);
+        RegisterRef UseR(UI->first, I.second); // Ref from Uses
+        // R = intersection of the ref from the phi and the ref from Uses
+        RegisterRef R = PhiDRs.at(PhiA.Id).intersectWith(UseR);
+        if (!R)
+          continue;
         // Calculate the exposed part of the reached use.
         RegisterAggr Covered(PRI);
         for (NodeAddr<DefNode *> DA : getAllReachingDefs(R, UA)) {
@@ -781,9 +785,10 @@ void Liveness::computeLiveIns() {
   for (NodeAddr<BlockNode *> BA : Blocks) {
     MachineBasicBlock *MB = BA.Addr->getCode();
     RefMap &LON = PhiLON[MB];
-    for (auto P : BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG))
+    for (auto P : BA.Addr->members_if(DFG.IsCode<NodeAttrs::Phi>, DFG)) {
       for (const RefMap::value_type &S : RealUseMap[P.Id])
         LON[S.first].insert(S.second.begin(), S.second.end());
+    }
   }
 
   if (Trace) {

diff  --git a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
index 99aaf1c1b592c..418cb3cbe0897 100644
--- a/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRDFOpt.cpp
@@ -320,8 +320,10 @@ bool HexagonRDFOpt::runOnMachineFunction(MachineFunction &MF) {
   Changed |= DCE.run();
 
   if (Changed) {
-    if (RDFDump)
-      dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n';
+    if (RDFDump) {
+      dbgs() << "Starting liveness recomputation on: " << MF.getName() << '\n'
+             << PrintNode<FuncNode*>(G.getFunc(), G) << '\n';
+    }
     Liveness LV(*MRI, G);
     LV.trace(RDFDump);
     LV.computeLiveIns();

diff  --git a/llvm/test/CodeGen/Hexagon/newify-crash.ll b/llvm/test/CodeGen/Hexagon/newify-crash.ll
index bb29954291271..2454a38b0388c 100644
--- a/llvm/test/CodeGen/Hexagon/newify-crash.ll
+++ b/llvm/test/CodeGen/Hexagon/newify-crash.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -march=hexagon < %s | FileCheck %s
 ;
 ; Check that this testcase doesn't crash.
-; CHECK: vadd
+; CHECK: jump f0
 
 target triple = "hexagon"
 


        


More information about the llvm-commits mailing list