[PATCH] D59722: [ScheduleDAG] Avoid unnecessary recomputation of topological order.

Florian Hahn via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 22 15:06:42 PDT 2019


fhahn created this revision.
fhahn added reviewers: MatzeB, atrick, efriedma, niravd.
Herald added subscribers: jdoerfert, hiraditya.
Herald added a project: LLVM.

In some cases ScheduleDAGRRList has to add new nodes to resolve problems
with interfering physical registers. When new nodes are added, it
completely re-computes the topological order, which can take a long
time, but is unnecessary. We only add nodes one by one, and initially
they do not have any predecessors. So we can just insert them at the end
of the vector. Later we add predecessors, but the helper function
properly updates the topological order much more efficiently. With this
change, the compile time for the program below drops from 300s to 30s on
my machine.

  define i11129 @test1() {
    %L1 = load i11129, i11129* undef
    %B30 = ashr i11129 %L1, %L1
    store i11129 %B30, i11129* undef
    ret i11129 %L1
  }

This should be generally beneficial, as we can skip a large amount of
work. Theoretically there are some scenarios where we might not safe
much, e.g. when we add a dependency between the first and last node.
Then we would have to shift all nodes. But we still do not have to spend
the time re-computing the initial order.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D59722

Files:
  llvm/include/llvm/CodeGen/ScheduleDAG.h
  llvm/lib/CodeGen/ScheduleDAG.cpp
  llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp


Index: llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -272,7 +272,7 @@
     SUnit *NewNode = newSUnit(N);
     // Update the topological ordering.
     if (NewNode->NodeNum >= NumSUnits)
-      Topo.InitDAGTopologicalSorting();
+      Topo.AddSUnitWithoutPredecessors(NewNode);
     return NewNode;
   }
 
@@ -283,7 +283,7 @@
     SUnit *NewNode = Clone(N);
     // Update the topological ordering.
     if (NewNode->NodeNum >= NumSUnits)
-      Topo.InitDAGTopologicalSorting();
+      Topo.AddSUnitWithoutPredecessors(NewNode);
     return NewNode;
   }
 
Index: llvm/lib/CodeGen/ScheduleDAG.cpp
===================================================================
--- llvm/lib/CodeGen/ScheduleDAG.cpp
+++ llvm/lib/CodeGen/ScheduleDAG.cpp
@@ -674,6 +674,14 @@
   return false;
 }
 
+void ScheduleDAGTopologicalSort::AddSUnitWithoutPredecessors(const SUnit *SU) {
+  assert(SU->NodeNum == Index2Node.size() && "Node cannot be added at the end");
+  assert(SU->NumPreds == 0 && "Can only add SU's with no predecessors");
+  Node2Index.push_back(Index2Node.size());
+  Index2Node.push_back(SU->NodeNum);
+  Visited.resize(Node2Index.size());
+}
+
 bool ScheduleDAGTopologicalSort::IsReachable(const SUnit *SU,
                                              const SUnit *TargetSU) {
   // If insertion of the edge SU->TargetSU would create a cycle
Index: llvm/include/llvm/CodeGen/ScheduleDAG.h
===================================================================
--- llvm/include/llvm/CodeGen/ScheduleDAG.h
+++ llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -713,6 +713,10 @@
   public:
     ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
 
+    /// Add a SUnit without predecessors to the end of the topological order. It
+    /// also must be the first new node added to the DAG.
+    void AddSUnitWithoutPredecessors(const SUnit *SU);
+
     /// Creates the initial topological ordering from the DAG to be scheduled.
     void InitDAGTopologicalSorting();
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D59722.191956.patch
Type: text/x-patch
Size: 2165 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190322/53f76b9d/attachment.bin>


More information about the llvm-commits mailing list