[llvm] [SSAUpdater] Avoid scanning basic blocks to find instruction order. (PR #123803)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 21 12:47:21 PST 2025


================
@@ -432,27 +432,27 @@ void LoadAndStorePromoter::run(const SmallVectorImpl<Instruction *> &Insts) {
       }
     }
 
-    // If so, we can queue them all as live in loads.  We don't have an
-    // efficient way to tell which on is first in the block and don't want to
-    // scan large blocks, so just add all loads as live ins.
+    // If so, we can queue them all as live in loads.
     if (!HasStore) {
       for (Instruction *I : BlockUses)
         LiveInLoads.push_back(cast<LoadInst>(I));
       BlockUses.clear();
       continue;
     }
 
+    // Sort all of the interesting instructions in the block so that we don't
+    // have to scan a large block just to find a few instructions.
+    std::sort(BlockUses.begin(), BlockUses.end(),
+              [](Instruction *A, Instruction *B) { return A->comesBefore(B); });
+
     // Otherwise, we have mixed loads and stores (or just a bunch of stores).
     // Since SSAUpdater is purely for cross-block values, we need to determine
     // the order of these instructions in the block.  If the first use in the
     // block is a load, then it uses the live in value.  The last store defines
-    // the live out value.  We handle this by doing a linear scan of the block.
+    // the live out value.
     Value *StoredValue = nullptr;
-    for (Instruction &I : *BB) {
-      if (LoadInst *L = dyn_cast<LoadInst>(&I)) {
-        // If this is a load from an unrelated pointer, ignore it.
-        if (!isInstInList(L, Insts)) continue;
-
+    for (Instruction *I : BlockUses) {
+      if (LoadInst *L = dyn_cast<LoadInst>(I)) {
----------------
nikic wrote:

Can also remove the isInstInList method now?

https://github.com/llvm/llvm-project/pull/123803


More information about the llvm-commits mailing list