[Loads] Extract helper frunction for available load/store (NFC)
authorNikita Popov <nikita.ppv@gmail.com>
Sun, 21 Feb 2021 17:22:34 +0000 (18:22 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Sun, 21 Feb 2021 17:24:58 +0000 (18:24 +0100)
This contains the logic for extracting an available load/store
from a given instruction, to be reused in a following patch.

llvm/lib/Analysis/Loads.cpp

index af7ef98..42fe548 100644 (file)
@@ -462,6 +462,49 @@ static bool AreNonOverlapSameBaseLoadAndStore(
   return LoadRange.intersectWith(StoreRange).isEmptySet();
 }
 
+static Value *getAvailableLoadStore(Instruction *Inst, Value *Ptr,
+                                    Type *AccessTy, bool AtLeastAtomic,
+                                    const DataLayout &DL, bool *IsLoadCSE) {
+  // If this is a load of Ptr, the loaded value is available.
+  // (This is true even if the load is volatile or atomic, although
+  // those cases are unlikely.)
+  if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
+    if (AreEquivalentAddressValues(
+            LI->getPointerOperand()->stripPointerCasts(), Ptr) &&
+        CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
+      // We can value forward from an atomic to a non-atomic, but not the
+      // other way around.
+      if (LI->isAtomic() < AtLeastAtomic)
+        return nullptr;
+
+      if (IsLoadCSE)
+        *IsLoadCSE = true;
+      return LI;
+    }
+  }
+
+  // If this is a store through Ptr, the value is available!
+  // (This is true even if the store is volatile or atomic, although
+  // those cases are unlikely.)
+  if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+    Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
+    if (AreEquivalentAddressValues(StorePtr, Ptr) &&
+        CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
+                                             AccessTy, DL)) {
+      // We can value forward from an atomic to a non-atomic, but not the
+      // other way around.
+      if (SI->isAtomic() < AtLeastAtomic)
+        return nullptr;
+
+      if (IsLoadCSE)
+        *IsLoadCSE = false;
+      return SI->getOperand(0);
+    }
+  }
+
+  return nullptr;
+}
+
 Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
                                        bool AtLeastAtomic, BasicBlock *ScanBB,
                                        BasicBlock::iterator &ScanFrom,
@@ -492,45 +535,16 @@ Value *llvm::FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy,
       return nullptr;
 
     --ScanFrom;
-    // If this is a load of Ptr, the loaded value is available.
-    // (This is true even if the load is volatile or atomic, although
-    // those cases are unlikely.)
-    if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
-      if (AreEquivalentAddressValues(
-              LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
-          CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
-
-        // We can value forward from an atomic to a non-atomic, but not the
-        // other way around.
-        if (LI->isAtomic() < AtLeastAtomic)
-          return nullptr;
-
-        if (IsLoadCSE)
-            *IsLoadCSE = true;
-        return LI;
-      }
+
+    if (Value *Available = getAvailableLoadStore(Inst, StrippedPtr, AccessTy,
+                                                 AtLeastAtomic, DL, IsLoadCSE))
+      return Available;
 
     // Try to get the store size for the type.
     auto AccessSize = LocationSize::precise(DL.getTypeStoreSize(AccessTy));
 
     if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
       Value *StorePtr = SI->getPointerOperand()->stripPointerCasts();
-      // If this is a store through Ptr, the value is available!
-      // (This is true even if the store is volatile or atomic, although
-      // those cases are unlikely.)
-      if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
-          CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
-                                               AccessTy, DL)) {
-
-        // We can value forward from an atomic to a non-atomic, but not the
-        // other way around.
-        if (SI->isAtomic() < AtLeastAtomic)
-          return nullptr;
-
-        if (IsLoadCSE)
-          *IsLoadCSE = false;
-        return SI->getOperand(0);
-      }
 
       // If both StrippedPtr and StorePtr reach all the way to an alloca or
       // global and they are different, ignore the store. This is a trivial form