Index: include/llvm/Analysis/AliasAnalysis.h =================================================================== --- include/llvm/Analysis/AliasAnalysis.h +++ 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/IR/CallSite.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/PassManager.h" @@ -500,46 +501,47 @@ return getModRefInfo(I, MemoryLocation(P, Size)); } - /// Check whether or not an instruction may read or write memory (without - /// regard to a specific 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. + /// Check whether or not an instruction may read or write the optionally + /// specified memory location. /// /// 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 specific + /// helpers above. + ModRefInfo getModRefInfo(const Instruction *I, + const Optional &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); - case Instruction::Store: return getModRefInfo((const StoreInst*)I, Loc); - case Instruction::Fence: return getModRefInfo((const FenceInst*)I, Loc); + case Instruction::VAArg: + return getModRefInfo((const VAArgInst *)I, Loc); + case Instruction::Load: + return getModRefInfo((const LoadInst *)I, Loc); + case Instruction::Store: + return getModRefInfo((const StoreInst *)I, Loc); + case Instruction::Fence: + return getModRefInfo((const FenceInst *)I, Loc); case Instruction::AtomicCmpXchg: - return getModRefInfo((const AtomicCmpXchgInst*)I, Loc); + return getModRefInfo((const AtomicCmpXchgInst *)I, Loc); case Instruction::AtomicRMW: - return getModRefInfo((const AtomicRMWInst*)I, Loc); - case Instruction::Call: return getModRefInfo((const CallInst*)I, Loc); - case Instruction::Invoke: return getModRefInfo((const InvokeInst*)I,Loc); + return getModRefInfo((const AtomicRMWInst *)I, Loc); + case Instruction::Call: + return getModRefInfo((const CallInst *)I, Loc); + case Instruction::Invoke: + return getModRefInfo((const InvokeInst *)I, Loc); case Instruction::CatchPad: return getModRefInfo((const CatchPadInst *)I, Loc); case Instruction::CatchRet: Index: include/llvm/Analysis/MemoryLocation.h =================================================================== --- include/llvm/Analysis/MemoryLocation.h +++ 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 @@ static MemoryLocation get(const AtomicCmpXchgInst *CXI); static MemoryLocation get(const AtomicRMWInst *RMWI); static MemoryLocation get(const Instruction *Inst) { - if (auto *I = dyn_cast(Inst)) - return get(I); - else if (auto *I = dyn_cast(Inst)) - return get(I); - else if (auto *I = dyn_cast(Inst)) - return get(I); - else if (auto *I = dyn_cast(Inst)) - return get(I); - else if (auto *I = dyn_cast(Inst)) - return get(I); - llvm_unreachable("unsupported memory instruction"); + return *MemoryLocation::getOrNone(Inst); + } + static Optional getOrNone(const Instruction *Inst) { + switch (Inst->getOpcode()) { + case Instruction::Load: + return get(cast(Inst)); + case Instruction::Store: + return get(cast(Inst)); + case Instruction::VAArg: + return get(cast(Inst)); + case Instruction::AtomicCmpXchg: + return get(cast(Inst)); + case Instruction::AtomicRMW: + return get(cast(Inst)); + default: + return None; + } } /// Return a location representing the source of a memory transfer. Index: lib/Transforms/Scalar/MemCpyOptimizer.cpp =================================================================== --- lib/Transforms/Scalar/MemCpyOptimizer.cpp +++ lib/Transforms/Scalar/MemCpyOptimizer.cpp @@ -551,7 +551,7 @@ 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, None) != MRI_NoModRef; bool NeedLift = false; if (Args.erase(C)) Index: lib/Transforms/Utils/MemorySSA.cpp =================================================================== --- lib/Transforms/Utils/MemorySSA.cpp +++ lib/Transforms/Utils/MemorySSA.cpp @@ -107,6 +107,21 @@ : MemoryLocOrCall(MUD->getMemoryInst()) {} MemoryLocOrCall(const MemoryUseOrDef *MUD) : MemoryLocOrCall(MUD->getMemoryInst()) {} + ~MemoryLocOrCall() {} + MemoryLocOrCall(const MemoryLocOrCall &MLOC) { + if (IsCall) + CS = MLOC.CS; + else + Loc = MLOC.Loc; + } + + MemoryLocOrCall &operator=(const MemoryLocOrCall &MLOC) { + if (IsCall) + CS = MLOC.CS; + else + Loc = MLOC.Loc; + return *this; + } MemoryLocOrCall(Instruction *Inst) { if (ImmutableCallSite(Inst)) { @@ -114,10 +129,7 @@ CS = ImmutableCallSite(Inst); } else { IsCall = false; - // There is no such thing as a memorylocation for a fence inst, and it is - // unique in that regard. - if (!isa(Inst)) - Loc = MemoryLocation::get(Inst); + Loc = MemoryLocation::getOrNone(Inst); } } @@ -129,11 +141,13 @@ assert(IsCall); return CS; } - MemoryLocation getLoc() const { + const MemoryLocation &getLoc() const { assert(!IsCall); - return Loc; + return *Loc; } + const Optional &getLocOrNone() const { return Loc; } + bool operator==(const MemoryLocOrCall &Other) const { if (IsCall != Other.IsCall) return false; @@ -146,7 +160,7 @@ private: union { ImmutableCallSite CS; - MemoryLocation Loc; + Optional Loc; }; }; } @@ -213,7 +227,7 @@ } static bool instructionClobbersQuery(MemoryDef *MD, - const MemoryLocation &UseLoc, + const Optional &UseLoc, const Instruction *UseInst, AliasAnalysis &AA) { Instruction *DefInst = MD->getMemoryInst(); @@ -248,7 +262,7 @@ case Reorderability::Never: return true; case Reorderability::IfNoAlias: - return !AA.isNoAlias(UseLoc, MemoryLocation::get(DefLoad)); + return !AA.isNoAlias(UseLoc.getValue(), MemoryLocation::get(DefLoad)); } } } @@ -256,22 +270,12 @@ return AA.getModRefInfo(DefInst, UseLoc) & MRI_Mod; } -static bool instructionClobbersQuery(MemoryDef *MD, const MemoryUseOrDef *MU, - const MemoryLocOrCall &UseMLOC, - AliasAnalysis &AA) { - // FIXME: This is a temporary hack to allow a single instructionClobbersQuery - // to exist while MemoryLocOrCall is pushed through places. - if (UseMLOC.IsCall) - return instructionClobbersQuery(MD, MemoryLocation(), MU->getMemoryInst(), - AA); - return instructionClobbersQuery(MD, UseMLOC.getLoc(), MU->getMemoryInst(), - AA); -} - // Return true when MD may alias MU, return false otherwise. bool MemorySSAUtil::defClobbersUseOrDef(MemoryDef *MD, const MemoryUseOrDef *MU, AliasAnalysis &AA) { - return instructionClobbersQuery(MD, MU, MemoryLocOrCall(MU), AA); + return instructionClobbersQuery( + MD, MemoryLocation::getOrNone(MU->getMemoryInst()), MU->getMemoryInst(), + AA); } } @@ -1457,7 +1461,8 @@ FoundClobberResult = true; break; } - if (instructionClobbersQuery(MD, MU, UseMLOC, *AA)) { + if (instructionClobbersQuery(MD, UseMLOC.getLocOrNone(), + MU->getMemoryInst(), *AA)) { FoundClobberResult = true; break; } @@ -1702,7 +1707,7 @@ return nullptr; // Find out what affect this instruction has on memory. - ModRefInfo ModRef = AA->getModRefInfo(I); + ModRefInfo ModRef = AA->getModRefInfo(I, None); bool Def = bool(ModRef & MRI_Mod); bool Use = bool(ModRef & MRI_Ref);