[llvm] r331087 - [FastISel] Fix local value sinking algorithmic complexity

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 27 14:48:51 PDT 2018


Author: rnk
Date: Fri Apr 27 14:48:51 2018
New Revision: 331087

URL: http://llvm.org/viewvc/llvm-project?rev=331087&view=rev
Log:
[FastISel] Fix local value sinking algorithmic complexity

Now local value sinking only scans and numbers instructions added
between the current flush point and the last flush point. This ensures
that ISel is overall linear in the size of the BB.

Fixes PR37010 and re-enables local value sinking by default.

Modified:
    llvm/trunk/include/llvm/CodeGen/FastISel.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp

Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=331087&r1=331086&r2=331087&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
+++ llvm/trunk/include/llvm/CodeGen/FastISel.h Fri Apr 27 14:48:51 2018
@@ -226,6 +226,10 @@ protected:
   /// makes sense (for example, on function calls)
   MachineInstr *EmitStartPt;
 
+  /// Last local value flush point. On a subsequent flush, no local value will
+  /// sink past this point.
+  MachineBasicBlock::iterator LastFlushPoint;
+
 public:
   virtual ~FastISel();
 
@@ -569,7 +573,8 @@ private:
     MachineInstr *FirstTerminator = nullptr;
     unsigned FirstTerminatorOrder = std::numeric_limits<unsigned>::max();
 
-    void initialize(MachineBasicBlock *MBB);
+    void initialize(MachineBasicBlock *MBB,
+                    MachineBasicBlock::iterator LastFlushPoint);
   };
 
   /// Sinks the local value materialization instruction LocalMI to its first use

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=331087&r1=331086&r2=331087&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Fri Apr 27 14:48:51 2018
@@ -215,6 +215,7 @@ void FastISel::flushLocalValueMap() {
   LastLocalValue = EmitStartPt;
   recomputeInsertPt();
   SavedInsertPt = FuncInfo.InsertPt;
+  LastFlushPoint = FuncInfo.InsertPt;
 }
 
 static bool isRegUsedByPhiNodes(unsigned DefReg,
@@ -228,7 +229,8 @@ static bool isRegUsedByPhiNodes(unsigned
 /// Build a map of instruction orders. Return the first terminator and its
 /// order. Consider EH_LABEL instructions to be terminators as well, since local
 /// values for phis after invokes must be materialized before the call.
-void FastISel::InstOrderMap::initialize(MachineBasicBlock *MBB) {
+void FastISel::InstOrderMap::initialize(
+    MachineBasicBlock *MBB, MachineBasicBlock::iterator LastFlushPoint) {
   unsigned Order = 0;
   for (MachineInstr &I : *MBB) {
     if (!FirstTerminator &&
@@ -237,6 +239,10 @@ void FastISel::InstOrderMap::initialize(
       FirstTerminatorOrder = Order;
     }
     Orders[&I] = Order++;
+
+    // We don't need to order instructions past the last flush point.
+    if (I.getIterator() == LastFlushPoint)
+      break;
   }
 }
 
@@ -266,13 +272,16 @@ void FastISel::sinkLocalValueMaterializa
   // Number the instructions if we haven't yet so we can efficiently find the
   // earliest use.
   if (OrderMap.Orders.empty())
-    OrderMap.initialize(FuncInfo.MBB);
+    OrderMap.initialize(FuncInfo.MBB, LastFlushPoint);
 
   // Find the first user in the BB.
   MachineInstr *FirstUser = nullptr;
   unsigned FirstOrder = std::numeric_limits<unsigned>::max();
   for (MachineInstr &UseInst : MRI.use_nodbg_instructions(DefReg)) {
-    unsigned UseOrder = OrderMap.Orders[&UseInst];
+    auto I = OrderMap.Orders.find(&UseInst);
+    assert(I != OrderMap.Orders.end() &&
+           "local value used by instruction outside local region");
+    unsigned UseOrder = I->second;
     if (UseOrder < FirstOrder) {
       FirstOrder = UseOrder;
       FirstUser = &UseInst;




More information about the llvm-commits mailing list