From ec25a71eb7fc72440149784951d62453301cc960 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 31 May 2020 11:04:35 +0100 Subject: [PATCH] [ScheduleDAG] Avoid unnecessary recomputation of topological order. 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. Reviewers: MatzeB, atrick, efriedma, niravd, paquette Reviewed By: paquette Differential Revision: https://reviews.llvm.org/D59722 --- llvm/include/llvm/CodeGen/ScheduleDAG.h | 4 ++++ llvm/lib/CodeGen/ScheduleDAG.cpp | 8 ++++++++ llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/ScheduleDAG.h b/llvm/include/llvm/CodeGen/ScheduleDAG.h index e004f3b..4c8d047 100644 --- a/llvm/include/llvm/CodeGen/ScheduleDAG.h +++ b/llvm/include/llvm/CodeGen/ScheduleDAG.h @@ -724,6 +724,10 @@ class TargetRegisterInfo; public: ScheduleDAGTopologicalSort(std::vector &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(); diff --git a/llvm/lib/CodeGen/ScheduleDAG.cpp b/llvm/lib/CodeGen/ScheduleDAG.cpp index dc3a116..60f8eec 100644 --- a/llvm/lib/CodeGen/ScheduleDAG.cpp +++ b/llvm/lib/CodeGen/ScheduleDAG.cpp @@ -713,6 +713,14 @@ bool ScheduleDAGTopologicalSort::WillCreateCycle(SUnit *TargetSU, SUnit *SU) { 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) { FixOrder(); diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index ff806bd..72e68a5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -279,7 +279,7 @@ private: SUnit *NewNode = newSUnit(N); // Update the topological ordering. if (NewNode->NodeNum >= NumSUnits) - Topo.MarkDirty(); + Topo.AddSUnitWithoutPredecessors(NewNode); return NewNode; } @@ -289,7 +289,7 @@ private: SUnit *NewNode = Clone(N); // Update the topological ordering. if (NewNode->NodeNum >= NumSUnits) - Topo.MarkDirty(); + Topo.AddSUnitWithoutPredecessors(NewNode); return NewNode; } -- 2.7.4