From 667ccf231b57857ea9e36f1d93bd895242d58284 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 15 Aug 2011 20:54:19 +0000 Subject: [PATCH] Misc analysis passes that need to be aware of atomic load/store. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137650 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/AliasAnalysis.cpp | 8 ++--- lib/Analysis/LoopDependenceAnalysis.cpp | 8 ++++- lib/Analysis/MemDepPrinter.cpp | 17 ++++++++--- lib/Analysis/MemoryDependenceAnalysis.cpp | 36 ++++++++++++++++------- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp index bfa02e0e1f8..73cc9037216 100644 --- a/lib/Analysis/AliasAnalysis.cpp +++ b/lib/Analysis/AliasAnalysis.cpp @@ -268,8 +268,8 @@ AliasAnalysis::getLocationForDest(const MemIntrinsic *MTI) { AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { - // Be conservative in the face of volatile. - if (L->isVolatile()) + // Be conservative in the face of volatile/atomic. + if (!L->isUnordered()) return ModRef; // If the load address doesn't alias the given address, it doesn't read @@ -283,8 +283,8 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) { AliasAnalysis::ModRefResult AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) { - // Be conservative in the face of volatile. - if (S->isVolatile()) + // Be conservative in the face of volatile/atomic. + if (!S->isUnordered()) return ModRef; // If the store address cannot alias the pointer in question, then the diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp index c1afe8fbd61..3997ac478b5 100644 --- a/lib/Analysis/LoopDependenceAnalysis.cpp +++ b/lib/Analysis/LoopDependenceAnalysis.cpp @@ -76,7 +76,13 @@ static void GetMemRefInstrs(const Loop *L, } static bool IsLoadOrStoreInst(Value *I) { - return isa(I) || isa(I); + // Returns true if the load or store can be analyzed. Atomic and volatile + // operations have properties which this analysis does not understand. + if (LoadInst *LI = dyn_cast(I)) + return LI->isUnordered(); + else if (StoreInst *SI = dyn_cast(I)) + return SI->isUnordered(); + return false; } static Value *GetPointerOperand(Value *I) { diff --git a/lib/Analysis/MemDepPrinter.cpp b/lib/Analysis/MemDepPrinter.cpp index 2283db0bc48..dc40da012c0 100644 --- a/lib/Analysis/MemDepPrinter.cpp +++ b/lib/Analysis/MemDepPrinter.cpp @@ -102,12 +102,21 @@ bool MemDepPrinter::runOnFunction(Function &F) { } else { SmallVector NLDI; if (LoadInst *LI = dyn_cast(Inst)) { - // FIXME: Volatile is not handled properly here. + if (!LI->isUnordered()) { + // FIXME: Handle atomic/volatile loads. + Deps[Inst].insert(std::make_pair(InstAndClobberFlag(0, false), + static_cast(0))); + continue; + } AliasAnalysis::Location Loc = AA.getLocation(LI); - MDA.getNonLocalPointerDependency(Loc, !LI->isVolatile(), - LI->getParent(), NLDI); + MDA.getNonLocalPointerDependency(Loc, true, LI->getParent(), NLDI); } else if (StoreInst *SI = dyn_cast(Inst)) { - // FIXME: Volatile is not handled properly here. + if (!LI->isUnordered()) { + // FIXME: Handle atomic/volatile stores. + Deps[Inst].insert(std::make_pair(InstAndClobberFlag(0, false), + static_cast(0))); + continue; + } AliasAnalysis::Location Loc = AA.getLocation(SI); MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI); } else if (VAArgInst *VI = dyn_cast(Inst)) { diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp index 34ba92509e5..cdff85a5134 100644 --- a/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -120,21 +120,27 @@ AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst, AliasAnalysis::Location &Loc, AliasAnalysis *AA) { if (const LoadInst *LI = dyn_cast(Inst)) { - if (LI->isVolatile()) { - Loc = AliasAnalysis::Location(); + if (LI->isUnordered()) { + Loc = AA->getLocation(LI); + return AliasAnalysis::Ref; + } else if (LI->getOrdering() == Monotonic) { + Loc = AA->getLocation(LI); return AliasAnalysis::ModRef; } - Loc = AA->getLocation(LI); - return AliasAnalysis::Ref; + Loc = AliasAnalysis::Location(); + return AliasAnalysis::ModRef; } if (const StoreInst *SI = dyn_cast(Inst)) { - if (SI->isVolatile()) { - Loc = AliasAnalysis::Location(); + if (SI->isUnordered()) { + Loc = AA->getLocation(SI); + return AliasAnalysis::Mod; + } else if (SI->getOrdering() == Monotonic) { + Loc = AA->getLocation(SI); return AliasAnalysis::ModRef; } - Loc = AA->getLocation(SI); - return AliasAnalysis::Mod; + Loc = AliasAnalysis::Location(); + return AliasAnalysis::ModRef; } if (const VAArgInst *V = dyn_cast(Inst)) { @@ -270,8 +276,8 @@ unsigned MemoryDependenceAnalysis:: getLoadLoadClobberFullWidthSize(const Value *MemLocBase, int64_t MemLocOffs, unsigned MemLocSize, const LoadInst *LI, const TargetData &TD) { - // We can only extend non-volatile integer loads. - if (!isa(LI->getType()) || LI->isVolatile()) return 0; + // We can only extend simple integer loads. + if (!isa(LI->getType()) || !LI->isSimple()) return 0; // Get the base of this load. int64_t LIOffs = 0; @@ -369,6 +375,11 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, // Values depend on loads if the pointers are must aliased. This means that // a load depends on another must aliased load from the same value. if (LoadInst *LI = dyn_cast(Inst)) { + // Atomic loads have complications involved. + // FIXME: This is overly conservative. + if (!LI->isUnordered()) + return MemDepResult::getClobber(LI); + AliasAnalysis::Location LoadLoc = AA->getLocation(LI); // If we found a pointer, check if it could be the same as our pointer. @@ -424,6 +435,11 @@ getPointerDependencyFrom(const AliasAnalysis::Location &MemLoc, bool isLoad, } if (StoreInst *SI = dyn_cast(Inst)) { + // Atomic stores have complications involved. + // FIXME: This is overly conservative. + if (!SI->isUnordered()) + return MemDepResult::getClobber(SI); + // 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. -- 2.34.1