diff options
-rw-r--r-- | llvm/include/llvm/Analysis/AliasAnalysis.h | 55 | ||||
-rw-r--r-- | llvm/include/llvm/Analysis/MemoryLocation.h | 29 | ||||
-rw-r--r-- | llvm/lib/Analysis/MemorySSA.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp | 2 | ||||
-rw-r--r-- | llvm/unittests/Analysis/AliasAnalysisTest.cpp | 12 |
5 files changed, 49 insertions, 51 deletions
diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index e00ae4f3bee..f79931c8402 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -38,6 +38,7 @@ #ifndef LLVM_ANALYSIS_ALIASANALYSIS_H #define LLVM_ANALYSIS_ALIASANALYSIS_H +#include "llvm/ADT/Optional.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/CallSite.h" @@ -500,43 +501,33 @@ public: return getModRefInfo(I, MemoryLocation(P, Size)); } - /// Check whether or not an instruction may read or write memory (without - /// regard to a specific location). + /// Check whether or not an instruction may read or write the optionally + /// specified memory location. /// - /// For function calls, this delegates to the alias-analysis specific - /// call-site mod-ref behavior queries. Otherwise it delegates to the generic - /// mod ref information query without a location. - ModRefInfo getModRefInfo(const Instruction *I) { - if (auto CS = ImmutableCallSite(I)) { - auto MRB = getModRefBehavior(CS); - if ((MRB & MRI_ModRef) == MRI_ModRef) - return MRI_ModRef; - if (MRB & MRI_Ref) - return MRI_Ref; - if (MRB & MRI_Mod) - return MRI_Mod; - return MRI_NoModRef; - } - - return getModRefInfo(I, MemoryLocation()); - } - - /// Check whether or not an instruction may read or write the specified - /// memory location. - /// - /// Note explicitly that getModRefInfo considers the effects of reading and - /// writing the memory location, and not the effect of ordering relative to - /// other instructions. Thus, a volatile load is considered to be Ref, - /// because it does not actually write memory, it just can't be reordered - /// relative to other volatiles (or removed). Atomic ordered loads/stores are - /// considered ModRef ATM because conservatively, the visible effect appears - /// as if memory was written, not just an ordering constraint. /// /// An instruction that doesn't read or write memory may be trivially LICM'd /// for example. /// - /// This primarily delegates to specific helpers above. - ModRefInfo getModRefInfo(const Instruction *I, const MemoryLocation &Loc) { + /// For function calls, this delegates to the alias-analysis specific + /// call-site mod-ref behavior queries. Otherwise it delegates to the specific + /// helpers above. + ModRefInfo getModRefInfo(const Instruction *I, + const Optional<MemoryLocation> &OptLoc) { + if (OptLoc == None) { + if (auto CS = ImmutableCallSite(I)) { + auto MRB = getModRefBehavior(CS); + if ((MRB & MRI_ModRef) == MRI_ModRef) + return MRI_ModRef; + if (MRB & MRI_Ref) + return MRI_Ref; + if (MRB & MRI_Mod) + return MRI_Mod; + return MRI_NoModRef; + } + } + + const MemoryLocation &Loc = OptLoc.getValueOr(MemoryLocation()); + switch (I->getOpcode()) { case Instruction::VAArg: return getModRefInfo((const VAArgInst*)I, Loc); case Instruction::Load: return getModRefInfo((const LoadInst*)I, Loc); diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h index f2cb2a123f2..c1080742e83 100644 --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -16,6 +16,7 @@ #ifndef LLVM_ANALYSIS_MEMORYLOCATION_H #define LLVM_ANALYSIS_MEMORYLOCATION_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Metadata.h" @@ -68,17 +69,23 @@ public: static MemoryLocation get(const AtomicCmpXchgInst *CXI); static MemoryLocation get(const AtomicRMWInst *RMWI); static MemoryLocation get(const Instruction *Inst) { - if (auto *I = dyn_cast<LoadInst>(Inst)) - return get(I); - else if (auto *I = dyn_cast<StoreInst>(Inst)) - return get(I); - else if (auto *I = dyn_cast<VAArgInst>(Inst)) - return get(I); - else if (auto *I = dyn_cast<AtomicCmpXchgInst>(Inst)) - return get(I); - else if (auto *I = dyn_cast<AtomicRMWInst>(Inst)) - return get(I); - llvm_unreachable("unsupported memory instruction"); + return *MemoryLocation::getOrNone(Inst); + } + static Optional<MemoryLocation> getOrNone(const Instruction *Inst) { + switch (Inst->getOpcode()) { + case Instruction::Load: + return get(cast<LoadInst>(Inst)); + case Instruction::Store: + return get(cast<StoreInst>(Inst)); + case Instruction::VAArg: + return get(cast<VAArgInst>(Inst)); + case Instruction::AtomicCmpXchg: + return get(cast<AtomicCmpXchgInst>(Inst)); + case Instruction::AtomicRMW: + return get(cast<AtomicRMWInst>(Inst)); + default: + return None; + } } /// Return a location representing the source of a memory transfer. diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp index 86de474c7aa..dddfb3c5049 100644 --- a/llvm/lib/Analysis/MemorySSA.cpp +++ b/llvm/lib/Analysis/MemorySSA.cpp @@ -1473,7 +1473,7 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I) { return nullptr; // Find out what affect this instruction has on memory. - ModRefInfo ModRef = AA->getModRefInfo(I); + ModRefInfo ModRef = AA->getModRefInfo(I, None); // The isOrdered check is used to ensure that volatiles end up as defs // (atomics end up as ModRef right now anyway). Until we separate the // ordering chain from the memory chain, this enables people to see at least diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp index 7896396f089..12aec1e0bdf 100644 --- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -535,7 +535,7 @@ static bool moveUp(AliasAnalysis &AA, StoreInst *SI, Instruction *P, for (auto I = --SI->getIterator(), E = P->getIterator(); I != E; --I) { auto *C = &*I; - bool MayAlias = AA.getModRefInfo(C) != MRI_NoModRef; + bool MayAlias = AA.getModRefInfo(C, MemoryLocation()) != MRI_NoModRef; bool NeedLift = false; if (Args.erase(C)) diff --git a/llvm/unittests/Analysis/AliasAnalysisTest.cpp b/llvm/unittests/Analysis/AliasAnalysisTest.cpp index 9a864b77a9d..6836c36d618 100644 --- a/llvm/unittests/Analysis/AliasAnalysisTest.cpp +++ b/llvm/unittests/Analysis/AliasAnalysisTest.cpp @@ -192,17 +192,17 @@ TEST_F(AliasAnalysisTest, getModRefInfo) { // Check basic results EXPECT_EQ(AA.getModRefInfo(Store1, MemoryLocation()), MRI_Mod); - EXPECT_EQ(AA.getModRefInfo(Store1), MRI_Mod); + EXPECT_EQ(AA.getModRefInfo(Store1, None), MRI_Mod); EXPECT_EQ(AA.getModRefInfo(Load1, MemoryLocation()), MRI_Ref); - EXPECT_EQ(AA.getModRefInfo(Load1), MRI_Ref); + EXPECT_EQ(AA.getModRefInfo(Load1, None), MRI_Ref); EXPECT_EQ(AA.getModRefInfo(Add1, MemoryLocation()), MRI_NoModRef); - EXPECT_EQ(AA.getModRefInfo(Add1), MRI_NoModRef); + EXPECT_EQ(AA.getModRefInfo(Add1, None), MRI_NoModRef); EXPECT_EQ(AA.getModRefInfo(VAArg1, MemoryLocation()), MRI_ModRef); - EXPECT_EQ(AA.getModRefInfo(VAArg1), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(VAArg1, None), MRI_ModRef); EXPECT_EQ(AA.getModRefInfo(CmpXChg1, MemoryLocation()), MRI_ModRef); - EXPECT_EQ(AA.getModRefInfo(CmpXChg1), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(CmpXChg1, None), MRI_ModRef); EXPECT_EQ(AA.getModRefInfo(AtomicRMW, MemoryLocation()), MRI_ModRef); - EXPECT_EQ(AA.getModRefInfo(AtomicRMW), MRI_ModRef); + EXPECT_EQ(AA.getModRefInfo(AtomicRMW, None), MRI_ModRef); } class AAPassInfraTest : public testing::Test { |