diff options
Diffstat (limited to 'lib/Analysis/MemoryDependenceAnalysis.cpp')
| -rw-r--r-- | lib/Analysis/MemoryDependenceAnalysis.cpp | 90 | 
1 files changed, 49 insertions, 41 deletions
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 263cf42ebe27..a6c590126c2f 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -15,28 +15,40 @@  //===----------------------------------------------------------------------===//  #include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/Statistic.h"  #include "llvm/Analysis/AliasAnalysis.h"  #include "llvm/Analysis/AssumptionCache.h"  #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Analysis/MemoryLocation.h"  #include "llvm/Analysis/OrderedBasicBlock.h"  #include "llvm/Analysis/PHITransAddr.h"  #include "llvm/Analysis/TargetLibraryInfo.h"  #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h"  #include "llvm/IR/CallSite.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/DerivedTypes.h"  #include "llvm/IR/Dominators.h"  #include "llvm/IR/Function.h" +#include "llvm/IR/InstrTypes.h"  #include "llvm/IR/Instruction.h"  #include "llvm/IR/Instructions.h"  #include "llvm/IR/IntrinsicInst.h"  #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" +#include "llvm/IR/Module.h"  #include "llvm/IR/PredIteratorCache.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Use.h" +#include "llvm/IR/User.h" +#include "llvm/IR/Value.h" +#include "llvm/Pass.h"  #include "llvm/Support/AtomicOrdering.h"  #include "llvm/Support/Casting.h"  #include "llvm/Support/CommandLine.h" @@ -45,7 +57,9 @@  #include "llvm/Support/MathExtras.h"  #include <algorithm>  #include <cassert> +#include <cstdint>  #include <iterator> +#include <utility>  using namespace llvm; @@ -105,38 +119,38 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,    if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {      if (LI->isUnordered()) {        Loc = MemoryLocation::get(LI); -      return MRI_Ref; +      return ModRefInfo::Ref;      }      if (LI->getOrdering() == AtomicOrdering::Monotonic) {        Loc = MemoryLocation::get(LI); -      return MRI_ModRef; +      return ModRefInfo::ModRef;      }      Loc = MemoryLocation(); -    return MRI_ModRef; +    return ModRefInfo::ModRef;    }    if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {      if (SI->isUnordered()) {        Loc = MemoryLocation::get(SI); -      return MRI_Mod; +      return ModRefInfo::Mod;      }      if (SI->getOrdering() == AtomicOrdering::Monotonic) {        Loc = MemoryLocation::get(SI); -      return MRI_ModRef; +      return ModRefInfo::ModRef;      }      Loc = MemoryLocation(); -    return MRI_ModRef; +    return ModRefInfo::ModRef;    }    if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {      Loc = MemoryLocation::get(V); -    return MRI_ModRef; +    return ModRefInfo::ModRef;    }    if (const CallInst *CI = isFreeCall(Inst, &TLI)) {      // calls to free() deallocate the entire structure      Loc = MemoryLocation(CI->getArgOperand(0)); -    return MRI_Mod; +    return ModRefInfo::Mod;    }    if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) { @@ -152,7 +166,7 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,            cast<ConstantInt>(II->getArgOperand(0))->getZExtValue(), AAInfo);        // These intrinsics don't really modify the memory, but returning Mod        // will allow them to be handled conservatively. -      return MRI_Mod; +      return ModRefInfo::Mod;      case Intrinsic::invariant_end:        II->getAAMetadata(AAInfo);        Loc = MemoryLocation( @@ -160,7 +174,7 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,            cast<ConstantInt>(II->getArgOperand(1))->getZExtValue(), AAInfo);        // These intrinsics don't really modify the memory, but returning Mod        // will allow them to be handled conservatively. -      return MRI_Mod; +      return ModRefInfo::Mod;      default:        break;      } @@ -168,10 +182,10 @@ static ModRefInfo GetLocation(const Instruction *Inst, MemoryLocation &Loc,    // Otherwise, just do the coarse-grained thing that always works.    if (Inst->mayWriteToMemory()) -    return MRI_ModRef; +    return ModRefInfo::ModRef;    if (Inst->mayReadFromMemory()) -    return MRI_Ref; -  return MRI_NoModRef; +    return ModRefInfo::Ref; +  return ModRefInfo::NoModRef;  }  /// Private helper for finding the local dependencies of a call site. @@ -182,48 +196,46 @@ MemDepResult MemoryDependenceResults::getCallSiteDependencyFrom(    // Walk backwards through the block, looking for dependencies.    while (ScanIt != BB->begin()) { +    Instruction *Inst = &*--ScanIt; +    // Debug intrinsics don't cause dependences and should not affect Limit +    if (isa<DbgInfoIntrinsic>(Inst)) +      continue; +      // Limit the amount of scanning we do so we don't end up with quadratic      // running time on extreme testcases.      --Limit;      if (!Limit)        return MemDepResult::getUnknown(); -    Instruction *Inst = &*--ScanIt; -      // If this inst is a memory op, get the pointer it accessed      MemoryLocation Loc;      ModRefInfo MR = GetLocation(Inst, Loc, TLI);      if (Loc.Ptr) {        // A simple instruction. -      if (AA.getModRefInfo(CS, Loc) != MRI_NoModRef) +      if (isModOrRefSet(AA.getModRefInfo(CS, Loc)))          return MemDepResult::getClobber(Inst);        continue;      }      if (auto InstCS = CallSite(Inst)) { -      // Debug intrinsics don't cause dependences. -      if (isa<DbgInfoIntrinsic>(Inst)) -        continue;        // If these two calls do not interfere, look past it. -      switch (AA.getModRefInfo(CS, InstCS)) { -      case MRI_NoModRef: +      if (isNoModRef(AA.getModRefInfo(CS, InstCS))) {          // If the two calls are the same, return InstCS as a Def, so that          // CS can be found redundant and eliminated. -        if (isReadOnlyCall && !(MR & MRI_Mod) && +        if (isReadOnlyCall && !isModSet(MR) &&              CS.getInstruction()->isIdenticalToWhenDefined(Inst))            return MemDepResult::getDef(Inst);          // Otherwise if the two calls don't interact (e.g. InstCS is readnone)          // keep scanning.          continue; -      default: +      } else          return MemDepResult::getClobber(Inst); -      }      }      // If we could not obtain a pointer for the instruction and the instruction      // touches memory then assume that this is a dependency. -    if (MR != MRI_NoModRef) +    if (isModOrRefSet(MR))        return MemDepResult::getClobber(Inst);    } @@ -294,8 +306,10 @@ unsigned MemoryDependenceResults::getLoadLoadClobberFullWidthSize(        return 0;      if (LIOffs + NewLoadByteSize > MemLocEnd && -        LI->getParent()->getParent()->hasFnAttribute( -            Attribute::SanitizeAddress)) +        (LI->getParent()->getParent()->hasFnAttribute( +             Attribute::SanitizeAddress) || +         LI->getParent()->getParent()->hasFnAttribute( +             Attribute::SanitizeHWAddress)))        // We will be reading past the location accessed by the original program.        // While this is safe in a regular build, Address Safety analysis tools        // may start reporting false warnings. So, don't do widening. @@ -322,7 +336,6 @@ static bool isVolatile(Instruction *Inst) {  MemDepResult MemoryDependenceResults::getPointerDependencyFrom(      const MemoryLocation &MemLoc, bool isLoad, BasicBlock::iterator ScanIt,      BasicBlock *BB, Instruction *QueryInst, unsigned *Limit) { -    MemDepResult InvariantGroupDependency = MemDepResult::getUnknown();    if (QueryInst != nullptr) {      if (auto *LI = dyn_cast<LoadInst>(QueryInst)) { @@ -350,7 +363,6 @@ MemDepResult MemoryDependenceResults::getPointerDependencyFrom(  MemDepResult  MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,                                                              BasicBlock *BB) { -    auto *InvariantGroupMD = LI->getMetadata(LLVMContext::MD_invariant_group);    if (!InvariantGroupMD)      return MemDepResult::getUnknown(); @@ -380,7 +392,6 @@ MemoryDependenceResults::getInvariantGroupPointerDependency(LoadInst *LI,      return Best;    }; -    // FIXME: This loop is O(N^2) because dominates can be O(n) and in worst case    // we will see all the instructions. This should be fixed in MSSA.    while (!LoadOperandsQueue.empty()) { @@ -541,7 +552,6 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(      // it does not alias with when this atomic load indicates that another      // thread may be accessing the location.      if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { -        // While volatile access cannot be eliminated, they do not have to clobber        // non-aliasing locations, as normal accesses, for example, can be safely        // reordered with volatile accesses. @@ -632,7 +642,7 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(        // If alias analysis can tell that this store is guaranteed to not modify        // the query pointer, ignore it.  Use getModRefInfo to handle cases where        // the query pointer points to constant memory etc. -      if (AA.getModRefInfo(SI, MemLoc) == MRI_NoModRef) +      if (!isModOrRefSet(AA.getModRefInfo(SI, MemLoc)))          continue;        // Ok, this store might clobber the query pointer.  Check to see if it is @@ -678,15 +688,15 @@ MemDepResult MemoryDependenceResults::getSimplePointerDependencyFrom(      // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.      ModRefInfo MR = AA.getModRefInfo(Inst, MemLoc);      // If necessary, perform additional analysis. -    if (MR == MRI_ModRef) +    if (isModAndRefSet(MR))        MR = AA.callCapturesBefore(Inst, MemLoc, &DT, &OBB);      switch (MR) { -    case MRI_NoModRef: +    case ModRefInfo::NoModRef:        // If the call has no effect on the queried pointer, just ignore it.        continue; -    case MRI_Mod: +    case ModRefInfo::Mod:        return MemDepResult::getClobber(Inst); -    case MRI_Ref: +    case ModRefInfo::Ref:        // If the call is known to never store to the pointer, and if this is a        // load query, we can safely ignore it (scan past it).        if (isLoad) @@ -739,7 +749,7 @@ MemDepResult MemoryDependenceResults::getDependency(Instruction *QueryInst) {      ModRefInfo MR = GetLocation(QueryInst, MemLoc, TLI);      if (MemLoc.Ptr) {        // If we can do a pointer scan, make it happen. -      bool isLoad = !(MR & MRI_Mod); +      bool isLoad = !isModSet(MR);        if (auto *II = dyn_cast<IntrinsicInst>(QueryInst))          isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_start; @@ -1508,7 +1518,6 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) {    }    // If we have a cached local dependence query for this instruction, remove it. -  //    LocalDepMapType::iterator LocalDepEntry = LocalDeps.find(RemInst);    if (LocalDepEntry != LocalDeps.end()) {      // Remove us from DepInst's reverse set now that the local dep info is gone. @@ -1531,7 +1540,6 @@ void MemoryDependenceResults::removeInstruction(Instruction *RemInst) {    }    // Loop over all of the things that depend on the instruction we're removing. -  //    SmallVector<std::pair<Instruction *, Instruction *>, 8> ReverseDepsToAdd;    // If we find RemInst as a clobber or Def in any of the maps for other values, @@ -1726,7 +1734,7 @@ MemoryDependenceWrapperPass::MemoryDependenceWrapperPass() : FunctionPass(ID) {    initializeMemoryDependenceWrapperPassPass(*PassRegistry::getPassRegistry());  } -MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() {} +MemoryDependenceWrapperPass::~MemoryDependenceWrapperPass() = default;  void MemoryDependenceWrapperPass::releaseMemory() {    MemDep.reset();  | 
