xref: /freebsd-src/contrib/llvm-project/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MemoryDependenceAnalysis.cpp - Mem Deps Implementation -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements an analysis that determines, for a given memory
100b57cec5SDimitry Andric // operation, what preceding memory operations it depends on.  It builds on
110b57cec5SDimitry Andric // alias analysis information, and tries to provide a lazy, caching interface to
120b57cec5SDimitry Andric // a common kind of alias information query.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/Analysis/MemoryDependenceAnalysis.h"
170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/MemoryBuiltins.h"
250b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
260b57cec5SDimitry Andric #include "llvm/Analysis/PHITransAddr.h"
270b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
280b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
290b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
300b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
310b57cec5SDimitry Andric #include "llvm/IR/Function.h"
320b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
330b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
340b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
350b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
360b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
370b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
380b57cec5SDimitry Andric #include "llvm/IR/Module.h"
390b57cec5SDimitry Andric #include "llvm/IR/PredIteratorCache.h"
400b57cec5SDimitry Andric #include "llvm/IR/Type.h"
410b57cec5SDimitry Andric #include "llvm/IR/Use.h"
420b57cec5SDimitry Andric #include "llvm/IR/Value.h"
43480093f4SDimitry Andric #include "llvm/InitializePasses.h"
440b57cec5SDimitry Andric #include "llvm/Pass.h"
450b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
460b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
470b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
480b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
490b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
500b57cec5SDimitry Andric #include <algorithm>
510b57cec5SDimitry Andric #include <cassert>
520b57cec5SDimitry Andric #include <iterator>
530b57cec5SDimitry Andric #include <utility>
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric using namespace llvm;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric #define DEBUG_TYPE "memdep"
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric STATISTIC(NumCacheNonLocal, "Number of fully cached non-local responses");
600b57cec5SDimitry Andric STATISTIC(NumCacheDirtyNonLocal, "Number of dirty cached non-local responses");
610b57cec5SDimitry Andric STATISTIC(NumUncacheNonLocal, "Number of uncached non-local responses");
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric STATISTIC(NumCacheNonLocalPtr,
640b57cec5SDimitry Andric           "Number of fully cached non-local ptr responses");
650b57cec5SDimitry Andric STATISTIC(NumCacheDirtyNonLocalPtr,
660b57cec5SDimitry Andric           "Number of cached, but dirty, non-local ptr responses");
670b57cec5SDimitry Andric STATISTIC(NumUncacheNonLocalPtr, "Number of uncached non-local ptr responses");
680b57cec5SDimitry Andric STATISTIC(NumCacheCompleteNonLocalPtr,
690b57cec5SDimitry Andric           "Number of block queries that were completely cached");
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric // Limit for the number of instructions to scan in a block.
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric static cl::opt<unsigned> BlockScanLimit(
740b57cec5SDimitry Andric     "memdep-block-scan-limit", cl::Hidden, cl::init(100),
750b57cec5SDimitry Andric     cl::desc("The number of instructions to scan in a block in memory "
760b57cec5SDimitry Andric              "dependency analysis (default = 100)"));
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric static cl::opt<unsigned>
79bdd1243dSDimitry Andric     BlockNumberLimit("memdep-block-number-limit", cl::Hidden, cl::init(200),
800b57cec5SDimitry Andric                      cl::desc("The number of blocks to scan during memory "
81bdd1243dSDimitry Andric                               "dependency analysis (default = 200)"));
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric // Limit on the number of memdep results to process.
840b57cec5SDimitry Andric static const unsigned int NumResultsLimit = 100;
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric /// This is a helper function that removes Val from 'Inst's set in ReverseMap.
870b57cec5SDimitry Andric ///
880b57cec5SDimitry Andric /// If the set becomes empty, remove Inst's entry.
890b57cec5SDimitry Andric template <typename KeyTy>
900b57cec5SDimitry Andric static void
910b57cec5SDimitry Andric RemoveFromReverseMap(DenseMap<Instruction *, SmallPtrSet<KeyTy, 4>> &ReverseMap,
920b57cec5SDimitry Andric                      Instruction *Inst, KeyTy Val) {
930b57cec5SDimitry Andric   typename DenseMap<Instruction *, SmallPtrSet<KeyTy, 4>>::iterator InstIt =
940b57cec5SDimitry Andric       ReverseMap.find(Inst);
950b57cec5SDimitry Andric   assert(InstIt != ReverseMap.end() && "Reverse map out of sync?");
960b57cec5SDimitry Andric   bool Found = InstIt->second.erase(Val);
970b57cec5SDimitry Andric   assert(Found && "Invalid reverse map!");
980b57cec5SDimitry Andric   (void)Found;
990b57cec5SDimitry Andric   if (InstIt->second.empty())
1000b57cec5SDimitry Andric     ReverseMap.erase(InstIt);
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric /// If the given instruction references a specific memory location, fill in Loc
1040b57cec5SDimitry Andric /// with the details, otherwise set Loc.Ptr to null.
1050b57cec5SDimitry Andric ///
1060b57cec5SDimitry Andric /// Returns a ModRefInfo value describing the general behavior of the
1070b57cec5SDimitry Andric /// instruction.
1080b57cec5SDimitry Andric static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,
1090b57cec5SDimitry Andric                               const TargetLibraryInfo &TLI) {
1100b57cec5SDimitry Andric   if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
1110b57cec5SDimitry Andric     if (LI->isUnordered()) {
1120b57cec5SDimitry Andric       Loc = MemoryLocation::get(LI);
1130b57cec5SDimitry Andric       return ModRefInfo::Ref;
1140b57cec5SDimitry Andric     }
1150b57cec5SDimitry Andric     if (LI->getOrdering() == AtomicOrdering::Monotonic) {
1160b57cec5SDimitry Andric       Loc = MemoryLocation::get(LI);
1170b57cec5SDimitry Andric       return ModRefInfo::ModRef;
1180b57cec5SDimitry Andric     }
1190b57cec5SDimitry Andric     Loc = MemoryLocation();
1200b57cec5SDimitry Andric     return ModRefInfo::ModRef;
1210b57cec5SDimitry Andric   }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
1240b57cec5SDimitry Andric     if (SI->isUnordered()) {
1250b57cec5SDimitry Andric       Loc = MemoryLocation::get(SI);
1260b57cec5SDimitry Andric       return ModRefInfo::Mod;
1270b57cec5SDimitry Andric     }
1280b57cec5SDimitry Andric     if (SI->getOrdering() == AtomicOrdering::Monotonic) {
1290b57cec5SDimitry Andric       Loc = MemoryLocation::get(SI);
1300b57cec5SDimitry Andric       return ModRefInfo::ModRef;
1310b57cec5SDimitry Andric     }
1320b57cec5SDimitry Andric     Loc = MemoryLocation();
1330b57cec5SDimitry Andric     return ModRefInfo::ModRef;
1340b57cec5SDimitry Andric   }
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
1370b57cec5SDimitry Andric     Loc = MemoryLocation::get(V);
1380b57cec5SDimitry Andric     return ModRefInfo::ModRef;
1390b57cec5SDimitry Andric   }
1400b57cec5SDimitry Andric 
141fcaf7f86SDimitry Andric   if (const CallBase *CB = dyn_cast<CallBase>(Inst)) {
142fcaf7f86SDimitry Andric     if (Value *FreedOp = getFreedOperand(CB, &TLI)) {
1430b57cec5SDimitry Andric       // calls to free() deallocate the entire structure
144fcaf7f86SDimitry Andric       Loc = MemoryLocation::getAfter(FreedOp);
1450b57cec5SDimitry Andric       return ModRefInfo::Mod;
1460b57cec5SDimitry Andric     }
147fcaf7f86SDimitry Andric   }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
1500b57cec5SDimitry Andric     switch (II->getIntrinsicID()) {
1510b57cec5SDimitry Andric     case Intrinsic::lifetime_start:
1520b57cec5SDimitry Andric     case Intrinsic::lifetime_end:
1530b57cec5SDimitry Andric     case Intrinsic::invariant_start:
1540b57cec5SDimitry Andric       Loc = MemoryLocation::getForArgument(II, 1, TLI);
1550b57cec5SDimitry Andric       // These intrinsics don't really modify the memory, but returning Mod
1560b57cec5SDimitry Andric       // will allow them to be handled conservatively.
1570b57cec5SDimitry Andric       return ModRefInfo::Mod;
1580b57cec5SDimitry Andric     case Intrinsic::invariant_end:
1590b57cec5SDimitry Andric       Loc = MemoryLocation::getForArgument(II, 2, TLI);
1600b57cec5SDimitry Andric       // These intrinsics don't really modify the memory, but returning Mod
1610b57cec5SDimitry Andric       // will allow them to be handled conservatively.
1620b57cec5SDimitry Andric       return ModRefInfo::Mod;
163e8d8bef9SDimitry Andric     case Intrinsic::masked_load:
164e8d8bef9SDimitry Andric       Loc = MemoryLocation::getForArgument(II, 0, TLI);
165e8d8bef9SDimitry Andric       return ModRefInfo::Ref;
166e8d8bef9SDimitry Andric     case Intrinsic::masked_store:
167e8d8bef9SDimitry Andric       Loc = MemoryLocation::getForArgument(II, 1, TLI);
168e8d8bef9SDimitry Andric       return ModRefInfo::Mod;
1690b57cec5SDimitry Andric     default:
1700b57cec5SDimitry Andric       break;
1710b57cec5SDimitry Andric     }
1720b57cec5SDimitry Andric   }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   // Otherwise, just do the coarse-grained thing that always works.
1750b57cec5SDimitry Andric   if (Inst->mayWriteToMemory())
1760b57cec5SDimitry Andric     return ModRefInfo::ModRef;
1770b57cec5SDimitry Andric   if (Inst->mayReadFromMemory())
1780b57cec5SDimitry Andric     return ModRefInfo::Ref;
1790b57cec5SDimitry Andric   return ModRefInfo::NoModRef;
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric /// Private helper for finding the local dependencies of a call site.
1830b57cec5SDimitry Andric MemDepResult MemoryDependenceResults::getCallDependencyFrom(
1840b57cec5SDimitry Andric     CallBase *Call, bool isReadOnlyCall, BasicBlock::iterator ScanIt,
1850b57cec5SDimitry Andric     BasicBlock *BB) {
1868bcb0991SDimitry Andric   unsigned Limit = getDefaultBlockScanLimit();
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   // Walk backwards through the block, looking for dependencies.
1890b57cec5SDimitry Andric   while (ScanIt != BB->begin()) {
1900b57cec5SDimitry Andric     Instruction *Inst = &*--ScanIt;
1910b57cec5SDimitry Andric     // Debug intrinsics don't cause dependences and should not affect Limit
1920b57cec5SDimitry Andric     if (isa<DbgInfoIntrinsic>(Inst))
1930b57cec5SDimitry Andric       continue;
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric     // Limit the amount of scanning we do so we don't end up with quadratic
1960b57cec5SDimitry Andric     // running time on extreme testcases.
1970b57cec5SDimitry Andric     --Limit;
1980b57cec5SDimitry Andric     if (!Limit)
1990b57cec5SDimitry Andric       return MemDepResult::getUnknown();
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric     // If this inst is a memory op, get the pointer it accessed
2020b57cec5SDimitry Andric     MemoryLocation Loc;
2030b57cec5SDimitry Andric     ModRefInfo MR = GetLocation(Inst, Loc, TLI);
2040b57cec5SDimitry Andric     if (Loc.Ptr) {
2050b57cec5SDimitry Andric       // A simple instruction.
2060b57cec5SDimitry Andric       if (isModOrRefSet(AA.getModRefInfo(Call, Loc)))
2070b57cec5SDimitry Andric         return MemDepResult::getClobber(Inst);
2080b57cec5SDimitry Andric       continue;
2090b57cec5SDimitry Andric     }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric     if (auto *CallB = dyn_cast<CallBase>(Inst)) {
2120b57cec5SDimitry Andric       // If these two calls do not interfere, look past it.
2130b57cec5SDimitry Andric       if (isNoModRef(AA.getModRefInfo(Call, CallB))) {
2140b57cec5SDimitry Andric         // If the two calls are the same, return Inst as a Def, so that
2150b57cec5SDimitry Andric         // Call can be found redundant and eliminated.
2160b57cec5SDimitry Andric         if (isReadOnlyCall && !isModSet(MR) &&
2170b57cec5SDimitry Andric             Call->isIdenticalToWhenDefined(CallB))
2180b57cec5SDimitry Andric           return MemDepResult::getDef(Inst);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric         // Otherwise if the two calls don't interact (e.g. CallB is readnone)
2210b57cec5SDimitry Andric         // keep scanning.
2220b57cec5SDimitry Andric         continue;
2230b57cec5SDimitry Andric       } else
2240b57cec5SDimitry Andric         return MemDepResult::getClobber(Inst);
2250b57cec5SDimitry Andric     }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric     // If we could not obtain a pointer for the instruction and the instruction
2280b57cec5SDimitry Andric     // touches memory then assume that this is a dependency.
2290b57cec5SDimitry Andric     if (isModOrRefSet(MR))
2300b57cec5SDimitry Andric       return MemDepResult::getClobber(Inst);
2310b57cec5SDimitry Andric   }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   // No dependence found.  If this is the entry block of the function, it is
2340b57cec5SDimitry Andric   // unknown, otherwise it is non-local.
2350b57cec5SDimitry Andric   if (BB != &BB->getParent()->getEntryBlock())
2360b57cec5SDimitry Andric     return MemDepResult::getNonLocal();
2370b57cec5SDimitry Andric   return MemDepResult::getNonFuncLocal();
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
2410b57cec5SDimitry Andric     const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
242fe6060f1SDimitry Andric     BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
243fe6060f1SDimitry Andric     BatchAAResults &BatchAA) {
2440b57cec5SDimitry Andric   MemDepResult InvariantGroupDependency = MemDepResult::getUnknown();
2450b57cec5SDimitry Andric   if (QueryInst != nullptr) {
2460b57cec5SDimitry Andric     if (auto *LI = dyn_cast<LoadInst>(QueryInst)) {
2470b57cec5SDimitry Andric       InvariantGroupDependency = getInvariantGroupPointerDependency(LI, BB);
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric       if (InvariantGroupDependency.isDef())
2500b57cec5SDimitry Andric         return InvariantGroupDependency;
2510b57cec5SDimitry Andric     }
2520b57cec5SDimitry Andric   }
2530b57cec5SDimitry Andric   MemDepResult SimpleDep = getSimplePointerDependencyFrom(
254fe6060f1SDimitry Andric       MemLoc, isLoad, ScanIt, BB, QueryInst, Limit, BatchAA);
2550b57cec5SDimitry Andric   if (SimpleDep.isDef())
2560b57cec5SDimitry Andric     return SimpleDep;
2570b57cec5SDimitry Andric   // Non-local invariant group dependency indicates there is non local Def
2580b57cec5SDimitry Andric   // (it only returns nonLocal if it finds nonLocal def), which is better than
2590b57cec5SDimitry Andric   // local clobber and everything else.
2600b57cec5SDimitry Andric   if (InvariantGroupDependency.isNonLocal())
2610b57cec5SDimitry Andric     return InvariantGroupDependency;
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   assert(InvariantGroupDependency.isUnknown() &&
2640b57cec5SDimitry Andric          "InvariantGroupDependency should be only unknown at this point");
2650b57cec5SDimitry Andric   return SimpleDep;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric 
268fe6060f1SDimitry Andric MemDepResult MemoryDependenceResults::getPointerDependencyFrom(
269fe6060f1SDimitry Andric     const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
270fe6060f1SDimitry Andric     BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) {
2715f757f3fSDimitry Andric   BatchAAResults BatchAA(AA, &EII);
272fe6060f1SDimitry Andric   return getPointerDependencyFrom(MemLoc, isLoad, ScanIt, BB, QueryInst, Limit,
273fe6060f1SDimitry Andric                                   BatchAA);
274fe6060f1SDimitry Andric }
275fe6060f1SDimitry Andric 
2760b57cec5SDimitry Andric MemDepResult
2770b57cec5SDimitry Andric MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,
2780b57cec5SDimitry Andric                                                             BasicBlock *BB) {
2790b57cec5SDimitry Andric 
2808bcb0991SDimitry Andric   if (!LI->hasMetadata(LLVMContext::MD_invariant_group))
2810b57cec5SDimitry Andric     return MemDepResult::getUnknown();
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   // Take the ptr operand after all casts and geps 0. This way we can search
2840b57cec5SDimitry Andric   // cast graph down only.
2850b57cec5SDimitry Andric   Value *LoadOperand = LI->getPointerOperand()->stripPointerCasts();
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   // It's is not safe to walk the use list of global value, because function
2880b57cec5SDimitry Andric   // passes aren't allowed to look outside their functions.
2890b57cec5SDimitry Andric   // FIXME: this could be fixed by filtering instructions from outside
2900b57cec5SDimitry Andric   // of current function.
2910b57cec5SDimitry Andric   if (isa<GlobalValue>(LoadOperand))
2920b57cec5SDimitry Andric     return MemDepResult::getUnknown();
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   // Queue to process all pointers that are equivalent to load operand.
2950b57cec5SDimitry Andric   SmallVector<const Value *, 8> LoadOperandsQueue;
2960b57cec5SDimitry Andric   LoadOperandsQueue.push_back(LoadOperand);
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   Instruction *ClosestDependency = nullptr;
2990b57cec5SDimitry Andric   // Order of instructions in uses list is unpredictible. In order to always
3000b57cec5SDimitry Andric   // get the same result, we will look for the closest dominance.
3010b57cec5SDimitry Andric   auto GetClosestDependency = [this](Instruction *Best, Instruction *Other) {
3020b57cec5SDimitry Andric     assert(Other && "Must call it with not null instruction");
3030b57cec5SDimitry Andric     if (Best == nullptr || DT.dominates(Best, Other))
3040b57cec5SDimitry Andric       return Other;
3050b57cec5SDimitry Andric     return Best;
3060b57cec5SDimitry Andric   };
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   // FIXME: This loop is O(N^2) because dominates can be O(n) and in worst case
3090b57cec5SDimitry Andric   // we will see all the instructions. This should be fixed in MSSA.
3100b57cec5SDimitry Andric   while (!LoadOperandsQueue.empty()) {
3110b57cec5SDimitry Andric     const Value *Ptr = LoadOperandsQueue.pop_back_val();
3120b57cec5SDimitry Andric     assert(Ptr && !isa<GlobalValue>(Ptr) &&
3130b57cec5SDimitry Andric            "Null or GlobalValue should not be inserted");
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric     for (const Use &Us : Ptr->uses()) {
3160b57cec5SDimitry Andric       auto *U = dyn_cast<Instruction>(Us.getUser());
3170b57cec5SDimitry Andric       if (!U || U == LI || !DT.dominates(U, LI))
3180b57cec5SDimitry Andric         continue;
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric       // Bitcast or gep with zeros are using Ptr. Add to queue to check it's
3210b57cec5SDimitry Andric       // users.      U = bitcast Ptr
3220b57cec5SDimitry Andric       if (isa<BitCastInst>(U)) {
3230b57cec5SDimitry Andric         LoadOperandsQueue.push_back(U);
3240b57cec5SDimitry Andric         continue;
3250b57cec5SDimitry Andric       }
3260b57cec5SDimitry Andric       // Gep with zeros is equivalent to bitcast.
3270b57cec5SDimitry Andric       // FIXME: we are not sure if some bitcast should be canonicalized to gep 0
3280b57cec5SDimitry Andric       // or gep 0 to bitcast because of SROA, so there are 2 forms. When
3290b57cec5SDimitry Andric       // typeless pointers will be ready then both cases will be gone
3300b57cec5SDimitry Andric       // (and this BFS also won't be needed).
3310b57cec5SDimitry Andric       if (auto *GEP = dyn_cast<GetElementPtrInst>(U))
3320b57cec5SDimitry Andric         if (GEP->hasAllZeroIndices()) {
3330b57cec5SDimitry Andric           LoadOperandsQueue.push_back(U);
3340b57cec5SDimitry Andric           continue;
3350b57cec5SDimitry Andric         }
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric       // If we hit load/store with the same invariant.group metadata (and the
3380b57cec5SDimitry Andric       // same pointer operand) we can assume that value pointed by pointer
3390b57cec5SDimitry Andric       // operand didn't change.
34023408297SDimitry Andric       if ((isa<LoadInst>(U) ||
34123408297SDimitry Andric            (isa<StoreInst>(U) &&
34223408297SDimitry Andric             cast<StoreInst>(U)->getPointerOperand() == Ptr)) &&
3438bcb0991SDimitry Andric           U->hasMetadata(LLVMContext::MD_invariant_group))
3440b57cec5SDimitry Andric         ClosestDependency = GetClosestDependency(ClosestDependency, U);
3450b57cec5SDimitry Andric     }
3460b57cec5SDimitry Andric   }
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   if (!ClosestDependency)
3490b57cec5SDimitry Andric     return MemDepResult::getUnknown();
3500b57cec5SDimitry Andric   if (ClosestDependency->getParent() == BB)
3510b57cec5SDimitry Andric     return MemDepResult::getDef(ClosestDependency);
3520b57cec5SDimitry Andric   // Def(U) can't be returned here because it is non-local. If local
3530b57cec5SDimitry Andric   // dependency won't be found then return nonLocal counting that the
3540b57cec5SDimitry Andric   // user will call getNonLocalPointerDependency, which will return cached
3550b57cec5SDimitry Andric   // result.
3560b57cec5SDimitry Andric   NonLocalDefsCache.try_emplace(
3570b57cec5SDimitry Andric       LI, NonLocalDepResult(ClosestDependency->getParent(),
3580b57cec5SDimitry Andric                             MemDepResult::getDef(ClosestDependency), nullptr));
3590b57cec5SDimitry Andric   ReverseNonLocalDefsCache[ClosestDependency].insert(LI);
3600b57cec5SDimitry Andric   return MemDepResult::getNonLocal();
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric 
3635f757f3fSDimitry Andric // Check if SI that may alias with MemLoc can be safely skipped. This is
3645f757f3fSDimitry Andric // possible in case if SI can only must alias or no alias with MemLoc (no
3655f757f3fSDimitry Andric // partial overlapping possible) and it writes the same value that MemLoc
3665f757f3fSDimitry Andric // contains now (it was loaded before this store and was not modified in
3675f757f3fSDimitry Andric // between).
3685f757f3fSDimitry Andric static bool canSkipClobberingStore(const StoreInst *SI,
3695f757f3fSDimitry Andric                                    const MemoryLocation &MemLoc,
3705f757f3fSDimitry Andric                                    Align MemLocAlign, BatchAAResults &BatchAA,
3715f757f3fSDimitry Andric                                    unsigned ScanLimit) {
3725f757f3fSDimitry Andric   if (!MemLoc.Size.hasValue())
3735f757f3fSDimitry Andric     return false;
3745f757f3fSDimitry Andric   if (MemoryLocation::get(SI).Size != MemLoc.Size)
3755f757f3fSDimitry Andric     return false;
3765f757f3fSDimitry Andric   if (MemLoc.Size.isScalable())
3775f757f3fSDimitry Andric     return false;
3785f757f3fSDimitry Andric   if (std::min(MemLocAlign, SI->getAlign()).value() <
3795f757f3fSDimitry Andric       MemLoc.Size.getValue().getKnownMinValue())
3805f757f3fSDimitry Andric     return false;
3815f757f3fSDimitry Andric 
3825f757f3fSDimitry Andric   auto *LI = dyn_cast<LoadInst>(SI->getValueOperand());
3835f757f3fSDimitry Andric   if (!LI || LI->getParent() != SI->getParent())
3845f757f3fSDimitry Andric     return false;
3855f757f3fSDimitry Andric   if (BatchAA.alias(MemoryLocation::get(LI), MemLoc) != AliasResult::MustAlias)
3865f757f3fSDimitry Andric     return false;
3875f757f3fSDimitry Andric   unsigned NumVisitedInsts = 0;
3885f757f3fSDimitry Andric   for (const Instruction *I = LI; I != SI; I = I->getNextNonDebugInstruction())
3895f757f3fSDimitry Andric     if (++NumVisitedInsts > ScanLimit ||
3905f757f3fSDimitry Andric         isModSet(BatchAA.getModRefInfo(I, MemLoc)))
3915f757f3fSDimitry Andric       return false;
3925f757f3fSDimitry Andric 
3935f757f3fSDimitry Andric   return true;
3945f757f3fSDimitry Andric }
3955f757f3fSDimitry Andric 
3960b57cec5SDimitry Andric MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(
3970b57cec5SDimitry Andric     const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,
398fe6060f1SDimitry Andric     BasicBlock *BB, Instruction *QueryInst, unsigned *Limit,
399fe6060f1SDimitry Andric     BatchAAResults &BatchAA) {
4000b57cec5SDimitry Andric   bool isInvariantLoad = false;
4015f757f3fSDimitry Andric   Align MemLocAlign =
402*0fca6ea1SDimitry Andric       MemLoc.Ptr->getPointerAlignment(BB->getDataLayout());
4030b57cec5SDimitry Andric 
4048bcb0991SDimitry Andric   unsigned DefaultLimit = getDefaultBlockScanLimit();
4050b57cec5SDimitry Andric   if (!Limit)
4060b57cec5SDimitry Andric     Limit = &DefaultLimit;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   // We must be careful with atomic accesses, as they may allow another thread
4090b57cec5SDimitry Andric   //   to touch this location, clobbering it. We are conservative: if the
4100b57cec5SDimitry Andric   //   QueryInst is not a simple (non-atomic) memory access, we automatically
4110b57cec5SDimitry Andric   //   return getClobber.
4120b57cec5SDimitry Andric   // If it is simple, we know based on the results of
4130b57cec5SDimitry Andric   // "Compiler testing via a theory of sound optimisations in the C11/C++11
4140b57cec5SDimitry Andric   //   memory model" in PLDI 2013, that a non-atomic location can only be
4150b57cec5SDimitry Andric   //   clobbered between a pair of a release and an acquire action, with no
4160b57cec5SDimitry Andric   //   access to the location in between.
4170b57cec5SDimitry Andric   // Here is an example for giving the general intuition behind this rule.
4180b57cec5SDimitry Andric   // In the following code:
4190b57cec5SDimitry Andric   //   store x 0;
4200b57cec5SDimitry Andric   //   release action; [1]
4210b57cec5SDimitry Andric   //   acquire action; [4]
4220b57cec5SDimitry Andric   //   %val = load x;
4230b57cec5SDimitry Andric   // It is unsafe to replace %val by 0 because another thread may be running:
4240b57cec5SDimitry Andric   //   acquire action; [2]
4250b57cec5SDimitry Andric   //   store x 42;
4260b57cec5SDimitry Andric   //   release action; [3]
4270b57cec5SDimitry Andric   // with synchronization from 1 to 2 and from 3 to 4, resulting in %val
4280b57cec5SDimitry Andric   // being 42. A key property of this program however is that if either
4290b57cec5SDimitry Andric   // 1 or 4 were missing, there would be a race between the store of 42
4300b57cec5SDimitry Andric   // either the store of 0 or the load (making the whole program racy).
4310b57cec5SDimitry Andric   // The paper mentioned above shows that the same property is respected
4320b57cec5SDimitry Andric   // by every program that can detect any optimization of that kind: either
4330b57cec5SDimitry Andric   // it is racy (undefined) or there is a release followed by an acquire
4340b57cec5SDimitry Andric   // between the pair of accesses under consideration.
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   // If the load is invariant, we "know" that it doesn't alias *any* write. We
4370b57cec5SDimitry Andric   // do want to respect mustalias results since defs are useful for value
4380b57cec5SDimitry Andric   // forwarding, but any mayalias write can be assumed to be noalias.
4390b57cec5SDimitry Andric   // Arguably, this logic should be pushed inside AliasAnalysis itself.
4405f757f3fSDimitry Andric   if (isLoad && QueryInst)
4415f757f3fSDimitry Andric     if (LoadInst *LI = dyn_cast<LoadInst>(QueryInst)) {
4425f757f3fSDimitry Andric       if (LI->hasMetadata(LLVMContext::MD_invariant_load))
4430b57cec5SDimitry Andric         isInvariantLoad = true;
4445f757f3fSDimitry Andric       MemLocAlign = LI->getAlign();
4450b57cec5SDimitry Andric     }
4460b57cec5SDimitry Andric 
44781ad6265SDimitry Andric   // True for volatile instruction.
44881ad6265SDimitry Andric   // For Load/Store return true if atomic ordering is stronger than AO,
44981ad6265SDimitry Andric   // for other instruction just true if it can read or write to memory.
45081ad6265SDimitry Andric   auto isComplexForReordering = [](Instruction * I, AtomicOrdering AO)->bool {
45181ad6265SDimitry Andric     if (I->isVolatile())
45281ad6265SDimitry Andric       return true;
4530b57cec5SDimitry Andric     if (auto *LI = dyn_cast<LoadInst>(I))
45481ad6265SDimitry Andric       return isStrongerThan(LI->getOrdering(), AO);
4550b57cec5SDimitry Andric     if (auto *SI = dyn_cast<StoreInst>(I))
45681ad6265SDimitry Andric       return isStrongerThan(SI->getOrdering(), AO);
45781ad6265SDimitry Andric     return I->mayReadOrWriteMemory();
4580b57cec5SDimitry Andric   };
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   // Walk backwards through the basic block, looking for dependencies.
4610b57cec5SDimitry Andric   while (ScanIt != BB->begin()) {
4620b57cec5SDimitry Andric     Instruction *Inst = &*--ScanIt;
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst))
4650b57cec5SDimitry Andric       // Debug intrinsics don't (and can't) cause dependencies.
4660b57cec5SDimitry Andric       if (isa<DbgInfoIntrinsic>(II))
4670b57cec5SDimitry Andric         continue;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric     // Limit the amount of scanning we do so we don't end up with quadratic
4700b57cec5SDimitry Andric     // running time on extreme testcases.
4710b57cec5SDimitry Andric     --*Limit;
4720b57cec5SDimitry Andric     if (!*Limit)
4730b57cec5SDimitry Andric       return MemDepResult::getUnknown();
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
4760b57cec5SDimitry Andric       // If we reach a lifetime begin or end marker, then the query ends here
4770b57cec5SDimitry Andric       // because the value is undefined.
478e8d8bef9SDimitry Andric       Intrinsic::ID ID = II->getIntrinsicID();
479e8d8bef9SDimitry Andric       switch (ID) {
480e8d8bef9SDimitry Andric       case Intrinsic::lifetime_start: {
4810b57cec5SDimitry Andric         // FIXME: This only considers queries directly on the invariant-tagged
4820b57cec5SDimitry Andric         // pointer, not on query pointers that are indexed off of them.  It'd
4830b57cec5SDimitry Andric         // be nice to handle that at some point (the right approach is to use
4840b57cec5SDimitry Andric         // GetPointerBaseWithConstantOffset).
485e8d8bef9SDimitry Andric         MemoryLocation ArgLoc = MemoryLocation::getAfter(II->getArgOperand(1));
486e8d8bef9SDimitry Andric         if (BatchAA.isMustAlias(ArgLoc, MemLoc))
4870b57cec5SDimitry Andric           return MemDepResult::getDef(II);
4880b57cec5SDimitry Andric         continue;
4890b57cec5SDimitry Andric       }
490e8d8bef9SDimitry Andric       case Intrinsic::masked_load:
491e8d8bef9SDimitry Andric       case Intrinsic::masked_store: {
492e8d8bef9SDimitry Andric         MemoryLocation Loc;
493e8d8bef9SDimitry Andric         /*ModRefInfo MR =*/ GetLocation(II, Loc, TLI);
494e8d8bef9SDimitry Andric         AliasResult R = BatchAA.alias(Loc, MemLoc);
495fe6060f1SDimitry Andric         if (R == AliasResult::NoAlias)
496e8d8bef9SDimitry Andric           continue;
497fe6060f1SDimitry Andric         if (R == AliasResult::MustAlias)
498e8d8bef9SDimitry Andric           return MemDepResult::getDef(II);
499e8d8bef9SDimitry Andric         if (ID == Intrinsic::masked_load)
500e8d8bef9SDimitry Andric           continue;
501e8d8bef9SDimitry Andric         return MemDepResult::getClobber(II);
502e8d8bef9SDimitry Andric       }
503e8d8bef9SDimitry Andric       }
5040b57cec5SDimitry Andric     }
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric     // Values depend on loads if the pointers are must aliased.  This means
5070b57cec5SDimitry Andric     // that a load depends on another must aliased load from the same value.
5080b57cec5SDimitry Andric     // One exception is atomic loads: a value can depend on an atomic load that
5090b57cec5SDimitry Andric     // it does not alias with when this atomic load indicates that another
5100b57cec5SDimitry Andric     // thread may be accessing the location.
5110b57cec5SDimitry Andric     if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
5120b57cec5SDimitry Andric       // While volatile access cannot be eliminated, they do not have to clobber
5130b57cec5SDimitry Andric       // non-aliasing locations, as normal accesses, for example, can be safely
5140b57cec5SDimitry Andric       // reordered with volatile accesses.
5150b57cec5SDimitry Andric       if (LI->isVolatile()) {
5160b57cec5SDimitry Andric         if (!QueryInst)
5170b57cec5SDimitry Andric           // Original QueryInst *may* be volatile
5180b57cec5SDimitry Andric           return MemDepResult::getClobber(LI);
519fe6060f1SDimitry Andric         if (QueryInst->isVolatile())
5200b57cec5SDimitry Andric           // Ordering required if QueryInst is itself volatile
5210b57cec5SDimitry Andric           return MemDepResult::getClobber(LI);
5220b57cec5SDimitry Andric         // Otherwise, volatile doesn't imply any special ordering
5230b57cec5SDimitry Andric       }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric       // Atomic loads have complications involved.
5260b57cec5SDimitry Andric       // A Monotonic (or higher) load is OK if the query inst is itself not
5270b57cec5SDimitry Andric       // atomic.
5280b57cec5SDimitry Andric       // FIXME: This is overly conservative.
5290b57cec5SDimitry Andric       if (LI->isAtomic() && isStrongerThanUnordered(LI->getOrdering())) {
53081ad6265SDimitry Andric         if (!QueryInst ||
53181ad6265SDimitry Andric             isComplexForReordering(QueryInst, AtomicOrdering::NotAtomic))
5320b57cec5SDimitry Andric           return MemDepResult::getClobber(LI);
5330b57cec5SDimitry Andric         if (LI->getOrdering() != AtomicOrdering::Monotonic)
5340b57cec5SDimitry Andric           return MemDepResult::getClobber(LI);
5350b57cec5SDimitry Andric       }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric       MemoryLocation LoadLoc = MemoryLocation::get(LI);
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric       // If we found a pointer, check if it could be the same as our pointer.
540e8d8bef9SDimitry Andric       AliasResult R = BatchAA.alias(LoadLoc, MemLoc);
5410b57cec5SDimitry Andric 
542fe6060f1SDimitry Andric       if (R == AliasResult::NoAlias)
5430b57cec5SDimitry Andric         continue;
5440b57cec5SDimitry Andric 
54581ad6265SDimitry Andric       if (isLoad) {
5460b57cec5SDimitry Andric         // Must aliased loads are defs of each other.
547fe6060f1SDimitry Andric         if (R == AliasResult::MustAlias)
5480b57cec5SDimitry Andric           return MemDepResult::getDef(Inst);
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric         // If we have a partial alias, then return this as a clobber for the
5510b57cec5SDimitry Andric         // client to handle.
552fe6060f1SDimitry Andric         if (R == AliasResult::PartialAlias && R.hasOffset()) {
553fe6060f1SDimitry Andric           ClobberOffsets[LI] = R.getOffset();
5540b57cec5SDimitry Andric           return MemDepResult::getClobber(Inst);
555fe6060f1SDimitry Andric         }
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric         // Random may-alias loads don't depend on each other without a
5580b57cec5SDimitry Andric         // dependence.
5590b57cec5SDimitry Andric         continue;
5600b57cec5SDimitry Andric       }
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric       // Stores don't alias loads from read-only memory.
563bdd1243dSDimitry Andric       if (!isModSet(BatchAA.getModRefInfoMask(LoadLoc)))
5640b57cec5SDimitry Andric         continue;
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric       // Stores depend on may/must aliased loads.
5670b57cec5SDimitry Andric       return MemDepResult::getDef(Inst);
5680b57cec5SDimitry Andric     }
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric     if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
5710b57cec5SDimitry Andric       // Atomic stores have complications involved.
5720b57cec5SDimitry Andric       // A Monotonic store is OK if the query inst is itself not atomic.
5730b57cec5SDimitry Andric       // FIXME: This is overly conservative.
5740b57cec5SDimitry Andric       if (!SI->isUnordered() && SI->isAtomic()) {
57581ad6265SDimitry Andric         if (!QueryInst ||
57681ad6265SDimitry Andric             isComplexForReordering(QueryInst, AtomicOrdering::Unordered))
5770b57cec5SDimitry Andric           return MemDepResult::getClobber(SI);
57881ad6265SDimitry Andric         // Ok, if we are here the guard above guarantee us that
57981ad6265SDimitry Andric         // QueryInst is a non-atomic or unordered load/store.
58081ad6265SDimitry Andric         // SI is atomic with monotonic or release semantic (seq_cst for store
58181ad6265SDimitry Andric         // is actually a release semantic plus total order over other seq_cst
58281ad6265SDimitry Andric         // instructions, as soon as QueryInst is not seq_cst we can consider it
58381ad6265SDimitry Andric         // as simple release semantic).
58481ad6265SDimitry Andric         // Monotonic and Release semantic allows re-ordering before store
58581ad6265SDimitry Andric         // so we are safe to go further and check the aliasing. It will prohibit
58681ad6265SDimitry Andric         // re-ordering in case locations are may or must alias.
5870b57cec5SDimitry Andric       }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric       // While volatile access cannot be eliminated, they do not have to clobber
5900b57cec5SDimitry Andric       // non-aliasing locations, as normal accesses can for example be reordered
5910b57cec5SDimitry Andric       // with volatile accesses.
5920b57cec5SDimitry Andric       if (SI->isVolatile())
59381ad6265SDimitry Andric         if (!QueryInst || QueryInst->isVolatile())
5940b57cec5SDimitry Andric           return MemDepResult::getClobber(SI);
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric       // If alias analysis can tell that this store is guaranteed to not modify
5970b57cec5SDimitry Andric       // the query pointer, ignore it.  Use getModRefInfo to handle cases where
5980b57cec5SDimitry Andric       // the query pointer points to constant memory etc.
599e8d8bef9SDimitry Andric       if (!isModOrRefSet(BatchAA.getModRefInfo(SI, MemLoc)))
6000b57cec5SDimitry Andric         continue;
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric       // Ok, this store might clobber the query pointer.  Check to see if it is
6030b57cec5SDimitry Andric       // a must alias: in this case, we want to return this as a def.
6040b57cec5SDimitry Andric       // FIXME: Use ModRefInfo::Must bit from getModRefInfo call above.
6050b57cec5SDimitry Andric       MemoryLocation StoreLoc = MemoryLocation::get(SI);
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric       // If we found a pointer, check if it could be the same as our pointer.
608e8d8bef9SDimitry Andric       AliasResult R = BatchAA.alias(StoreLoc, MemLoc);
6090b57cec5SDimitry Andric 
610fe6060f1SDimitry Andric       if (R == AliasResult::NoAlias)
6110b57cec5SDimitry Andric         continue;
612fe6060f1SDimitry Andric       if (R == AliasResult::MustAlias)
6130b57cec5SDimitry Andric         return MemDepResult::getDef(Inst);
6140b57cec5SDimitry Andric       if (isInvariantLoad)
6150b57cec5SDimitry Andric         continue;
6165f757f3fSDimitry Andric       if (canSkipClobberingStore(SI, MemLoc, MemLocAlign, BatchAA, *Limit))
6175f757f3fSDimitry Andric         continue;
6180b57cec5SDimitry Andric       return MemDepResult::getClobber(Inst);
6190b57cec5SDimitry Andric     }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric     // If this is an allocation, and if we know that the accessed pointer is to
6220b57cec5SDimitry Andric     // the allocation, return Def.  This means that there is no dependence and
6230b57cec5SDimitry Andric     // the access can be optimized based on that.  For example, a load could
6240b57cec5SDimitry Andric     // turn into undef.  Note that we can bypass the allocation itself when
6250b57cec5SDimitry Andric     // looking for a clobber in many cases; that's an alias property and is
6260b57cec5SDimitry Andric     // handled by BasicAA.
62704eeddc0SDimitry Andric     if (isa<AllocaInst>(Inst) || isNoAliasCall(Inst)) {
628e8d8bef9SDimitry Andric       const Value *AccessPtr = getUnderlyingObject(MemLoc.Ptr);
629e8d8bef9SDimitry Andric       if (AccessPtr == Inst || BatchAA.isMustAlias(Inst, AccessPtr))
6300b57cec5SDimitry Andric         return MemDepResult::getDef(Inst);
6310b57cec5SDimitry Andric     }
6320b57cec5SDimitry Andric 
633bdd1243dSDimitry Andric     // If we found a select instruction for MemLoc pointer, return it as Def
634bdd1243dSDimitry Andric     // dependency.
635bdd1243dSDimitry Andric     if (isa<SelectInst>(Inst) && MemLoc.Ptr == Inst)
636bdd1243dSDimitry Andric       return MemDepResult::getDef(Inst);
637bdd1243dSDimitry Andric 
6380b57cec5SDimitry Andric     if (isInvariantLoad)
6390b57cec5SDimitry Andric       continue;
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric     // A release fence requires that all stores complete before it, but does
6420b57cec5SDimitry Andric     // not prevent the reordering of following loads or stores 'before' the
6430b57cec5SDimitry Andric     // fence.  As a result, we look past it when finding a dependency for
6440b57cec5SDimitry Andric     // loads.  DSE uses this to find preceding stores to delete and thus we
6450b57cec5SDimitry Andric     // can't bypass the fence if the query instruction is a store.
6460b57cec5SDimitry Andric     if (FenceInst *FI = dyn_cast<FenceInst>(Inst))
6470b57cec5SDimitry Andric       if (isLoad && FI->getOrdering() == AtomicOrdering::Release)
6480b57cec5SDimitry Andric         continue;
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric     // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.
6515f757f3fSDimitry Andric     switch (BatchAA.getModRefInfo(Inst, MemLoc)) {
6520b57cec5SDimitry Andric     case ModRefInfo::NoModRef:
6530b57cec5SDimitry Andric       // If the call has no effect on the queried pointer, just ignore it.
6540b57cec5SDimitry Andric       continue;
6550b57cec5SDimitry Andric     case ModRefInfo::Mod:
6560b57cec5SDimitry Andric       return MemDepResult::getClobber(Inst);
6570b57cec5SDimitry Andric     case ModRefInfo::Ref:
6580b57cec5SDimitry Andric       // If the call is known to never store to the pointer, and if this is a
6590b57cec5SDimitry Andric       // load query, we can safely ignore it (scan past it).
6600b57cec5SDimitry Andric       if (isLoad)
6610b57cec5SDimitry Andric         continue;
662bdd1243dSDimitry Andric       [[fallthrough]];
6630b57cec5SDimitry Andric     default:
6640b57cec5SDimitry Andric       // Otherwise, there is a potential dependence.  Return a clobber.
6650b57cec5SDimitry Andric       return MemDepResult::getClobber(Inst);
6660b57cec5SDimitry Andric     }
6670b57cec5SDimitry Andric   }
6680b57cec5SDimitry Andric 
6690b57cec5SDimitry Andric   // No dependence found.  If this is the entry block of the function, it is
6700b57cec5SDimitry Andric   // unknown, otherwise it is non-local.
6710b57cec5SDimitry Andric   if (BB != &BB->getParent()->getEntryBlock())
6720b57cec5SDimitry Andric     return MemDepResult::getNonLocal();
6730b57cec5SDimitry Andric   return MemDepResult::getNonFuncLocal();
6740b57cec5SDimitry Andric }
6750b57cec5SDimitry Andric 
6765ffd83dbSDimitry Andric MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) {
677fe6060f1SDimitry Andric   ClobberOffsets.clear();
6780b57cec5SDimitry Andric   Instruction *ScanPos = QueryInst;
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric   // Check for a cached result
6810b57cec5SDimitry Andric   MemDepResult &LocalCache = LocalDeps[QueryInst];
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   // If the cached entry is non-dirty, just return it.  Note that this depends
6840b57cec5SDimitry Andric   // on MemDepResult's default constructing to 'dirty'.
6850b57cec5SDimitry Andric   if (!LocalCache.isDirty())
6860b57cec5SDimitry Andric     return LocalCache;
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   // Otherwise, if we have a dirty entry, we know we can start the scan at that
6890b57cec5SDimitry Andric   // instruction, which may save us some work.
6900b57cec5SDimitry Andric   if (Instruction *Inst = LocalCache.getInst()) {
6910b57cec5SDimitry Andric     ScanPos = Inst;
6920b57cec5SDimitry Andric 
6930b57cec5SDimitry Andric     RemoveFromReverseMap(ReverseLocalDeps, Inst, QueryInst);
6940b57cec5SDimitry Andric   }
6950b57cec5SDimitry Andric 
6960b57cec5SDimitry Andric   BasicBlock *QueryParent = QueryInst->getParent();
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   // Do the scan.
6990b57cec5SDimitry Andric   if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
7000b57cec5SDimitry Andric     // No dependence found. If this is the entry block of the function, it is
7010b57cec5SDimitry Andric     // unknown, otherwise it is non-local.
7020b57cec5SDimitry Andric     if (QueryParent != &QueryParent->getParent()->getEntryBlock())
7030b57cec5SDimitry Andric       LocalCache = MemDepResult::getNonLocal();
7040b57cec5SDimitry Andric     else
7050b57cec5SDimitry Andric       LocalCache = MemDepResult::getNonFuncLocal();
7060b57cec5SDimitry Andric   } else {
7070b57cec5SDimitry Andric     MemoryLocation MemLoc;
7080b57cec5SDimitry Andric     ModRefInfo MR = GetLocation(QueryInst, MemLoc, TLI);
7090b57cec5SDimitry Andric     if (MemLoc.Ptr) {
7100b57cec5SDimitry Andric       // If we can do a pointer scan, make it happen.
7110b57cec5SDimitry Andric       bool isLoad = !isModSet(MR);
7120b57cec5SDimitry Andric       if (auto *II = dyn_cast<IntrinsicInst>(QueryInst))
7130b57cec5SDimitry Andric         isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start;
7140b57cec5SDimitry Andric 
7150b57cec5SDimitry Andric       LocalCache =
7160b57cec5SDimitry Andric           getPointerDependencyFrom(MemLoc, isLoad, ScanPos->getIterator(),
7175ffd83dbSDimitry Andric                                    QueryParent, QueryInst, nullptr);
7180b57cec5SDimitry Andric     } else if (auto *QueryCall = dyn_cast<CallBase>(QueryInst)) {
7190b57cec5SDimitry Andric       bool isReadOnly = AA.onlyReadsMemory(QueryCall);
7200b57cec5SDimitry Andric       LocalCache = getCallDependencyFrom(QueryCall, isReadOnly,
7210b57cec5SDimitry Andric                                          ScanPos->getIterator(), QueryParent);
7220b57cec5SDimitry Andric     } else
7230b57cec5SDimitry Andric       // Non-memory instruction.
7240b57cec5SDimitry Andric       LocalCache = MemDepResult::getUnknown();
7250b57cec5SDimitry Andric   }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   // Remember the result!
7280b57cec5SDimitry Andric   if (Instruction *I = LocalCache.getInst())
7290b57cec5SDimitry Andric     ReverseLocalDeps[I].insert(QueryInst);
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   return LocalCache;
7320b57cec5SDimitry Andric }
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric #ifndef NDEBUG
7350b57cec5SDimitry Andric /// This method is used when -debug is specified to verify that cache arrays
7360b57cec5SDimitry Andric /// are properly kept sorted.
7370b57cec5SDimitry Andric static void AssertSorted(MemoryDependenceResults::NonLocalDepInfo &Cache,
7380b57cec5SDimitry Andric                          int Count = -1) {
7390b57cec5SDimitry Andric   if (Count == -1)
7400b57cec5SDimitry Andric     Count = Cache.size();
7410b57cec5SDimitry Andric   assert(std::is_sorted(Cache.begin(), Cache.begin() + Count) &&
7420b57cec5SDimitry Andric          "Cache isn't sorted!");
7430b57cec5SDimitry Andric }
7440b57cec5SDimitry Andric #endif
7450b57cec5SDimitry Andric 
7460b57cec5SDimitry Andric const MemoryDependenceResults::NonLocalDepInfo &
7470b57cec5SDimitry Andric MemoryDependenceResults::getNonLocalCallDependency(CallBase *QueryCall) {
7480b57cec5SDimitry Andric   assert(getDependency(QueryCall).isNonLocal() &&
7490b57cec5SDimitry Andric          "getNonLocalCallDependency should only be used on calls with "
7500b57cec5SDimitry Andric          "non-local deps!");
751fe6060f1SDimitry Andric   PerInstNLInfo &CacheP = NonLocalDepsMap[QueryCall];
7520b57cec5SDimitry Andric   NonLocalDepInfo &Cache = CacheP.first;
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric   // This is the set of blocks that need to be recomputed.  In the cached case,
7550b57cec5SDimitry Andric   // this can happen due to instructions being deleted etc. In the uncached
7560b57cec5SDimitry Andric   // case, this starts out as the set of predecessors we care about.
7570b57cec5SDimitry Andric   SmallVector<BasicBlock *, 32> DirtyBlocks;
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric   if (!Cache.empty()) {
7600b57cec5SDimitry Andric     // Okay, we have a cache entry.  If we know it is not dirty, just return it
7610b57cec5SDimitry Andric     // with no computation.
7620b57cec5SDimitry Andric     if (!CacheP.second) {
7630b57cec5SDimitry Andric       ++NumCacheNonLocal;
7640b57cec5SDimitry Andric       return Cache;
7650b57cec5SDimitry Andric     }
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric     // If we already have a partially computed set of results, scan them to
7680b57cec5SDimitry Andric     // determine what is dirty, seeding our initial DirtyBlocks worklist.
7690b57cec5SDimitry Andric     for (auto &Entry : Cache)
7700b57cec5SDimitry Andric       if (Entry.getResult().isDirty())
7710b57cec5SDimitry Andric         DirtyBlocks.push_back(Entry.getBB());
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric     // Sort the cache so that we can do fast binary search lookups below.
7740b57cec5SDimitry Andric     llvm::sort(Cache);
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric     ++NumCacheDirtyNonLocal;
7770b57cec5SDimitry Andric   } else {
7780b57cec5SDimitry Andric     // Seed DirtyBlocks with each of the preds of QueryInst's block.
7790b57cec5SDimitry Andric     BasicBlock *QueryBB = QueryCall->getParent();
780e8d8bef9SDimitry Andric     append_range(DirtyBlocks, PredCache.get(QueryBB));
7810b57cec5SDimitry Andric     ++NumUncacheNonLocal;
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric   // isReadonlyCall - If this is a read-only call, we can be more aggressive.
7850b57cec5SDimitry Andric   bool isReadonlyCall = AA.onlyReadsMemory(QueryCall);
7860b57cec5SDimitry Andric 
7870b57cec5SDimitry Andric   SmallPtrSet<BasicBlock *, 32> Visited;
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric   unsigned NumSortedEntries = Cache.size();
7900b57cec5SDimitry Andric   LLVM_DEBUG(AssertSorted(Cache));
7910b57cec5SDimitry Andric 
7920b57cec5SDimitry Andric   // Iterate while we still have blocks to update.
7930b57cec5SDimitry Andric   while (!DirtyBlocks.empty()) {
794e8d8bef9SDimitry Andric     BasicBlock *DirtyBB = DirtyBlocks.pop_back_val();
7950b57cec5SDimitry Andric 
7960b57cec5SDimitry Andric     // Already processed this block?
7970b57cec5SDimitry Andric     if (!Visited.insert(DirtyBB).second)
7980b57cec5SDimitry Andric       continue;
7990b57cec5SDimitry Andric 
8000b57cec5SDimitry Andric     // Do a binary search to see if we already have an entry for this block in
8010b57cec5SDimitry Andric     // the cache set.  If so, find it.
8020b57cec5SDimitry Andric     LLVM_DEBUG(AssertSorted(Cache, NumSortedEntries));
8030b57cec5SDimitry Andric     NonLocalDepInfo::iterator Entry =
8040b57cec5SDimitry Andric         std::upper_bound(Cache.begin(), Cache.begin() + NumSortedEntries,
8050b57cec5SDimitry Andric                          NonLocalDepEntry(DirtyBB));
8060b57cec5SDimitry Andric     if (Entry != Cache.begin() && std::prev(Entry)->getBB() == DirtyBB)
8070b57cec5SDimitry Andric       --Entry;
8080b57cec5SDimitry Andric 
8090b57cec5SDimitry Andric     NonLocalDepEntry *ExistingResult = nullptr;
8100b57cec5SDimitry Andric     if (Entry != Cache.begin() + NumSortedEntries &&
8110b57cec5SDimitry Andric         Entry->getBB() == DirtyBB) {
8120b57cec5SDimitry Andric       // If we already have an entry, and if it isn't already dirty, the block
8130b57cec5SDimitry Andric       // is done.
8140b57cec5SDimitry Andric       if (!Entry->getResult().isDirty())
8150b57cec5SDimitry Andric         continue;
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric       // Otherwise, remember this slot so we can update the value.
8180b57cec5SDimitry Andric       ExistingResult = &*Entry;
8190b57cec5SDimitry Andric     }
8200b57cec5SDimitry Andric 
8210b57cec5SDimitry Andric     // If the dirty entry has a pointer, start scanning from it so we don't have
8220b57cec5SDimitry Andric     // to rescan the entire block.
8230b57cec5SDimitry Andric     BasicBlock::iterator ScanPos = DirtyBB->end();
8240b57cec5SDimitry Andric     if (ExistingResult) {
8250b57cec5SDimitry Andric       if (Instruction *Inst = ExistingResult->getResult().getInst()) {
8260b57cec5SDimitry Andric         ScanPos = Inst->getIterator();
8270b57cec5SDimitry Andric         // We're removing QueryInst's use of Inst.
8280b57cec5SDimitry Andric         RemoveFromReverseMap<Instruction *>(ReverseNonLocalDeps, Inst,
8290b57cec5SDimitry Andric                                             QueryCall);
8300b57cec5SDimitry Andric       }
8310b57cec5SDimitry Andric     }
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric     // Find out if this block has a local dependency for QueryInst.
8340b57cec5SDimitry Andric     MemDepResult Dep;
8350b57cec5SDimitry Andric 
8360b57cec5SDimitry Andric     if (ScanPos != DirtyBB->begin()) {
8370b57cec5SDimitry Andric       Dep = getCallDependencyFrom(QueryCall, isReadonlyCall, ScanPos, DirtyBB);
8380b57cec5SDimitry Andric     } else if (DirtyBB != &DirtyBB->getParent()->getEntryBlock()) {
8390b57cec5SDimitry Andric       // No dependence found.  If this is the entry block of the function, it is
8400b57cec5SDimitry Andric       // a clobber, otherwise it is unknown.
8410b57cec5SDimitry Andric       Dep = MemDepResult::getNonLocal();
8420b57cec5SDimitry Andric     } else {
8430b57cec5SDimitry Andric       Dep = MemDepResult::getNonFuncLocal();
8440b57cec5SDimitry Andric     }
8450b57cec5SDimitry Andric 
8460b57cec5SDimitry Andric     // If we had a dirty entry for the block, update it.  Otherwise, just add
8470b57cec5SDimitry Andric     // a new entry.
8480b57cec5SDimitry Andric     if (ExistingResult)
8490b57cec5SDimitry Andric       ExistingResult->setResult(Dep);
8500b57cec5SDimitry Andric     else
8510b57cec5SDimitry Andric       Cache.push_back(NonLocalDepEntry(DirtyBB, Dep));
8520b57cec5SDimitry Andric 
8530b57cec5SDimitry Andric     // If the block has a dependency (i.e. it isn't completely transparent to
8540b57cec5SDimitry Andric     // the value), remember the association!
8550b57cec5SDimitry Andric     if (!Dep.isNonLocal()) {
8560b57cec5SDimitry Andric       // Keep the ReverseNonLocalDeps map up to date so we can efficiently
8570b57cec5SDimitry Andric       // update this when we remove instructions.
8580b57cec5SDimitry Andric       if (Instruction *Inst = Dep.getInst())
8590b57cec5SDimitry Andric         ReverseNonLocalDeps[Inst].insert(QueryCall);
8600b57cec5SDimitry Andric     } else {
8610b57cec5SDimitry Andric 
8620b57cec5SDimitry Andric       // If the block *is* completely transparent to the load, we need to check
8630b57cec5SDimitry Andric       // the predecessors of this block.  Add them to our worklist.
864e8d8bef9SDimitry Andric       append_range(DirtyBlocks, PredCache.get(DirtyBB));
8650b57cec5SDimitry Andric     }
8660b57cec5SDimitry Andric   }
8670b57cec5SDimitry Andric 
8680b57cec5SDimitry Andric   return Cache;
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric 
8710b57cec5SDimitry Andric void MemoryDependenceResults::getNonLocalPointerDependency(
8720b57cec5SDimitry Andric     Instruction *QueryInst, SmallVectorImpl<NonLocalDepResult> &Result) {
8730b57cec5SDimitry Andric   const MemoryLocation Loc = MemoryLocation::get(QueryInst);
8740b57cec5SDimitry Andric   bool isLoad = isa<LoadInst>(QueryInst);
8750b57cec5SDimitry Andric   BasicBlock *FromBB = QueryInst->getParent();
8760b57cec5SDimitry Andric   assert(FromBB);
8770b57cec5SDimitry Andric 
8780b57cec5SDimitry Andric   assert(Loc.Ptr->getType()->isPointerTy() &&
8790b57cec5SDimitry Andric          "Can't get pointer deps of a non-pointer!");
8800b57cec5SDimitry Andric   Result.clear();
8810b57cec5SDimitry Andric   {
8820b57cec5SDimitry Andric     // Check if there is cached Def with invariant.group.
8830b57cec5SDimitry Andric     auto NonLocalDefIt = NonLocalDefsCache.find(QueryInst);
8840b57cec5SDimitry Andric     if (NonLocalDefIt != NonLocalDefsCache.end()) {
8850b57cec5SDimitry Andric       Result.push_back(NonLocalDefIt->second);
8860b57cec5SDimitry Andric       ReverseNonLocalDefsCache[NonLocalDefIt->second.getResult().getInst()]
8870b57cec5SDimitry Andric           .erase(QueryInst);
8880b57cec5SDimitry Andric       NonLocalDefsCache.erase(NonLocalDefIt);
8890b57cec5SDimitry Andric       return;
8900b57cec5SDimitry Andric     }
8910b57cec5SDimitry Andric   }
8920b57cec5SDimitry Andric   // This routine does not expect to deal with volatile instructions.
8930b57cec5SDimitry Andric   // Doing so would require piping through the QueryInst all the way through.
8940b57cec5SDimitry Andric   // TODO: volatiles can't be elided, but they can be reordered with other
8950b57cec5SDimitry Andric   // non-volatile accesses.
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric   // We currently give up on any instruction which is ordered, but we do handle
8980b57cec5SDimitry Andric   // atomic instructions which are unordered.
8990b57cec5SDimitry Andric   // TODO: Handle ordered instructions
9000b57cec5SDimitry Andric   auto isOrdered = [](Instruction *Inst) {
9010b57cec5SDimitry Andric     if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
9020b57cec5SDimitry Andric       return !LI->isUnordered();
9030b57cec5SDimitry Andric     } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
9040b57cec5SDimitry Andric       return !SI->isUnordered();
9050b57cec5SDimitry Andric     }
9060b57cec5SDimitry Andric     return false;
9070b57cec5SDimitry Andric   };
908fe6060f1SDimitry Andric   if (QueryInst->isVolatile() || isOrdered(QueryInst)) {
9090b57cec5SDimitry Andric     Result.push_back(NonLocalDepResult(FromBB, MemDepResult::getUnknown(),
9100b57cec5SDimitry Andric                                        const_cast<Value *>(Loc.Ptr)));
9110b57cec5SDimitry Andric     return;
9120b57cec5SDimitry Andric   }
913*0fca6ea1SDimitry Andric   const DataLayout &DL = FromBB->getDataLayout();
9140b57cec5SDimitry Andric   PHITransAddr Address(const_cast<Value *>(Loc.Ptr), DL, &AC);
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   // This is the set of blocks we've inspected, and the pointer we consider in
9170b57cec5SDimitry Andric   // each block.  Because of critical edges, we currently bail out if querying
9180b57cec5SDimitry Andric   // a block with multiple different pointers.  This can happen during PHI
9190b57cec5SDimitry Andric   // translation.
9200b57cec5SDimitry Andric   DenseMap<BasicBlock *, Value *> Visited;
9210b57cec5SDimitry Andric   if (getNonLocalPointerDepFromBB(QueryInst, Address, Loc, isLoad, FromBB,
9220b57cec5SDimitry Andric                                    Result, Visited, true))
9230b57cec5SDimitry Andric     return;
9240b57cec5SDimitry Andric   Result.clear();
9250b57cec5SDimitry Andric   Result.push_back(NonLocalDepResult(FromBB, MemDepResult::getUnknown(),
9260b57cec5SDimitry Andric                                      const_cast<Value *>(Loc.Ptr)));
9270b57cec5SDimitry Andric }
9280b57cec5SDimitry Andric 
9290b57cec5SDimitry Andric /// Compute the memdep value for BB with Pointer/PointeeSize using either
9300b57cec5SDimitry Andric /// cached information in Cache or by doing a lookup (which may use dirty cache
9310b57cec5SDimitry Andric /// info if available).
9320b57cec5SDimitry Andric ///
9330b57cec5SDimitry Andric /// If we do a lookup, add the result to the cache.
934fe6060f1SDimitry Andric MemDepResult MemoryDependenceResults::getNonLocalInfoForBlock(
9350b57cec5SDimitry Andric     Instruction *QueryInst, const MemoryLocation &Loc, bool isLoad,
936fe6060f1SDimitry Andric     BasicBlock *BB, NonLocalDepInfo *Cache, unsigned NumSortedEntries,
937fe6060f1SDimitry Andric     BatchAAResults &BatchAA) {
9380b57cec5SDimitry Andric 
9395ffd83dbSDimitry Andric   bool isInvariantLoad = false;
9405ffd83dbSDimitry Andric 
9415ffd83dbSDimitry Andric   if (LoadInst *LI = dyn_cast_or_null<LoadInst>(QueryInst))
9425ffd83dbSDimitry Andric     isInvariantLoad = LI->getMetadata(LLVMContext::MD_invariant_load);
9435ffd83dbSDimitry Andric 
9440b57cec5SDimitry Andric   // Do a binary search to see if we already have an entry for this block in
9450b57cec5SDimitry Andric   // the cache set.  If so, find it.
9460b57cec5SDimitry Andric   NonLocalDepInfo::iterator Entry = std::upper_bound(
9470b57cec5SDimitry Andric       Cache->begin(), Cache->begin() + NumSortedEntries, NonLocalDepEntry(BB));
9480b57cec5SDimitry Andric   if (Entry != Cache->begin() && (Entry - 1)->getBB() == BB)
9490b57cec5SDimitry Andric     --Entry;
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric   NonLocalDepEntry *ExistingResult = nullptr;
9520b57cec5SDimitry Andric   if (Entry != Cache->begin() + NumSortedEntries && Entry->getBB() == BB)
9530b57cec5SDimitry Andric     ExistingResult = &*Entry;
9540b57cec5SDimitry Andric 
9555ffd83dbSDimitry Andric   // Use cached result for invariant load only if there is no dependency for non
9565ffd83dbSDimitry Andric   // invariant load. In this case invariant load can not have any dependency as
9575ffd83dbSDimitry Andric   // well.
9585ffd83dbSDimitry Andric   if (ExistingResult && isInvariantLoad &&
9595ffd83dbSDimitry Andric       !ExistingResult->getResult().isNonFuncLocal())
9605ffd83dbSDimitry Andric     ExistingResult = nullptr;
9615ffd83dbSDimitry Andric 
9620b57cec5SDimitry Andric   // If we have a cached entry, and it is non-dirty, use it as the value for
9630b57cec5SDimitry Andric   // this dependency.
9640b57cec5SDimitry Andric   if (ExistingResult && !ExistingResult->getResult().isDirty()) {
9650b57cec5SDimitry Andric     ++NumCacheNonLocalPtr;
9660b57cec5SDimitry Andric     return ExistingResult->getResult();
9670b57cec5SDimitry Andric   }
9680b57cec5SDimitry Andric 
9690b57cec5SDimitry Andric   // Otherwise, we have to scan for the value.  If we have a dirty cache
9700b57cec5SDimitry Andric   // entry, start scanning from its position, otherwise we scan from the end
9710b57cec5SDimitry Andric   // of the block.
9720b57cec5SDimitry Andric   BasicBlock::iterator ScanPos = BB->end();
9730b57cec5SDimitry Andric   if (ExistingResult && ExistingResult->getResult().getInst()) {
9740b57cec5SDimitry Andric     assert(ExistingResult->getResult().getInst()->getParent() == BB &&
9750b57cec5SDimitry Andric            "Instruction invalidated?");
9760b57cec5SDimitry Andric     ++NumCacheDirtyNonLocalPtr;
9770b57cec5SDimitry Andric     ScanPos = ExistingResult->getResult().getInst()->getIterator();
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric     // Eliminating the dirty entry from 'Cache', so update the reverse info.
9800b57cec5SDimitry Andric     ValueIsLoadPair CacheKey(Loc.Ptr, isLoad);
9810b57cec5SDimitry Andric     RemoveFromReverseMap(ReverseNonLocalPtrDeps, &*ScanPos, CacheKey);
9820b57cec5SDimitry Andric   } else {
9830b57cec5SDimitry Andric     ++NumUncacheNonLocalPtr;
9840b57cec5SDimitry Andric   }
9850b57cec5SDimitry Andric 
9860b57cec5SDimitry Andric   // Scan the block for the dependency.
987fe6060f1SDimitry Andric   MemDepResult Dep = getPointerDependencyFrom(Loc, isLoad, ScanPos, BB,
988fe6060f1SDimitry Andric                                               QueryInst, nullptr, BatchAA);
9890b57cec5SDimitry Andric 
9905ffd83dbSDimitry Andric   // Don't cache results for invariant load.
9915ffd83dbSDimitry Andric   if (isInvariantLoad)
9925ffd83dbSDimitry Andric     return Dep;
9935ffd83dbSDimitry Andric 
9940b57cec5SDimitry Andric   // If we had a dirty entry for the block, update it.  Otherwise, just add
9950b57cec5SDimitry Andric   // a new entry.
9960b57cec5SDimitry Andric   if (ExistingResult)
9970b57cec5SDimitry Andric     ExistingResult->setResult(Dep);
9980b57cec5SDimitry Andric   else
9990b57cec5SDimitry Andric     Cache->push_back(NonLocalDepEntry(BB, Dep));
10000b57cec5SDimitry Andric 
10010b57cec5SDimitry Andric   // If the block has a dependency (i.e. it isn't completely transparent to
10020b57cec5SDimitry Andric   // the value), remember the reverse association because we just added it
10030b57cec5SDimitry Andric   // to Cache!
1004bdd1243dSDimitry Andric   if (!Dep.isLocal())
10050b57cec5SDimitry Andric     return Dep;
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric   // Keep the ReverseNonLocalPtrDeps map up to date so we can efficiently
10080b57cec5SDimitry Andric   // update MemDep when we remove instructions.
10090b57cec5SDimitry Andric   Instruction *Inst = Dep.getInst();
10100b57cec5SDimitry Andric   assert(Inst && "Didn't depend on anything?");
10110b57cec5SDimitry Andric   ValueIsLoadPair CacheKey(Loc.Ptr, isLoad);
10120b57cec5SDimitry Andric   ReverseNonLocalPtrDeps[Inst].insert(CacheKey);
10130b57cec5SDimitry Andric   return Dep;
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric /// Sort the NonLocalDepInfo cache, given a certain number of elements in the
10170b57cec5SDimitry Andric /// array that are already properly ordered.
10180b57cec5SDimitry Andric ///
10190b57cec5SDimitry Andric /// This is optimized for the case when only a few entries are added.
10200b57cec5SDimitry Andric static void
10210b57cec5SDimitry Andric SortNonLocalDepInfoCache(MemoryDependenceResults::NonLocalDepInfo &Cache,
10220b57cec5SDimitry Andric                          unsigned NumSortedEntries) {
10230b57cec5SDimitry Andric   switch (Cache.size() - NumSortedEntries) {
10240b57cec5SDimitry Andric   case 0:
10250b57cec5SDimitry Andric     // done, no new entries.
10260b57cec5SDimitry Andric     break;
10270b57cec5SDimitry Andric   case 2: {
10280b57cec5SDimitry Andric     // Two new entries, insert the last one into place.
10290b57cec5SDimitry Andric     NonLocalDepEntry Val = Cache.back();
10300b57cec5SDimitry Andric     Cache.pop_back();
10310b57cec5SDimitry Andric     MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
10320b57cec5SDimitry Andric         std::upper_bound(Cache.begin(), Cache.end() - 1, Val);
10330b57cec5SDimitry Andric     Cache.insert(Entry, Val);
1034bdd1243dSDimitry Andric     [[fallthrough]];
10350b57cec5SDimitry Andric   }
10360b57cec5SDimitry Andric   case 1:
10370b57cec5SDimitry Andric     // One new entry, Just insert the new value at the appropriate position.
10380b57cec5SDimitry Andric     if (Cache.size() != 1) {
10390b57cec5SDimitry Andric       NonLocalDepEntry Val = Cache.back();
10400b57cec5SDimitry Andric       Cache.pop_back();
10410b57cec5SDimitry Andric       MemoryDependenceResults::NonLocalDepInfo::iterator Entry =
1042e8d8bef9SDimitry Andric           llvm::upper_bound(Cache, Val);
10430b57cec5SDimitry Andric       Cache.insert(Entry, Val);
10440b57cec5SDimitry Andric     }
10450b57cec5SDimitry Andric     break;
10460b57cec5SDimitry Andric   default:
10470b57cec5SDimitry Andric     // Added many values, do a full scale sort.
10480b57cec5SDimitry Andric     llvm::sort(Cache);
10490b57cec5SDimitry Andric     break;
10500b57cec5SDimitry Andric   }
10510b57cec5SDimitry Andric }
10520b57cec5SDimitry Andric 
10530b57cec5SDimitry Andric /// Perform a dependency query based on pointer/pointeesize starting at the end
10540b57cec5SDimitry Andric /// of StartBB.
10550b57cec5SDimitry Andric ///
10560b57cec5SDimitry Andric /// Add any clobber/def results to the results vector and keep track of which
10570b57cec5SDimitry Andric /// blocks are visited in 'Visited'.
10580b57cec5SDimitry Andric ///
10590b57cec5SDimitry Andric /// This has special behavior for the first block queries (when SkipFirstBlock
10600b57cec5SDimitry Andric /// is true).  In this special case, it ignores the contents of the specified
10610b57cec5SDimitry Andric /// block and starts returning dependence info for its predecessors.
10620b57cec5SDimitry Andric ///
10630b57cec5SDimitry Andric /// This function returns true on success, or false to indicate that it could
10640b57cec5SDimitry Andric /// not compute dependence information for some reason.  This should be treated
10650b57cec5SDimitry Andric /// as a clobber dependence on the first instruction in the predecessor block.
10660b57cec5SDimitry Andric bool MemoryDependenceResults::getNonLocalPointerDepFromBB(
10670b57cec5SDimitry Andric     Instruction *QueryInst, const PHITransAddr &Pointer,
10680b57cec5SDimitry Andric     const MemoryLocation &Loc, bool isLoad, BasicBlock *StartBB,
10690b57cec5SDimitry Andric     SmallVectorImpl<NonLocalDepResult> &Result,
10705ffd83dbSDimitry Andric     DenseMap<BasicBlock *, Value *> &Visited, bool SkipFirstBlock,
10715ffd83dbSDimitry Andric     bool IsIncomplete) {
10720b57cec5SDimitry Andric   // Look up the cached info for Pointer.
10730b57cec5SDimitry Andric   ValueIsLoadPair CacheKey(Pointer.getAddr(), isLoad);
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric   // Set up a temporary NLPI value. If the map doesn't yet have an entry for
10760b57cec5SDimitry Andric   // CacheKey, this value will be inserted as the associated value. Otherwise,
10770b57cec5SDimitry Andric   // it'll be ignored, and we'll have to check to see if the cached size and
10780b57cec5SDimitry Andric   // aa tags are consistent with the current query.
10790b57cec5SDimitry Andric   NonLocalPointerInfo InitialNLPI;
10800b57cec5SDimitry Andric   InitialNLPI.Size = Loc.Size;
10810b57cec5SDimitry Andric   InitialNLPI.AATags = Loc.AATags;
10820b57cec5SDimitry Andric 
10835ffd83dbSDimitry Andric   bool isInvariantLoad = false;
10845ffd83dbSDimitry Andric   if (LoadInst *LI = dyn_cast_or_null<LoadInst>(QueryInst))
10855ffd83dbSDimitry Andric     isInvariantLoad = LI->getMetadata(LLVMContext::MD_invariant_load);
10865ffd83dbSDimitry Andric 
10870b57cec5SDimitry Andric   // Get the NLPI for CacheKey, inserting one into the map if it doesn't
10880b57cec5SDimitry Andric   // already have one.
10890b57cec5SDimitry Andric   std::pair<CachedNonLocalPointerInfo::iterator, bool> Pair =
10900b57cec5SDimitry Andric       NonLocalPointerDeps.insert(std::make_pair(CacheKey, InitialNLPI));
10910b57cec5SDimitry Andric   NonLocalPointerInfo *CacheInfo = &Pair.first->second;
10920b57cec5SDimitry Andric 
10930b57cec5SDimitry Andric   // If we already have a cache entry for this CacheKey, we may need to do some
10940b57cec5SDimitry Andric   // work to reconcile the cache entry and the current query.
10955ffd83dbSDimitry Andric   // Invariant loads don't participate in caching. Thus no need to reconcile.
10965ffd83dbSDimitry Andric   if (!isInvariantLoad && !Pair.second) {
10970b57cec5SDimitry Andric     if (CacheInfo->Size != Loc.Size) {
10980b57cec5SDimitry Andric       bool ThrowOutEverything;
10990b57cec5SDimitry Andric       if (CacheInfo->Size.hasValue() && Loc.Size.hasValue()) {
11000b57cec5SDimitry Andric         // FIXME: We may be able to do better in the face of results with mixed
11010b57cec5SDimitry Andric         // precision. We don't appear to get them in practice, though, so just
11020b57cec5SDimitry Andric         // be conservative.
11030b57cec5SDimitry Andric         ThrowOutEverything =
11040b57cec5SDimitry Andric             CacheInfo->Size.isPrecise() != Loc.Size.isPrecise() ||
11055f757f3fSDimitry Andric             !TypeSize::isKnownGE(CacheInfo->Size.getValue(),
11065f757f3fSDimitry Andric                                  Loc.Size.getValue());
11070b57cec5SDimitry Andric       } else {
11080b57cec5SDimitry Andric         // For our purposes, unknown size > all others.
11090b57cec5SDimitry Andric         ThrowOutEverything = !Loc.Size.hasValue();
11100b57cec5SDimitry Andric       }
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric       if (ThrowOutEverything) {
11130b57cec5SDimitry Andric         // The query's Size is greater than the cached one. Throw out the
11140b57cec5SDimitry Andric         // cached data and proceed with the query at the greater size.
11150b57cec5SDimitry Andric         CacheInfo->Pair = BBSkipFirstBlockPair();
11160b57cec5SDimitry Andric         CacheInfo->Size = Loc.Size;
11170b57cec5SDimitry Andric         for (auto &Entry : CacheInfo->NonLocalDeps)
11180b57cec5SDimitry Andric           if (Instruction *Inst = Entry.getResult().getInst())
11190b57cec5SDimitry Andric             RemoveFromReverseMap(ReverseNonLocalPtrDeps, Inst, CacheKey);
11200b57cec5SDimitry Andric         CacheInfo->NonLocalDeps.clear();
11215ffd83dbSDimitry Andric         // The cache is cleared (in the above line) so we will have lost
11225ffd83dbSDimitry Andric         // information about blocks we have already visited. We therefore must
11235ffd83dbSDimitry Andric         // assume that the cache information is incomplete.
11245ffd83dbSDimitry Andric         IsIncomplete = true;
11250b57cec5SDimitry Andric       } else {
11260b57cec5SDimitry Andric         // This query's Size is less than the cached one. Conservatively restart
11270b57cec5SDimitry Andric         // the query using the greater size.
11280b57cec5SDimitry Andric         return getNonLocalPointerDepFromBB(
11290b57cec5SDimitry Andric             QueryInst, Pointer, Loc.getWithNewSize(CacheInfo->Size), isLoad,
11305ffd83dbSDimitry Andric             StartBB, Result, Visited, SkipFirstBlock, IsIncomplete);
11310b57cec5SDimitry Andric       }
11320b57cec5SDimitry Andric     }
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric     // If the query's AATags are inconsistent with the cached one,
11350b57cec5SDimitry Andric     // conservatively throw out the cached data and restart the query with
11360b57cec5SDimitry Andric     // no tag if needed.
11370b57cec5SDimitry Andric     if (CacheInfo->AATags != Loc.AATags) {
11380b57cec5SDimitry Andric       if (CacheInfo->AATags) {
11390b57cec5SDimitry Andric         CacheInfo->Pair = BBSkipFirstBlockPair();
11400b57cec5SDimitry Andric         CacheInfo->AATags = AAMDNodes();
11410b57cec5SDimitry Andric         for (auto &Entry : CacheInfo->NonLocalDeps)
11420b57cec5SDimitry Andric           if (Instruction *Inst = Entry.getResult().getInst())
11430b57cec5SDimitry Andric             RemoveFromReverseMap(ReverseNonLocalPtrDeps, Inst, CacheKey);
11440b57cec5SDimitry Andric         CacheInfo->NonLocalDeps.clear();
11455ffd83dbSDimitry Andric         // The cache is cleared (in the above line) so we will have lost
11465ffd83dbSDimitry Andric         // information about blocks we have already visited. We therefore must
11475ffd83dbSDimitry Andric         // assume that the cache information is incomplete.
11485ffd83dbSDimitry Andric         IsIncomplete = true;
11490b57cec5SDimitry Andric       }
11500b57cec5SDimitry Andric       if (Loc.AATags)
11510b57cec5SDimitry Andric         return getNonLocalPointerDepFromBB(
11520b57cec5SDimitry Andric             QueryInst, Pointer, Loc.getWithoutAATags(), isLoad, StartBB, Result,
11535ffd83dbSDimitry Andric             Visited, SkipFirstBlock, IsIncomplete);
11540b57cec5SDimitry Andric     }
11550b57cec5SDimitry Andric   }
11560b57cec5SDimitry Andric 
11570b57cec5SDimitry Andric   NonLocalDepInfo *Cache = &CacheInfo->NonLocalDeps;
11580b57cec5SDimitry Andric 
11590b57cec5SDimitry Andric   // If we have valid cached information for exactly the block we are
11600b57cec5SDimitry Andric   // investigating, just return it with no recomputation.
11615ffd83dbSDimitry Andric   // Don't use cached information for invariant loads since it is valid for
11625ffd83dbSDimitry Andric   // non-invariant loads only.
11635ffd83dbSDimitry Andric   if (!IsIncomplete && !isInvariantLoad &&
11645ffd83dbSDimitry Andric       CacheInfo->Pair == BBSkipFirstBlockPair(StartBB, SkipFirstBlock)) {
11650b57cec5SDimitry Andric     // We have a fully cached result for this query then we can just return the
11660b57cec5SDimitry Andric     // cached results and populate the visited set.  However, we have to verify
11670b57cec5SDimitry Andric     // that we don't already have conflicting results for these blocks.  Check
11680b57cec5SDimitry Andric     // to ensure that if a block in the results set is in the visited set that
11690b57cec5SDimitry Andric     // it was for the same pointer query.
11700b57cec5SDimitry Andric     if (!Visited.empty()) {
11710b57cec5SDimitry Andric       for (auto &Entry : *Cache) {
11720b57cec5SDimitry Andric         DenseMap<BasicBlock *, Value *>::iterator VI =
11730b57cec5SDimitry Andric             Visited.find(Entry.getBB());
11740b57cec5SDimitry Andric         if (VI == Visited.end() || VI->second == Pointer.getAddr())
11750b57cec5SDimitry Andric           continue;
11760b57cec5SDimitry Andric 
11770b57cec5SDimitry Andric         // We have a pointer mismatch in a block.  Just return false, saying
11780b57cec5SDimitry Andric         // that something was clobbered in this result.  We could also do a
11790b57cec5SDimitry Andric         // non-fully cached query, but there is little point in doing this.
11800b57cec5SDimitry Andric         return false;
11810b57cec5SDimitry Andric       }
11820b57cec5SDimitry Andric     }
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric     Value *Addr = Pointer.getAddr();
11850b57cec5SDimitry Andric     for (auto &Entry : *Cache) {
11860b57cec5SDimitry Andric       Visited.insert(std::make_pair(Entry.getBB(), Addr));
11870b57cec5SDimitry Andric       if (Entry.getResult().isNonLocal()) {
11880b57cec5SDimitry Andric         continue;
11890b57cec5SDimitry Andric       }
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric       if (DT.isReachableFromEntry(Entry.getBB())) {
11920b57cec5SDimitry Andric         Result.push_back(
11930b57cec5SDimitry Andric             NonLocalDepResult(Entry.getBB(), Entry.getResult(), Addr));
11940b57cec5SDimitry Andric       }
11950b57cec5SDimitry Andric     }
11960b57cec5SDimitry Andric     ++NumCacheCompleteNonLocalPtr;
11970b57cec5SDimitry Andric     return true;
11980b57cec5SDimitry Andric   }
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric   // Otherwise, either this is a new block, a block with an invalid cache
12015ffd83dbSDimitry Andric   // pointer or one that we're about to invalidate by putting more info into
12025ffd83dbSDimitry Andric   // it than its valid cache info.  If empty and not explicitly indicated as
12035ffd83dbSDimitry Andric   // incomplete, the result will be valid cache info, otherwise it isn't.
12045ffd83dbSDimitry Andric   //
12055ffd83dbSDimitry Andric   // Invariant loads don't affect cache in any way thus no need to update
12065ffd83dbSDimitry Andric   // CacheInfo as well.
12075ffd83dbSDimitry Andric   if (!isInvariantLoad) {
12085ffd83dbSDimitry Andric     if (!IsIncomplete && Cache->empty())
12090b57cec5SDimitry Andric       CacheInfo->Pair = BBSkipFirstBlockPair(StartBB, SkipFirstBlock);
12100b57cec5SDimitry Andric     else
12110b57cec5SDimitry Andric       CacheInfo->Pair = BBSkipFirstBlockPair();
12125ffd83dbSDimitry Andric   }
12130b57cec5SDimitry Andric 
12140b57cec5SDimitry Andric   SmallVector<BasicBlock *, 32> Worklist;
12150b57cec5SDimitry Andric   Worklist.push_back(StartBB);
12160b57cec5SDimitry Andric 
12170b57cec5SDimitry Andric   // PredList used inside loop.
12180b57cec5SDimitry Andric   SmallVector<std::pair<BasicBlock *, PHITransAddr>, 16> PredList;
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric   // Keep track of the entries that we know are sorted.  Previously cached
12210b57cec5SDimitry Andric   // entries will all be sorted.  The entries we add we only sort on demand (we
12220b57cec5SDimitry Andric   // don't insert every element into its sorted position).  We know that we
12230b57cec5SDimitry Andric   // won't get any reuse from currently inserted values, because we don't
12240b57cec5SDimitry Andric   // revisit blocks after we insert info for them.
12250b57cec5SDimitry Andric   unsigned NumSortedEntries = Cache->size();
12260b57cec5SDimitry Andric   unsigned WorklistEntries = BlockNumberLimit;
12270b57cec5SDimitry Andric   bool GotWorklistLimit = false;
12280b57cec5SDimitry Andric   LLVM_DEBUG(AssertSorted(*Cache));
12290b57cec5SDimitry Andric 
12305f757f3fSDimitry Andric   BatchAAResults BatchAA(AA, &EII);
12310b57cec5SDimitry Andric   while (!Worklist.empty()) {
12320b57cec5SDimitry Andric     BasicBlock *BB = Worklist.pop_back_val();
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric     // If we do process a large number of blocks it becomes very expensive and
12350b57cec5SDimitry Andric     // likely it isn't worth worrying about
12360b57cec5SDimitry Andric     if (Result.size() > NumResultsLimit) {
12370b57cec5SDimitry Andric       // Sort it now (if needed) so that recursive invocations of
12380b57cec5SDimitry Andric       // getNonLocalPointerDepFromBB and other routines that could reuse the
12390b57cec5SDimitry Andric       // cache value will only see properly sorted cache arrays.
12400b57cec5SDimitry Andric       if (Cache && NumSortedEntries != Cache->size()) {
12410b57cec5SDimitry Andric         SortNonLocalDepInfoCache(*Cache, NumSortedEntries);
12420b57cec5SDimitry Andric       }
12430b57cec5SDimitry Andric       // Since we bail out, the "Cache" set won't contain all of the
12440b57cec5SDimitry Andric       // results for the query.  This is ok (we can still use it to accelerate
12450b57cec5SDimitry Andric       // specific block queries) but we can't do the fastpath "return all
12460b57cec5SDimitry Andric       // results from the set".  Clear out the indicator for this.
12470b57cec5SDimitry Andric       CacheInfo->Pair = BBSkipFirstBlockPair();
12480b57cec5SDimitry Andric       return false;
12490b57cec5SDimitry Andric     }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric     // Skip the first block if we have it.
12520b57cec5SDimitry Andric     if (!SkipFirstBlock) {
12530b57cec5SDimitry Andric       // Analyze the dependency of *Pointer in FromBB.  See if we already have
12540b57cec5SDimitry Andric       // been here.
12550b57cec5SDimitry Andric       assert(Visited.count(BB) && "Should check 'visited' before adding to WL");
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric       // Get the dependency info for Pointer in BB.  If we have cached
12580b57cec5SDimitry Andric       // information, we will use it, otherwise we compute it.
12590b57cec5SDimitry Andric       LLVM_DEBUG(AssertSorted(*Cache, NumSortedEntries));
1260fe6060f1SDimitry Andric       MemDepResult Dep = getNonLocalInfoForBlock(
1261fe6060f1SDimitry Andric           QueryInst, Loc, isLoad, BB, Cache, NumSortedEntries, BatchAA);
12620b57cec5SDimitry Andric 
12630b57cec5SDimitry Andric       // If we got a Def or Clobber, add this to the list of results.
12640b57cec5SDimitry Andric       if (!Dep.isNonLocal()) {
12650b57cec5SDimitry Andric         if (DT.isReachableFromEntry(BB)) {
12660b57cec5SDimitry Andric           Result.push_back(NonLocalDepResult(BB, Dep, Pointer.getAddr()));
12670b57cec5SDimitry Andric           continue;
12680b57cec5SDimitry Andric         }
12690b57cec5SDimitry Andric       }
12700b57cec5SDimitry Andric     }
12710b57cec5SDimitry Andric 
12720b57cec5SDimitry Andric     // If 'Pointer' is an instruction defined in this block, then we need to do
12730b57cec5SDimitry Andric     // phi translation to change it into a value live in the predecessor block.
12740b57cec5SDimitry Andric     // If not, we just add the predecessors to the worklist and scan them with
12750b57cec5SDimitry Andric     // the same Pointer.
127606c3fb27SDimitry Andric     if (!Pointer.needsPHITranslationFromBlock(BB)) {
12770b57cec5SDimitry Andric       SkipFirstBlock = false;
12780b57cec5SDimitry Andric       SmallVector<BasicBlock *, 16> NewBlocks;
12790b57cec5SDimitry Andric       for (BasicBlock *Pred : PredCache.get(BB)) {
12800b57cec5SDimitry Andric         // Verify that we haven't looked at this block yet.
12810b57cec5SDimitry Andric         std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> InsertRes =
12820b57cec5SDimitry Andric             Visited.insert(std::make_pair(Pred, Pointer.getAddr()));
12830b57cec5SDimitry Andric         if (InsertRes.second) {
12840b57cec5SDimitry Andric           // First time we've looked at *PI.
12850b57cec5SDimitry Andric           NewBlocks.push_back(Pred);
12860b57cec5SDimitry Andric           continue;
12870b57cec5SDimitry Andric         }
12880b57cec5SDimitry Andric 
12890b57cec5SDimitry Andric         // If we have seen this block before, but it was with a different
12900b57cec5SDimitry Andric         // pointer then we have a phi translation failure and we have to treat
12910b57cec5SDimitry Andric         // this as a clobber.
12920b57cec5SDimitry Andric         if (InsertRes.first->second != Pointer.getAddr()) {
12930b57cec5SDimitry Andric           // Make sure to clean up the Visited map before continuing on to
12940b57cec5SDimitry Andric           // PredTranslationFailure.
1295cb14a3feSDimitry Andric           for (auto *NewBlock : NewBlocks)
1296cb14a3feSDimitry Andric             Visited.erase(NewBlock);
12970b57cec5SDimitry Andric           goto PredTranslationFailure;
12980b57cec5SDimitry Andric         }
12990b57cec5SDimitry Andric       }
13000b57cec5SDimitry Andric       if (NewBlocks.size() > WorklistEntries) {
13010b57cec5SDimitry Andric         // Make sure to clean up the Visited map before continuing on to
13020b57cec5SDimitry Andric         // PredTranslationFailure.
1303cb14a3feSDimitry Andric         for (auto *NewBlock : NewBlocks)
1304cb14a3feSDimitry Andric           Visited.erase(NewBlock);
13050b57cec5SDimitry Andric         GotWorklistLimit = true;
13060b57cec5SDimitry Andric         goto PredTranslationFailure;
13070b57cec5SDimitry Andric       }
13080b57cec5SDimitry Andric       WorklistEntries -= NewBlocks.size();
13090b57cec5SDimitry Andric       Worklist.append(NewBlocks.begin(), NewBlocks.end());
13100b57cec5SDimitry Andric       continue;
13110b57cec5SDimitry Andric     }
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric     // We do need to do phi translation, if we know ahead of time we can't phi
13140b57cec5SDimitry Andric     // translate this value, don't even try.
131506c3fb27SDimitry Andric     if (!Pointer.isPotentiallyPHITranslatable())
13160b57cec5SDimitry Andric       goto PredTranslationFailure;
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric     // We may have added values to the cache list before this PHI translation.
13190b57cec5SDimitry Andric     // If so, we haven't done anything to ensure that the cache remains sorted.
13200b57cec5SDimitry Andric     // Sort it now (if needed) so that recursive invocations of
13210b57cec5SDimitry Andric     // getNonLocalPointerDepFromBB and other routines that could reuse the cache
13220b57cec5SDimitry Andric     // value will only see properly sorted cache arrays.
13230b57cec5SDimitry Andric     if (Cache && NumSortedEntries != Cache->size()) {
13240b57cec5SDimitry Andric       SortNonLocalDepInfoCache(*Cache, NumSortedEntries);
13250b57cec5SDimitry Andric       NumSortedEntries = Cache->size();
13260b57cec5SDimitry Andric     }
13270b57cec5SDimitry Andric     Cache = nullptr;
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric     PredList.clear();
13300b57cec5SDimitry Andric     for (BasicBlock *Pred : PredCache.get(BB)) {
13310b57cec5SDimitry Andric       PredList.push_back(std::make_pair(Pred, Pointer));
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric       // Get the PHI translated pointer in this predecessor.  This can fail if
13340b57cec5SDimitry Andric       // not translatable, in which case the getAddr() returns null.
13350b57cec5SDimitry Andric       PHITransAddr &PredPointer = PredList.back().second;
133606c3fb27SDimitry Andric       Value *PredPtrVal =
133706c3fb27SDimitry Andric           PredPointer.translateValue(BB, Pred, &DT, /*MustDominate=*/false);
13380b57cec5SDimitry Andric 
13390b57cec5SDimitry Andric       // Check to see if we have already visited this pred block with another
13400b57cec5SDimitry Andric       // pointer.  If so, we can't do this lookup.  This failure can occur
13410b57cec5SDimitry Andric       // with PHI translation when a critical edge exists and the PHI node in
13420b57cec5SDimitry Andric       // the successor translates to a pointer value different than the
13430b57cec5SDimitry Andric       // pointer the block was first analyzed with.
13440b57cec5SDimitry Andric       std::pair<DenseMap<BasicBlock *, Value *>::iterator, bool> InsertRes =
13450b57cec5SDimitry Andric           Visited.insert(std::make_pair(Pred, PredPtrVal));
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric       if (!InsertRes.second) {
13480b57cec5SDimitry Andric         // We found the pred; take it off the list of preds to visit.
13490b57cec5SDimitry Andric         PredList.pop_back();
13500b57cec5SDimitry Andric 
13510b57cec5SDimitry Andric         // If the predecessor was visited with PredPtr, then we already did
13520b57cec5SDimitry Andric         // the analysis and can ignore it.
13530b57cec5SDimitry Andric         if (InsertRes.first->second == PredPtrVal)
13540b57cec5SDimitry Andric           continue;
13550b57cec5SDimitry Andric 
13560b57cec5SDimitry Andric         // Otherwise, the block was previously analyzed with a different
13570b57cec5SDimitry Andric         // pointer.  We can't represent the result of this case, so we just
13580b57cec5SDimitry Andric         // treat this as a phi translation failure.
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric         // Make sure to clean up the Visited map before continuing on to
13610b57cec5SDimitry Andric         // PredTranslationFailure.
1362cb14a3feSDimitry Andric         for (const auto &Pred : PredList)
1363cb14a3feSDimitry Andric           Visited.erase(Pred.first);
13640b57cec5SDimitry Andric 
13650b57cec5SDimitry Andric         goto PredTranslationFailure;
13660b57cec5SDimitry Andric       }
13670b57cec5SDimitry Andric     }
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric     // Actually process results here; this need to be a separate loop to avoid
13700b57cec5SDimitry Andric     // calling getNonLocalPointerDepFromBB for blocks we don't want to return
13710b57cec5SDimitry Andric     // any results for.  (getNonLocalPointerDepFromBB will modify our
13720b57cec5SDimitry Andric     // datastructures in ways the code after the PredTranslationFailure label
13730b57cec5SDimitry Andric     // doesn't expect.)
1374cb14a3feSDimitry Andric     for (auto &I : PredList) {
1375cb14a3feSDimitry Andric       BasicBlock *Pred = I.first;
1376cb14a3feSDimitry Andric       PHITransAddr &PredPointer = I.second;
13770b57cec5SDimitry Andric       Value *PredPtrVal = PredPointer.getAddr();
13780b57cec5SDimitry Andric 
13790b57cec5SDimitry Andric       bool CanTranslate = true;
13800b57cec5SDimitry Andric       // If PHI translation was unable to find an available pointer in this
13810b57cec5SDimitry Andric       // predecessor, then we have to assume that the pointer is clobbered in
13820b57cec5SDimitry Andric       // that predecessor.  We can still do PRE of the load, which would insert
13830b57cec5SDimitry Andric       // a computation of the pointer in this predecessor.
13840b57cec5SDimitry Andric       if (!PredPtrVal)
13850b57cec5SDimitry Andric         CanTranslate = false;
13860b57cec5SDimitry Andric 
13870b57cec5SDimitry Andric       // FIXME: it is entirely possible that PHI translating will end up with
13880b57cec5SDimitry Andric       // the same value.  Consider PHI translating something like:
13890b57cec5SDimitry Andric       // X = phi [x, bb1], [y, bb2].  PHI translating for bb1 doesn't *need*
13900b57cec5SDimitry Andric       // to recurse here, pedantically speaking.
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric       // If getNonLocalPointerDepFromBB fails here, that means the cached
13930b57cec5SDimitry Andric       // result conflicted with the Visited list; we have to conservatively
13940b57cec5SDimitry Andric       // assume it is unknown, but this also does not block PRE of the load.
13950b57cec5SDimitry Andric       if (!CanTranslate ||
13960b57cec5SDimitry Andric           !getNonLocalPointerDepFromBB(QueryInst, PredPointer,
13970b57cec5SDimitry Andric                                       Loc.getWithNewPtr(PredPtrVal), isLoad,
13980b57cec5SDimitry Andric                                       Pred, Result, Visited)) {
13990b57cec5SDimitry Andric         // Add the entry to the Result list.
14000b57cec5SDimitry Andric         NonLocalDepResult Entry(Pred, MemDepResult::getUnknown(), PredPtrVal);
14010b57cec5SDimitry Andric         Result.push_back(Entry);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric         // Since we had a phi translation failure, the cache for CacheKey won't
14040b57cec5SDimitry Andric         // include all of the entries that we need to immediately satisfy future
14050b57cec5SDimitry Andric         // queries.  Mark this in NonLocalPointerDeps by setting the
14060b57cec5SDimitry Andric         // BBSkipFirstBlockPair pointer to null.  This requires reuse of the
14070b57cec5SDimitry Andric         // cached value to do more work but not miss the phi trans failure.
14080b57cec5SDimitry Andric         NonLocalPointerInfo &NLPI = NonLocalPointerDeps[CacheKey];
14090b57cec5SDimitry Andric         NLPI.Pair = BBSkipFirstBlockPair();
14100b57cec5SDimitry Andric         continue;
14110b57cec5SDimitry Andric       }
14120b57cec5SDimitry Andric     }
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric     // Refresh the CacheInfo/Cache pointer so that it isn't invalidated.
14150b57cec5SDimitry Andric     CacheInfo = &NonLocalPointerDeps[CacheKey];
14160b57cec5SDimitry Andric     Cache = &CacheInfo->NonLocalDeps;
14170b57cec5SDimitry Andric     NumSortedEntries = Cache->size();
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric     // Since we did phi translation, the "Cache" set won't contain all of the
14200b57cec5SDimitry Andric     // results for the query.  This is ok (we can still use it to accelerate
14210b57cec5SDimitry Andric     // specific block queries) but we can't do the fastpath "return all
14220b57cec5SDimitry Andric     // results from the set"  Clear out the indicator for this.
14230b57cec5SDimitry Andric     CacheInfo->Pair = BBSkipFirstBlockPair();
14240b57cec5SDimitry Andric     SkipFirstBlock = false;
14250b57cec5SDimitry Andric     continue;
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric   PredTranslationFailure:
14280b57cec5SDimitry Andric     // The following code is "failure"; we can't produce a sane translation
14290b57cec5SDimitry Andric     // for the given block.  It assumes that we haven't modified any of
14300b57cec5SDimitry Andric     // our datastructures while processing the current block.
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric     if (!Cache) {
14330b57cec5SDimitry Andric       // Refresh the CacheInfo/Cache pointer if it got invalidated.
14340b57cec5SDimitry Andric       CacheInfo = &NonLocalPointerDeps[CacheKey];
14350b57cec5SDimitry Andric       Cache = &CacheInfo->NonLocalDeps;
14360b57cec5SDimitry Andric       NumSortedEntries = Cache->size();
14370b57cec5SDimitry Andric     }
14380b57cec5SDimitry Andric 
14390b57cec5SDimitry Andric     // Since we failed phi translation, the "Cache" set won't contain all of the
14400b57cec5SDimitry Andric     // results for the query.  This is ok (we can still use it to accelerate
14410b57cec5SDimitry Andric     // specific block queries) but we can't do the fastpath "return all
14420b57cec5SDimitry Andric     // results from the set".  Clear out the indicator for this.
14430b57cec5SDimitry Andric     CacheInfo->Pair = BBSkipFirstBlockPair();
14440b57cec5SDimitry Andric 
14450b57cec5SDimitry Andric     // If *nothing* works, mark the pointer as unknown.
14460b57cec5SDimitry Andric     //
14470b57cec5SDimitry Andric     // If this is the magic first block, return this as a clobber of the whole
14480b57cec5SDimitry Andric     // incoming value.  Since we can't phi translate to one of the predecessors,
14490b57cec5SDimitry Andric     // we have to bail out.
14500b57cec5SDimitry Andric     if (SkipFirstBlock)
14510b57cec5SDimitry Andric       return false;
14520b57cec5SDimitry Andric 
14535ffd83dbSDimitry Andric     // Results of invariant loads are not cached thus no need to update cached
14545ffd83dbSDimitry Andric     // information.
14555ffd83dbSDimitry Andric     if (!isInvariantLoad) {
14560b57cec5SDimitry Andric       for (NonLocalDepEntry &I : llvm::reverse(*Cache)) {
14570b57cec5SDimitry Andric         if (I.getBB() != BB)
14580b57cec5SDimitry Andric           continue;
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric         assert((GotWorklistLimit || I.getResult().isNonLocal() ||
14610b57cec5SDimitry Andric                 !DT.isReachableFromEntry(BB)) &&
14620b57cec5SDimitry Andric                "Should only be here with transparent block");
14635ffd83dbSDimitry Andric 
14640b57cec5SDimitry Andric         I.setResult(MemDepResult::getUnknown());
14655ffd83dbSDimitry Andric 
14665ffd83dbSDimitry Andric 
14670b57cec5SDimitry Andric         break;
14680b57cec5SDimitry Andric       }
14695ffd83dbSDimitry Andric     }
14705ffd83dbSDimitry Andric     (void)GotWorklistLimit;
14715ffd83dbSDimitry Andric     // Go ahead and report unknown dependence.
14725ffd83dbSDimitry Andric     Result.push_back(
14735ffd83dbSDimitry Andric         NonLocalDepResult(BB, MemDepResult::getUnknown(), Pointer.getAddr()));
14740b57cec5SDimitry Andric   }
14750b57cec5SDimitry Andric 
14760b57cec5SDimitry Andric   // Okay, we're done now.  If we added new values to the cache, re-sort it.
14770b57cec5SDimitry Andric   SortNonLocalDepInfoCache(*Cache, NumSortedEntries);
14780b57cec5SDimitry Andric   LLVM_DEBUG(AssertSorted(*Cache));
14790b57cec5SDimitry Andric   return true;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
14820b57cec5SDimitry Andric /// If P exists in CachedNonLocalPointerInfo or NonLocalDefsCache, remove it.
1483fe6060f1SDimitry Andric void MemoryDependenceResults::removeCachedNonLocalPointerDependencies(
14840b57cec5SDimitry Andric     ValueIsLoadPair P) {
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric   // Most of the time this cache is empty.
14870b57cec5SDimitry Andric   if (!NonLocalDefsCache.empty()) {
14880b57cec5SDimitry Andric     auto it = NonLocalDefsCache.find(P.getPointer());
14890b57cec5SDimitry Andric     if (it != NonLocalDefsCache.end()) {
14900b57cec5SDimitry Andric       RemoveFromReverseMap(ReverseNonLocalDefsCache,
14910b57cec5SDimitry Andric                            it->second.getResult().getInst(), P.getPointer());
14920b57cec5SDimitry Andric       NonLocalDefsCache.erase(it);
14930b57cec5SDimitry Andric     }
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric     if (auto *I = dyn_cast<Instruction>(P.getPointer())) {
14960b57cec5SDimitry Andric       auto toRemoveIt = ReverseNonLocalDefsCache.find(I);
14970b57cec5SDimitry Andric       if (toRemoveIt != ReverseNonLocalDefsCache.end()) {
1498480093f4SDimitry Andric         for (const auto *entry : toRemoveIt->second)
14990b57cec5SDimitry Andric           NonLocalDefsCache.erase(entry);
15000b57cec5SDimitry Andric         ReverseNonLocalDefsCache.erase(toRemoveIt);
15010b57cec5SDimitry Andric       }
15020b57cec5SDimitry Andric     }
15030b57cec5SDimitry Andric   }
15040b57cec5SDimitry Andric 
15050b57cec5SDimitry Andric   CachedNonLocalPointerInfo::iterator It = NonLocalPointerDeps.find(P);
15060b57cec5SDimitry Andric   if (It == NonLocalPointerDeps.end())
15070b57cec5SDimitry Andric     return;
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric   // Remove all of the entries in the BB->val map.  This involves removing
15100b57cec5SDimitry Andric   // instructions from the reverse map.
15110b57cec5SDimitry Andric   NonLocalDepInfo &PInfo = It->second.NonLocalDeps;
15120b57cec5SDimitry Andric 
15134824e7fdSDimitry Andric   for (const NonLocalDepEntry &DE : PInfo) {
15144824e7fdSDimitry Andric     Instruction *Target = DE.getResult().getInst();
15150b57cec5SDimitry Andric     if (!Target)
15160b57cec5SDimitry Andric       continue; // Ignore non-local dep results.
15174824e7fdSDimitry Andric     assert(Target->getParent() == DE.getBB());
15180b57cec5SDimitry Andric 
15190b57cec5SDimitry Andric     // Eliminating the dirty entry from 'Cache', so update the reverse info.
15200b57cec5SDimitry Andric     RemoveFromReverseMap(ReverseNonLocalPtrDeps, Target, P);
15210b57cec5SDimitry Andric   }
15220b57cec5SDimitry Andric 
15230b57cec5SDimitry Andric   // Remove P from NonLocalPointerDeps (which deletes NonLocalDepInfo).
15240b57cec5SDimitry Andric   NonLocalPointerDeps.erase(It);
15250b57cec5SDimitry Andric }
15260b57cec5SDimitry Andric 
15270b57cec5SDimitry Andric void MemoryDependenceResults::invalidateCachedPointerInfo(Value *Ptr) {
15280b57cec5SDimitry Andric   // If Ptr isn't really a pointer, just ignore it.
15290b57cec5SDimitry Andric   if (!Ptr->getType()->isPointerTy())
15300b57cec5SDimitry Andric     return;
15310b57cec5SDimitry Andric   // Flush store info for the pointer.
1532fe6060f1SDimitry Andric   removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, false));
15330b57cec5SDimitry Andric   // Flush load info for the pointer.
1534fe6060f1SDimitry Andric   removeCachedNonLocalPointerDependencies(ValueIsLoadPair(Ptr, true));
15350b57cec5SDimitry Andric }
15360b57cec5SDimitry Andric 
15370b57cec5SDimitry Andric void MemoryDependenceResults::invalidateCachedPredecessors() {
15380b57cec5SDimitry Andric   PredCache.clear();
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric 
15410b57cec5SDimitry Andric void MemoryDependenceResults::removeInstruction(Instruction *RemInst) {
15425f757f3fSDimitry Andric   EII.removeInstruction(RemInst);
15435f757f3fSDimitry Andric 
15440b57cec5SDimitry Andric   // Walk through the Non-local dependencies, removing this one as the value
15450b57cec5SDimitry Andric   // for any cached queries.
1546fe6060f1SDimitry Andric   NonLocalDepMapType::iterator NLDI = NonLocalDepsMap.find(RemInst);
1547fe6060f1SDimitry Andric   if (NLDI != NonLocalDepsMap.end()) {
15480b57cec5SDimitry Andric     NonLocalDepInfo &BlockMap = NLDI->second.first;
15490b57cec5SDimitry Andric     for (auto &Entry : BlockMap)
15500b57cec5SDimitry Andric       if (Instruction *Inst = Entry.getResult().getInst())
15510b57cec5SDimitry Andric         RemoveFromReverseMap(ReverseNonLocalDeps, Inst, RemInst);
1552fe6060f1SDimitry Andric     NonLocalDepsMap.erase(NLDI);
15530b57cec5SDimitry Andric   }
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric   // If we have a cached local dependence query for this instruction, remove it.
15560b57cec5SDimitry Andric   LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst);
15570b57cec5SDimitry Andric   if (LocalDepEntry != LocalDeps.end()) {
15580b57cec5SDimitry Andric     // Remove us from DepInst's reverse set now that the local dep info is gone.
15590b57cec5SDimitry Andric     if (Instruction *Inst = LocalDepEntry->second.getInst())
15600b57cec5SDimitry Andric       RemoveFromReverseMap(ReverseLocalDeps, Inst, RemInst);
15610b57cec5SDimitry Andric 
15620b57cec5SDimitry Andric     // Remove this local dependency info.
15630b57cec5SDimitry Andric     LocalDeps.erase(LocalDepEntry);
15640b57cec5SDimitry Andric   }
15650b57cec5SDimitry Andric 
15665ffd83dbSDimitry Andric   // If we have any cached dependencies on this instruction, remove
15675ffd83dbSDimitry Andric   // them.
15680b57cec5SDimitry Andric 
15695ffd83dbSDimitry Andric   // If the instruction is a pointer, remove it from both the load info and the
15705ffd83dbSDimitry Andric   // store info.
15710b57cec5SDimitry Andric   if (RemInst->getType()->isPointerTy()) {
1572fe6060f1SDimitry Andric     removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, false));
1573fe6060f1SDimitry Andric     removeCachedNonLocalPointerDependencies(ValueIsLoadPair(RemInst, true));
15745ffd83dbSDimitry Andric   } else {
15755ffd83dbSDimitry Andric     // Otherwise, if the instructions is in the map directly, it must be a load.
15765ffd83dbSDimitry Andric     // Remove it.
15775ffd83dbSDimitry Andric     auto toRemoveIt = NonLocalDefsCache.find(RemInst);
15785ffd83dbSDimitry Andric     if (toRemoveIt != NonLocalDefsCache.end()) {
15795ffd83dbSDimitry Andric       assert(isa<LoadInst>(RemInst) &&
15805ffd83dbSDimitry Andric              "only load instructions should be added directly");
15815ffd83dbSDimitry Andric       const Instruction *DepV = toRemoveIt->second.getResult().getInst();
15825ffd83dbSDimitry Andric       ReverseNonLocalDefsCache.find(DepV)->second.erase(RemInst);
15835ffd83dbSDimitry Andric       NonLocalDefsCache.erase(toRemoveIt);
15845ffd83dbSDimitry Andric     }
15850b57cec5SDimitry Andric   }
15860b57cec5SDimitry Andric 
15870b57cec5SDimitry Andric   // Loop over all of the things that depend on the instruction we're removing.
15880b57cec5SDimitry Andric   SmallVector<std::pair<Instruction *, Instruction *>, 8> ReverseDepsToAdd;
15890b57cec5SDimitry Andric 
15900b57cec5SDimitry Andric   // If we find RemInst as a clobber or Def in any of the maps for other values,
15910b57cec5SDimitry Andric   // we need to replace its entry with a dirty version of the instruction after
15920b57cec5SDimitry Andric   // it.  If RemInst is a terminator, we use a null dirty value.
15930b57cec5SDimitry Andric   //
15940b57cec5SDimitry Andric   // Using a dirty version of the instruction after RemInst saves having to scan
15950b57cec5SDimitry Andric   // the entire block to get to this point.
15960b57cec5SDimitry Andric   MemDepResult NewDirtyVal;
15970b57cec5SDimitry Andric   if (!RemInst->isTerminator())
15980b57cec5SDimitry Andric     NewDirtyVal = MemDepResult::getDirty(&*++RemInst->getIterator());
15990b57cec5SDimitry Andric 
16000b57cec5SDimitry Andric   ReverseDepMapType::iterator ReverseDepIt = ReverseLocalDeps.find(RemInst);
16010b57cec5SDimitry Andric   if (ReverseDepIt != ReverseLocalDeps.end()) {
16020b57cec5SDimitry Andric     // RemInst can't be the terminator if it has local stuff depending on it.
16030b57cec5SDimitry Andric     assert(!ReverseDepIt->second.empty() && !RemInst->isTerminator() &&
16040b57cec5SDimitry Andric            "Nothing can locally depend on a terminator");
16050b57cec5SDimitry Andric 
16060b57cec5SDimitry Andric     for (Instruction *InstDependingOnRemInst : ReverseDepIt->second) {
16070b57cec5SDimitry Andric       assert(InstDependingOnRemInst != RemInst &&
16080b57cec5SDimitry Andric              "Already removed our local dep info");
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric       LocalDeps[InstDependingOnRemInst] = NewDirtyVal;
16110b57cec5SDimitry Andric 
16120b57cec5SDimitry Andric       // Make sure to remember that new things depend on NewDepInst.
16130b57cec5SDimitry Andric       assert(NewDirtyVal.getInst() &&
16140b57cec5SDimitry Andric              "There is no way something else can have "
16150b57cec5SDimitry Andric              "a local dep on this if it is a terminator!");
16160b57cec5SDimitry Andric       ReverseDepsToAdd.push_back(
16170b57cec5SDimitry Andric           std::make_pair(NewDirtyVal.getInst(), InstDependingOnRemInst));
16180b57cec5SDimitry Andric     }
16190b57cec5SDimitry Andric 
16200b57cec5SDimitry Andric     ReverseLocalDeps.erase(ReverseDepIt);
16210b57cec5SDimitry Andric 
16220b57cec5SDimitry Andric     // Add new reverse deps after scanning the set, to avoid invalidating the
16230b57cec5SDimitry Andric     // 'ReverseDeps' reference.
16240b57cec5SDimitry Andric     while (!ReverseDepsToAdd.empty()) {
16250b57cec5SDimitry Andric       ReverseLocalDeps[ReverseDepsToAdd.back().first].insert(
16260b57cec5SDimitry Andric           ReverseDepsToAdd.back().second);
16270b57cec5SDimitry Andric       ReverseDepsToAdd.pop_back();
16280b57cec5SDimitry Andric     }
16290b57cec5SDimitry Andric   }
16300b57cec5SDimitry Andric 
16310b57cec5SDimitry Andric   ReverseDepIt = ReverseNonLocalDeps.find(RemInst);
16320b57cec5SDimitry Andric   if (ReverseDepIt != ReverseNonLocalDeps.end()) {
16330b57cec5SDimitry Andric     for (Instruction *I : ReverseDepIt->second) {
16340b57cec5SDimitry Andric       assert(I != RemInst && "Already removed NonLocalDep info for RemInst");
16350b57cec5SDimitry Andric 
1636fe6060f1SDimitry Andric       PerInstNLInfo &INLD = NonLocalDepsMap[I];
16370b57cec5SDimitry Andric       // The information is now dirty!
16380b57cec5SDimitry Andric       INLD.second = true;
16390b57cec5SDimitry Andric 
16400b57cec5SDimitry Andric       for (auto &Entry : INLD.first) {
16410b57cec5SDimitry Andric         if (Entry.getResult().getInst() != RemInst)
16420b57cec5SDimitry Andric           continue;
16430b57cec5SDimitry Andric 
16440b57cec5SDimitry Andric         // Convert to a dirty entry for the subsequent instruction.
16450b57cec5SDimitry Andric         Entry.setResult(NewDirtyVal);
16460b57cec5SDimitry Andric 
16470b57cec5SDimitry Andric         if (Instruction *NextI = NewDirtyVal.getInst())
16480b57cec5SDimitry Andric           ReverseDepsToAdd.push_back(std::make_pair(NextI, I));
16490b57cec5SDimitry Andric       }
16500b57cec5SDimitry Andric     }
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric     ReverseNonLocalDeps.erase(ReverseDepIt);
16530b57cec5SDimitry Andric 
16540b57cec5SDimitry Andric     // Add new reverse deps after scanning the set, to avoid invalidating 'Set'
16550b57cec5SDimitry Andric     while (!ReverseDepsToAdd.empty()) {
16560b57cec5SDimitry Andric       ReverseNonLocalDeps[ReverseDepsToAdd.back().first].insert(
16570b57cec5SDimitry Andric           ReverseDepsToAdd.back().second);
16580b57cec5SDimitry Andric       ReverseDepsToAdd.pop_back();
16590b57cec5SDimitry Andric     }
16600b57cec5SDimitry Andric   }
16610b57cec5SDimitry Andric 
16620b57cec5SDimitry Andric   // If the instruction is in ReverseNonLocalPtrDeps then it appears as a
16630b57cec5SDimitry Andric   // value in the NonLocalPointerDeps info.
16640b57cec5SDimitry Andric   ReverseNonLocalPtrDepTy::iterator ReversePtrDepIt =
16650b57cec5SDimitry Andric       ReverseNonLocalPtrDeps.find(RemInst);
16660b57cec5SDimitry Andric   if (ReversePtrDepIt != ReverseNonLocalPtrDeps.end()) {
16670b57cec5SDimitry Andric     SmallVector<std::pair<Instruction *, ValueIsLoadPair>, 8>
16680b57cec5SDimitry Andric         ReversePtrDepsToAdd;
16690b57cec5SDimitry Andric 
16700b57cec5SDimitry Andric     for (ValueIsLoadPair P : ReversePtrDepIt->second) {
16710b57cec5SDimitry Andric       assert(P.getPointer() != RemInst &&
16720b57cec5SDimitry Andric              "Already removed NonLocalPointerDeps info for RemInst");
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric       NonLocalDepInfo &NLPDI = NonLocalPointerDeps[P].NonLocalDeps;
16750b57cec5SDimitry Andric 
16760b57cec5SDimitry Andric       // The cache is not valid for any specific block anymore.
16770b57cec5SDimitry Andric       NonLocalPointerDeps[P].Pair = BBSkipFirstBlockPair();
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric       // Update any entries for RemInst to use the instruction after it.
16800b57cec5SDimitry Andric       for (auto &Entry : NLPDI) {
16810b57cec5SDimitry Andric         if (Entry.getResult().getInst() != RemInst)
16820b57cec5SDimitry Andric           continue;
16830b57cec5SDimitry Andric 
16840b57cec5SDimitry Andric         // Convert to a dirty entry for the subsequent instruction.
16850b57cec5SDimitry Andric         Entry.setResult(NewDirtyVal);
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric         if (Instruction *NewDirtyInst = NewDirtyVal.getInst())
16880b57cec5SDimitry Andric           ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P));
16890b57cec5SDimitry Andric       }
16900b57cec5SDimitry Andric 
16910b57cec5SDimitry Andric       // Re-sort the NonLocalDepInfo.  Changing the dirty entry to its
16920b57cec5SDimitry Andric       // subsequent value may invalidate the sortedness.
16930b57cec5SDimitry Andric       llvm::sort(NLPDI);
16940b57cec5SDimitry Andric     }
16950b57cec5SDimitry Andric 
16960b57cec5SDimitry Andric     ReverseNonLocalPtrDeps.erase(ReversePtrDepIt);
16970b57cec5SDimitry Andric 
16980b57cec5SDimitry Andric     while (!ReversePtrDepsToAdd.empty()) {
16990b57cec5SDimitry Andric       ReverseNonLocalPtrDeps[ReversePtrDepsToAdd.back().first].insert(
17000b57cec5SDimitry Andric           ReversePtrDepsToAdd.back().second);
17010b57cec5SDimitry Andric       ReversePtrDepsToAdd.pop_back();
17020b57cec5SDimitry Andric     }
17030b57cec5SDimitry Andric   }
17040b57cec5SDimitry Andric 
1705fe6060f1SDimitry Andric   assert(!NonLocalDepsMap.count(RemInst) && "RemInst got reinserted?");
17060b57cec5SDimitry Andric   LLVM_DEBUG(verifyRemoved(RemInst));
17070b57cec5SDimitry Andric }
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric /// Verify that the specified instruction does not occur in our internal data
17100b57cec5SDimitry Andric /// structures.
17110b57cec5SDimitry Andric ///
17120b57cec5SDimitry Andric /// This function verifies by asserting in debug builds.
17130b57cec5SDimitry Andric void MemoryDependenceResults::verifyRemoved(Instruction *D) const {
17140b57cec5SDimitry Andric #ifndef NDEBUG
17150b57cec5SDimitry Andric   for (const auto &DepKV : LocalDeps) {
17160b57cec5SDimitry Andric     assert(DepKV.first != D && "Inst occurs in data structures");
17170b57cec5SDimitry Andric     assert(DepKV.second.getInst() != D && "Inst occurs in data structures");
17180b57cec5SDimitry Andric   }
17190b57cec5SDimitry Andric 
17200b57cec5SDimitry Andric   for (const auto &DepKV : NonLocalPointerDeps) {
17210b57cec5SDimitry Andric     assert(DepKV.first.getPointer() != D && "Inst occurs in NLPD map key");
17220b57cec5SDimitry Andric     for (const auto &Entry : DepKV.second.NonLocalDeps)
17230b57cec5SDimitry Andric       assert(Entry.getResult().getInst() != D && "Inst occurs as NLPD value");
17240b57cec5SDimitry Andric   }
17250b57cec5SDimitry Andric 
1726fe6060f1SDimitry Andric   for (const auto &DepKV : NonLocalDepsMap) {
17270b57cec5SDimitry Andric     assert(DepKV.first != D && "Inst occurs in data structures");
17280b57cec5SDimitry Andric     const PerInstNLInfo &INLD = DepKV.second;
17290b57cec5SDimitry Andric     for (const auto &Entry : INLD.first)
17300b57cec5SDimitry Andric       assert(Entry.getResult().getInst() != D &&
17310b57cec5SDimitry Andric              "Inst occurs in data structures");
17320b57cec5SDimitry Andric   }
17330b57cec5SDimitry Andric 
17340b57cec5SDimitry Andric   for (const auto &DepKV : ReverseLocalDeps) {
17350b57cec5SDimitry Andric     assert(DepKV.first != D && "Inst occurs in data structures");
17360b57cec5SDimitry Andric     for (Instruction *Inst : DepKV.second)
17370b57cec5SDimitry Andric       assert(Inst != D && "Inst occurs in data structures");
17380b57cec5SDimitry Andric   }
17390b57cec5SDimitry Andric 
17400b57cec5SDimitry Andric   for (const auto &DepKV : ReverseNonLocalDeps) {
17410b57cec5SDimitry Andric     assert(DepKV.first != D && "Inst occurs in data structures");
17420b57cec5SDimitry Andric     for (Instruction *Inst : DepKV.second)
17430b57cec5SDimitry Andric       assert(Inst != D && "Inst occurs in data structures");
17440b57cec5SDimitry Andric   }
17450b57cec5SDimitry Andric 
17460b57cec5SDimitry Andric   for (const auto &DepKV : ReverseNonLocalPtrDeps) {
17470b57cec5SDimitry Andric     assert(DepKV.first != D && "Inst occurs in rev NLPD map");
17480b57cec5SDimitry Andric 
17490b57cec5SDimitry Andric     for (ValueIsLoadPair P : DepKV.second)
17500b57cec5SDimitry Andric       assert(P != ValueIsLoadPair(D, false) && P != ValueIsLoadPair(D, true) &&
17510b57cec5SDimitry Andric              "Inst occurs in ReverseNonLocalPtrDeps map");
17520b57cec5SDimitry Andric   }
17530b57cec5SDimitry Andric #endif
17540b57cec5SDimitry Andric }
17550b57cec5SDimitry Andric 
17560b57cec5SDimitry Andric AnalysisKey MemoryDependenceAnalysis::Key;
17570b57cec5SDimitry Andric 
17588bcb0991SDimitry Andric MemoryDependenceAnalysis::MemoryDependenceAnalysis()
17598bcb0991SDimitry Andric     : DefaultBlockScanLimit(BlockScanLimit) {}
17608bcb0991SDimitry Andric 
17610b57cec5SDimitry Andric MemoryDependenceResults
17620b57cec5SDimitry Andric MemoryDependenceAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
17630b57cec5SDimitry Andric   auto &AA = AM.getResult<AAManager>(F);
17640b57cec5SDimitry Andric   auto &AC = AM.getResult<AssumptionAnalysis>(F);
17650b57cec5SDimitry Andric   auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
17660b57cec5SDimitry Andric   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
1767bdd1243dSDimitry Andric   return MemoryDependenceResults(AA, AC, TLI, DT, DefaultBlockScanLimit);
17680b57cec5SDimitry Andric }
17690b57cec5SDimitry Andric 
17700b57cec5SDimitry Andric char MemoryDependenceWrapperPass::ID = 0;
17710b57cec5SDimitry Andric 
17720b57cec5SDimitry Andric INITIALIZE_PASS_BEGIN(MemoryDependenceWrapperPass, "memdep",
17730b57cec5SDimitry Andric                       "Memory Dependence Analysis", false, true)
17740b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
17750b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
17760b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
17770b57cec5SDimitry Andric INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
17780b57cec5SDimitry Andric INITIALIZE_PASS_END(MemoryDependenceWrapperPass, "memdep",
17790b57cec5SDimitry Andric                     "Memory Dependence Analysis", false, true)
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric MemoryDependenceWrapperPass::MemoryDependenceWrapperPass() : FunctionPass(ID) {
17820b57cec5SDimitry Andric   initializeMemoryDependenceWrapperPassPass(*PassRegistry::getPassRegistry());
17830b57cec5SDimitry Andric }
17840b57cec5SDimitry Andric 
17850b57cec5SDimitry Andric MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() = default;
17860b57cec5SDimitry Andric 
17870b57cec5SDimitry Andric void MemoryDependenceWrapperPass::releaseMemory() {
17880b57cec5SDimitry Andric   MemDep.reset();
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric void MemoryDependenceWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
17920b57cec5SDimitry Andric   AU.setPreservesAll();
17930b57cec5SDimitry Andric   AU.addRequired<AssumptionCacheTracker>();
17940b57cec5SDimitry Andric   AU.addRequired<DominatorTreeWrapperPass>();
17950b57cec5SDimitry Andric   AU.addRequiredTransitive<AAResultsWrapperPass>();
17960b57cec5SDimitry Andric   AU.addRequiredTransitive<TargetLibraryInfoWrapperPass>();
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric bool MemoryDependenceResults::invalidate(Function &F, const PreservedAnalyses &PA,
18000b57cec5SDimitry Andric                                FunctionAnalysisManager::Invalidator &Inv) {
18010b57cec5SDimitry Andric   // Check whether our analysis is preserved.
18020b57cec5SDimitry Andric   auto PAC = PA.getChecker<MemoryDependenceAnalysis>();
18030b57cec5SDimitry Andric   if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>())
18040b57cec5SDimitry Andric     // If not, give up now.
18050b57cec5SDimitry Andric     return true;
18060b57cec5SDimitry Andric 
18070b57cec5SDimitry Andric   // Check whether the analyses we depend on became invalid for any reason.
18080b57cec5SDimitry Andric   if (Inv.invalidate<AAManager>(F, PA) ||
18090b57cec5SDimitry Andric       Inv.invalidate<AssumptionAnalysis>(F, PA) ||
1810bdd1243dSDimitry Andric       Inv.invalidate<DominatorTreeAnalysis>(F, PA))
18110b57cec5SDimitry Andric     return true;
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric   // Otherwise this analysis result remains valid.
18140b57cec5SDimitry Andric   return false;
18150b57cec5SDimitry Andric }
18160b57cec5SDimitry Andric 
18170b57cec5SDimitry Andric unsigned MemoryDependenceResults::getDefaultBlockScanLimit() const {
18188bcb0991SDimitry Andric   return DefaultBlockScanLimit;
18190b57cec5SDimitry Andric }
18200b57cec5SDimitry Andric 
18210b57cec5SDimitry Andric bool MemoryDependenceWrapperPass::runOnFunction(Function &F) {
18220b57cec5SDimitry Andric   auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
18230b57cec5SDimitry Andric   auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
18248bcb0991SDimitry Andric   auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
18250b57cec5SDimitry Andric   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1826bdd1243dSDimitry Andric   MemDep.emplace(AA, AC, TLI, DT, BlockScanLimit);
18270b57cec5SDimitry Andric   return false;
18280b57cec5SDimitry Andric }
1829