diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:39 +0300 |
commit | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch) | |
tree | 64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp | |
parent | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff) | |
download | ydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp | 350 |
1 files changed, 175 insertions, 175 deletions
diff --git a/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp b/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp index a5ce422acf..4722b68e20 100644 --- a/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp +++ b/contrib/libs/llvm12/lib/Analysis/MemorySSA.cpp @@ -24,7 +24,7 @@ #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/CFGPrinter.h" +#include "llvm/Analysis/CFGPrinter.h" #include "llvm/Analysis/IteratedDominanceFrontier.h" #include "llvm/Analysis/MemoryLocation.h" #include "llvm/Config/llvm-config.h" @@ -60,11 +60,11 @@ using namespace llvm; #define DEBUG_TYPE "memoryssa" -static cl::opt<std::string> - DotCFGMSSA("dot-cfg-mssa", - cl::value_desc("file name for generated dot file"), - cl::desc("file name for generated dot file"), cl::init("")); - +static cl::opt<std::string> + DotCFGMSSA("dot-cfg-mssa", + cl::value_desc("file name for generated dot file"), + cl::desc("file name for generated dot file"), cl::init("")); + INITIALIZE_PASS_BEGIN(MemorySSAWrapperPass, "memoryssa", "Memory SSA", false, true) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) @@ -284,7 +284,7 @@ instructionClobbersQuery(const MemoryDef *MD, const MemoryLocation &UseLoc, case Intrinsic::invariant_start: case Intrinsic::invariant_end: case Intrinsic::assume: - case Intrinsic::experimental_noalias_scope_decl: + case Intrinsic::experimental_noalias_scope_decl: return {false, NoAlias}; case Intrinsic::dbg_addr: case Intrinsic::dbg_declare: @@ -296,14 +296,14 @@ instructionClobbersQuery(const MemoryDef *MD, const MemoryLocation &UseLoc, } } - if (auto *CB = dyn_cast_or_null<CallBase>(UseInst)) { - ModRefInfo I = AA.getModRefInfo(DefInst, CB); + if (auto *CB = dyn_cast_or_null<CallBase>(UseInst)) { + ModRefInfo I = AA.getModRefInfo(DefInst, CB); AR = isMustSet(I) ? MustAlias : MayAlias; return {isModOrRefSet(I), AR}; } if (auto *DefLoad = dyn_cast<LoadInst>(DefInst)) - if (auto *UseLoad = dyn_cast_or_null<LoadInst>(UseInst)) + if (auto *UseLoad = dyn_cast_or_null<LoadInst>(UseInst)) return {!areLoadsReorderable(UseLoad, DefLoad), MayAlias}; ModRefInfo I = AA.getModRefInfo(DefInst, UseLoc); @@ -362,10 +362,10 @@ static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysisType &AA, const Instruction *I) { // If the memory can't be changed, then loads of the memory can't be // clobbered. - if (auto *LI = dyn_cast<LoadInst>(I)) - return I->hasMetadata(LLVMContext::MD_invariant_load) || - AA.pointsToConstantMemory(MemoryLocation::get(LI)); - return false; + if (auto *LI = dyn_cast<LoadInst>(I)) + return I->hasMetadata(LLVMContext::MD_invariant_load) || + AA.pointsToConstantMemory(MemoryLocation::get(LI)); + return false; } /// Verifies that `Start` is clobbered by `ClobberAt`, and that nothing @@ -452,15 +452,15 @@ checkClobberSanity(const MemoryAccess *Start, MemoryAccess *ClobberAt, } assert(isa<MemoryPhi>(MA)); - - // Add reachable phi predecessors - for (auto ItB = upward_defs_begin( - {const_cast<MemoryAccess *>(MA), MAP.second}, - MSSA.getDomTree()), - ItE = upward_defs_end(); - ItB != ItE; ++ItB) - if (MSSA.getDomTree().isReachableFromEntry(ItB.getPhiArgBlock())) - Worklist.emplace_back(*ItB); + + // Add reachable phi predecessors + for (auto ItB = upward_defs_begin( + {const_cast<MemoryAccess *>(MA), MAP.second}, + MSSA.getDomTree()), + ItE = upward_defs_end(); + ItB != ItE; ++ItB) + if (MSSA.getDomTree().isReachableFromEntry(ItB.getPhiArgBlock())) + Worklist.emplace_back(*ItB); } } @@ -511,16 +511,16 @@ template <class AliasAnalysisType> class ClobberWalker { UpwardsMemoryQuery *Query; unsigned *UpwardWalkLimit; - // Phi optimization bookkeeping: - // List of DefPath to process during the current phi optimization walk. + // Phi optimization bookkeeping: + // List of DefPath to process during the current phi optimization walk. SmallVector<DefPath, 32> Paths; - // List of visited <Access, Location> pairs; we can skip paths already - // visited with the same memory location. + // List of visited <Access, Location> pairs; we can skip paths already + // visited with the same memory location. DenseSet<ConstMemoryAccessPair> VisitedPhis; - // Record if phi translation has been performed during the current phi - // optimization walk, as merging alias results after phi translation can - // yield incorrect results. Context in PR46156. - bool PerformedPhiTranslation = false; + // Record if phi translation has been performed during the current phi + // optimization walk, as merging alias results after phi translation can + // yield incorrect results. Context in PR46156. + bool PerformedPhiTranslation = false; /// Find the nearest def or phi that `From` can legally be optimized to. const MemoryAccess *getWalkTarget(const MemoryPhi *From) const { @@ -595,9 +595,9 @@ template <class AliasAnalysisType> class ClobberWalker { void addSearches(MemoryPhi *Phi, SmallVectorImpl<ListIndex> &PausedSearches, ListIndex PriorNode) { - auto UpwardDefsBegin = upward_defs_begin({Phi, Paths[PriorNode].Loc}, DT, - &PerformedPhiTranslation); - auto UpwardDefs = make_range(UpwardDefsBegin, upward_defs_end()); + auto UpwardDefsBegin = upward_defs_begin({Phi, Paths[PriorNode].Loc}, DT, + &PerformedPhiTranslation); + auto UpwardDefs = make_range(UpwardDefsBegin, upward_defs_end()); for (const MemoryAccessPair &P : UpwardDefs) { PausedSearches.push_back(Paths.size()); Paths.emplace_back(P.second, P.first, PriorNode); @@ -651,16 +651,16 @@ template <class AliasAnalysisType> class ClobberWalker { // - We still cache things for A, so C only needs to walk up a bit. // If this behavior becomes problematic, we can fix without a ton of extra // work. - if (!VisitedPhis.insert({Node.Last, Node.Loc}).second) { - if (PerformedPhiTranslation) { - // If visiting this path performed Phi translation, don't continue, - // since it may not be correct to merge results from two paths if one - // relies on the phi translation. - TerminatedPath Term{Node.Last, PathIndex}; - return Term; - } + if (!VisitedPhis.insert({Node.Last, Node.Loc}).second) { + if (PerformedPhiTranslation) { + // If visiting this path performed Phi translation, don't continue, + // since it may not be correct to merge results from two paths if one + // relies on the phi translation. + TerminatedPath Term{Node.Last, PathIndex}; + return Term; + } continue; - } + } const MemoryAccess *SkipStopWhere = nullptr; if (Query->SkipSelfAccess && Node.Loc == Query->StartingLoc) { @@ -773,7 +773,7 @@ template <class AliasAnalysisType> class ClobberWalker { /// terminates when a MemoryAccess that clobbers said MemoryLocation is found. OptznResult tryOptimizePhi(MemoryPhi *Phi, MemoryAccess *Start, const MemoryLocation &Loc) { - assert(Paths.empty() && VisitedPhis.empty() && !PerformedPhiTranslation && + assert(Paths.empty() && VisitedPhis.empty() && !PerformedPhiTranslation && "Reset the optimization state."); Paths.emplace_back(Loc, Start, Phi, None); @@ -929,7 +929,7 @@ template <class AliasAnalysisType> class ClobberWalker { void resetPhiOptznState() { Paths.clear(); VisitedPhis.clear(); - PerformedPhiTranslation = false; + PerformedPhiTranslation = false; } public: @@ -1709,11 +1709,11 @@ MemoryUseOrDef *MemorySSA::createDefinedAccess(Instruction *I, if (CreationMustSucceed) assert(NewAccess != nullptr && "Tried to create a memory access for a " "non-memory touching instruction"); - if (NewAccess) { - assert((!Definition || !isa<MemoryUse>(Definition)) && - "A use cannot be a defining access"); + if (NewAccess) { + assert((!Definition || !isa<MemoryUse>(Definition)) && + "A use cannot be a defining access"); NewAccess->setDefiningAccess(Definition); - } + } return NewAccess; } @@ -1742,15 +1742,15 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I, // dependencies here. // FIXME: Replace this special casing with a more accurate modelling of // assume's control dependency. - if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { - switch (II->getIntrinsicID()) { - default: - break; - case Intrinsic::assume: - case Intrinsic::experimental_noalias_scope_decl: + if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) { + switch (II->getIntrinsicID()) { + default: + break; + case Intrinsic::assume: + case Intrinsic::experimental_noalias_scope_decl: return nullptr; - } - } + } + } // Using a nonstandard AA pipelines might leave us with unexpected modref // results for I, so add a check to not model instructions that may not read @@ -1760,8 +1760,8 @@ MemoryUseOrDef *MemorySSA::createNewAccess(Instruction *I, bool Def, Use; if (Template) { - Def = isa<MemoryDef>(Template); - Use = isa<MemoryUse>(Template); + Def = isa<MemoryDef>(Template); + Use = isa<MemoryUse>(Template); #if !defined(NDEBUG) ModRefInfo ModRef = AAP->getModRefInfo(I, None); bool DefCheck, UseCheck; @@ -1981,7 +1981,7 @@ void MemorySSA::verifyOrderingDominationAndDefUses(Function &F) const { "Incomplete MemoryPhi Node"); for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) { verifyUseInDefs(Phi->getIncomingValue(I), Phi); - assert(is_contained(predecessors(&B), Phi->getIncomingBlock(I)) && + assert(is_contained(predecessors(&B), Phi->getIncomingBlock(I)) && "Incoming phi block not a block predecessor"); } #endif @@ -2228,98 +2228,98 @@ void MemorySSAPrinterLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<MemorySSAWrapperPass>(); } -class DOTFuncMSSAInfo { -private: - const Function &F; - MemorySSAAnnotatedWriter MSSAWriter; - -public: - DOTFuncMSSAInfo(const Function &F, MemorySSA &MSSA) - : F(F), MSSAWriter(&MSSA) {} - - const Function *getFunction() { return &F; } - MemorySSAAnnotatedWriter &getWriter() { return MSSAWriter; } -}; - -namespace llvm { - -template <> -struct GraphTraits<DOTFuncMSSAInfo *> : public GraphTraits<const BasicBlock *> { - static NodeRef getEntryNode(DOTFuncMSSAInfo *CFGInfo) { - return &(CFGInfo->getFunction()->getEntryBlock()); - } - - // nodes_iterator/begin/end - Allow iteration over all nodes in the graph - using nodes_iterator = pointer_iterator<Function::const_iterator>; - - static nodes_iterator nodes_begin(DOTFuncMSSAInfo *CFGInfo) { - return nodes_iterator(CFGInfo->getFunction()->begin()); - } - - static nodes_iterator nodes_end(DOTFuncMSSAInfo *CFGInfo) { - return nodes_iterator(CFGInfo->getFunction()->end()); - } - - static size_t size(DOTFuncMSSAInfo *CFGInfo) { - return CFGInfo->getFunction()->size(); - } -}; - -template <> -struct DOTGraphTraits<DOTFuncMSSAInfo *> : public DefaultDOTGraphTraits { - - DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {} - - static std::string getGraphName(DOTFuncMSSAInfo *CFGInfo) { - return "MSSA CFG for '" + CFGInfo->getFunction()->getName().str() + - "' function"; - } - - std::string getNodeLabel(const BasicBlock *Node, DOTFuncMSSAInfo *CFGInfo) { - return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel( - Node, nullptr, - [CFGInfo](raw_string_ostream &OS, const BasicBlock &BB) -> void { - BB.print(OS, &CFGInfo->getWriter(), true, true); - }, - [](std::string &S, unsigned &I, unsigned Idx) -> void { - std::string Str = S.substr(I, Idx - I); - StringRef SR = Str; - if (SR.count(" = MemoryDef(") || SR.count(" = MemoryPhi(") || - SR.count("MemoryUse(")) - return; - DOTGraphTraits<DOTFuncInfo *>::eraseComment(S, I, Idx); - }); - } - - static std::string getEdgeSourceLabel(const BasicBlock *Node, - const_succ_iterator I) { - return DOTGraphTraits<DOTFuncInfo *>::getEdgeSourceLabel(Node, I); - } - - /// Display the raw branch weights from PGO. - std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, - DOTFuncMSSAInfo *CFGInfo) { - return ""; - } - - std::string getNodeAttributes(const BasicBlock *Node, - DOTFuncMSSAInfo *CFGInfo) { - return getNodeLabel(Node, CFGInfo).find(';') != std::string::npos - ? "style=filled, fillcolor=lightpink" - : ""; - } -}; - -} // namespace llvm - +class DOTFuncMSSAInfo { +private: + const Function &F; + MemorySSAAnnotatedWriter MSSAWriter; + +public: + DOTFuncMSSAInfo(const Function &F, MemorySSA &MSSA) + : F(F), MSSAWriter(&MSSA) {} + + const Function *getFunction() { return &F; } + MemorySSAAnnotatedWriter &getWriter() { return MSSAWriter; } +}; + +namespace llvm { + +template <> +struct GraphTraits<DOTFuncMSSAInfo *> : public GraphTraits<const BasicBlock *> { + static NodeRef getEntryNode(DOTFuncMSSAInfo *CFGInfo) { + return &(CFGInfo->getFunction()->getEntryBlock()); + } + + // nodes_iterator/begin/end - Allow iteration over all nodes in the graph + using nodes_iterator = pointer_iterator<Function::const_iterator>; + + static nodes_iterator nodes_begin(DOTFuncMSSAInfo *CFGInfo) { + return nodes_iterator(CFGInfo->getFunction()->begin()); + } + + static nodes_iterator nodes_end(DOTFuncMSSAInfo *CFGInfo) { + return nodes_iterator(CFGInfo->getFunction()->end()); + } + + static size_t size(DOTFuncMSSAInfo *CFGInfo) { + return CFGInfo->getFunction()->size(); + } +}; + +template <> +struct DOTGraphTraits<DOTFuncMSSAInfo *> : public DefaultDOTGraphTraits { + + DOTGraphTraits(bool IsSimple = false) : DefaultDOTGraphTraits(IsSimple) {} + + static std::string getGraphName(DOTFuncMSSAInfo *CFGInfo) { + return "MSSA CFG for '" + CFGInfo->getFunction()->getName().str() + + "' function"; + } + + std::string getNodeLabel(const BasicBlock *Node, DOTFuncMSSAInfo *CFGInfo) { + return DOTGraphTraits<DOTFuncInfo *>::getCompleteNodeLabel( + Node, nullptr, + [CFGInfo](raw_string_ostream &OS, const BasicBlock &BB) -> void { + BB.print(OS, &CFGInfo->getWriter(), true, true); + }, + [](std::string &S, unsigned &I, unsigned Idx) -> void { + std::string Str = S.substr(I, Idx - I); + StringRef SR = Str; + if (SR.count(" = MemoryDef(") || SR.count(" = MemoryPhi(") || + SR.count("MemoryUse(")) + return; + DOTGraphTraits<DOTFuncInfo *>::eraseComment(S, I, Idx); + }); + } + + static std::string getEdgeSourceLabel(const BasicBlock *Node, + const_succ_iterator I) { + return DOTGraphTraits<DOTFuncInfo *>::getEdgeSourceLabel(Node, I); + } + + /// Display the raw branch weights from PGO. + std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I, + DOTFuncMSSAInfo *CFGInfo) { + return ""; + } + + std::string getNodeAttributes(const BasicBlock *Node, + DOTFuncMSSAInfo *CFGInfo) { + return getNodeLabel(Node, CFGInfo).find(';') != std::string::npos + ? "style=filled, fillcolor=lightpink" + : ""; + } +}; + +} // namespace llvm + bool MemorySSAPrinterLegacyPass::runOnFunction(Function &F) { auto &MSSA = getAnalysis<MemorySSAWrapperPass>().getMSSA(); - if (DotCFGMSSA != "") { - DOTFuncMSSAInfo CFGInfo(F, MSSA); - WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA); - } else - MSSA.print(dbgs()); - + if (DotCFGMSSA != "") { + DOTFuncMSSAInfo CFGInfo(F, MSSA); + WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA); + } else + MSSA.print(dbgs()); + if (VerifyMemorySSA) MSSA.verifyMemorySSA(); return false; @@ -2345,14 +2345,14 @@ bool MemorySSAAnalysis::Result::invalidate( PreservedAnalyses MemorySSAPrinterPass::run(Function &F, FunctionAnalysisManager &AM) { - auto &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA(); - if (DotCFGMSSA != "") { - DOTFuncMSSAInfo CFGInfo(F, MSSA); - WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA); - } else { - OS << "MemorySSA for function: " << F.getName() << "\n"; - MSSA.print(OS); - } + auto &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA(); + if (DotCFGMSSA != "") { + DOTFuncMSSAInfo CFGInfo(F, MSSA); + WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA); + } else { + OS << "MemorySSA for function: " << F.getName() << "\n"; + MSSA.print(OS); + } return PreservedAnalyses::all(); } @@ -2422,7 +2422,7 @@ MemorySSA::ClobberWalkerBase<AliasAnalysisType>::getClobberingMemoryAccessBase( UpwardsMemoryQuery Q; Q.OriginalAccess = StartingUseOrDef; Q.StartingLoc = Loc; - Q.Inst = nullptr; + Q.Inst = nullptr; Q.IsCall = false; // Unlike the other function, do not walk to the def of a def, because we are @@ -2544,19 +2544,19 @@ void MemoryDef::deleteMe(DerivedUser *Self) { void MemoryUse::deleteMe(DerivedUser *Self) { delete static_cast<MemoryUse *>(Self); } - -bool upward_defs_iterator::IsGuaranteedLoopInvariant(Value *Ptr) const { - auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) { - Ptr = Ptr->stripPointerCasts(); - if (!isa<Instruction>(Ptr)) - return true; - return isa<AllocaInst>(Ptr); - }; - - Ptr = Ptr->stripPointerCasts(); - if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) { - return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) && - GEP->hasAllConstantIndices(); - } - return IsGuaranteedLoopInvariantBase(Ptr); -} + +bool upward_defs_iterator::IsGuaranteedLoopInvariant(Value *Ptr) const { + auto IsGuaranteedLoopInvariantBase = [](Value *Ptr) { + Ptr = Ptr->stripPointerCasts(); + if (!isa<Instruction>(Ptr)) + return true; + return isa<AllocaInst>(Ptr); + }; + + Ptr = Ptr->stripPointerCasts(); + if (auto *GEP = dyn_cast<GEPOperator>(Ptr)) { + return IsGuaranteedLoopInvariantBase(GEP->getPointerOperand()) && + GEP->hasAllConstantIndices(); + } + return IsGuaranteedLoopInvariantBase(Ptr); +} |