003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Analysis
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Analysis
/
📁
..
📄
AliasAnalysis.cpp
(33.55 KB)
📄
AliasAnalysisEvaluator.cpp
(15.64 KB)
📄
AliasAnalysisSummary.cpp
(3.49 KB)
📄
AliasAnalysisSummary.h
(10.17 KB)
📄
AliasSetTracker.cpp
(25.86 KB)
📄
Analysis.cpp
(5.29 KB)
📄
AssumeBundleQueries.cpp
(7.96 KB)
📄
AssumptionCache.cpp
(10.94 KB)
📄
BasicAliasAnalysis.cpp
(85.81 KB)
📄
BlockFrequencyInfo.cpp
(12.39 KB)
📄
BlockFrequencyInfoImpl.cpp
(28.6 KB)
📄
BranchProbabilityInfo.cpp
(43.48 KB)
📄
CFG.cpp
(9.9 KB)
📄
CFGPrinter.cpp
(11.2 KB)
📄
CFLAndersAliasAnalysis.cpp
(33.01 KB)
📄
CFLGraph.h
(21.23 KB)
📄
CFLSteensAliasAnalysis.cpp
(13.24 KB)
📄
CGSCCPassManager.cpp
(31.2 KB)
📄
CallGraph.cpp
(12.86 KB)
📄
CallGraphSCCPass.cpp
(26.31 KB)
📄
CallPrinter.cpp
(9.48 KB)
📄
CaptureTracking.cpp
(15.38 KB)
📄
CmpInstAnalysis.cpp
(4.63 KB)
📄
CodeMetrics.cpp
(6.99 KB)
📄
ConstantFolding.cpp
(105.15 KB)
📄
CostModel.cpp
(3.87 KB)
📄
DDG.cpp
(11.29 KB)
📄
Delinearization.cpp
(4.49 KB)
📄
DemandedBits.cpp
(16.27 KB)
📄
DependenceAnalysis.cpp
(150.78 KB)
📄
DependenceGraphBuilder.cpp
(19.24 KB)
📄
DivergenceAnalysis.cpp
(15.59 KB)
📄
DomPrinter.cpp
(9.67 KB)
📄
DomTreeUpdater.cpp
(15.21 KB)
📄
DominanceFrontier.cpp
(3.2 KB)
📄
EHPersonalities.cpp
(5.89 KB)
📄
GlobalsModRef.cpp
(41 KB)
📄
GuardUtils.cpp
(3.27 KB)
📄
HeatUtils.cpp
(2.85 KB)
📄
IVDescriptors.cpp
(42.28 KB)
📄
IVUsers.cpp
(16.12 KB)
📄
IndirectCallPromotionAnalysis.cpp
(4.33 KB)
📄
InlineAdvisor.cpp
(15.28 KB)
📄
InlineCost.cpp
(99.47 KB)
📄
InlineFeaturesAnalysis.cpp
(1.59 KB)
📄
InlineSizeEstimatorAnalysis.cpp
(10.95 KB)
📄
InstCount.cpp
(2.45 KB)
📄
InstructionPrecedenceTracking.cpp
(4.8 KB)
📄
InstructionSimplify.cpp
(216.91 KB)
📄
Interval.cpp
(1.78 KB)
📄
IntervalPartition.cpp
(4.5 KB)
📄
LazyBlockFrequencyInfo.cpp
(2.81 KB)
📄
LazyBranchProbabilityInfo.cpp
(2.96 KB)
📄
LazyCallGraph.cpp
(67.33 KB)
📄
LazyValueInfo.cpp
(76.38 KB)
📄
LegacyDivergenceAnalysis.cpp
(14.82 KB)
📄
Lint.cpp
(29.07 KB)
📄
Loads.cpp
(20.6 KB)
📄
LoopAccessAnalysis.cpp
(88.02 KB)
📄
LoopAnalysisManager.cpp
(6.6 KB)
📄
LoopCacheAnalysis.cpp
(23.53 KB)
📄
LoopInfo.cpp
(37.15 KB)
📄
LoopNestAnalysis.cpp
(10.62 KB)
📄
LoopPass.cpp
(12.89 KB)
📄
LoopUnrollAnalyzer.cpp
(7.26 KB)
📄
MLInlineAdvisor.cpp
(11.36 KB)
📄
MemDepPrinter.cpp
(5.13 KB)
📄
MemDerefPrinter.cpp
(2.53 KB)
📄
MemoryBuiltins.cpp
(41.14 KB)
📄
MemoryDependenceAnalysis.cpp
(69.89 KB)
📄
MemoryLocation.cpp
(7.92 KB)
📄
MemorySSA.cpp
(90.16 KB)
📄
MemorySSAUpdater.cpp
(57.9 KB)
📄
ModuleDebugInfoPrinter.cpp
(4.02 KB)
📄
ModuleSummaryAnalysis.cpp
(38.13 KB)
📄
MustExecute.cpp
(31.18 KB)
📄
ObjCARCAliasAnalysis.cpp
(5.81 KB)
📄
ObjCARCAnalysisUtils.cpp
(1.07 KB)
📄
ObjCARCInstKind.cpp
(23.15 KB)
📄
OptimizationRemarkEmitter.cpp
(4.23 KB)
📄
PHITransAddr.cpp
(16.05 KB)
📄
PhiValues.cpp
(8.4 KB)
📄
PostDominators.cpp
(3.59 KB)
📄
ProfileSummaryInfo.cpp
(18.07 KB)
📄
PtrUseVisitor.cpp
(1.28 KB)
📄
RegionInfo.cpp
(6.5 KB)
📄
RegionPass.cpp
(9.23 KB)
📄
RegionPrinter.cpp
(8.61 KB)
📄
ReleaseModeModelRunner.cpp
(2.83 KB)
📄
ScalarEvolution.cpp
(475.26 KB)
📄
ScalarEvolutionAliasAnalysis.cpp
(5.96 KB)
📄
ScalarEvolutionDivision.cpp
(7.51 KB)
📄
ScalarEvolutionNormalization.cpp
(4.59 KB)
📄
ScopedNoAliasAA.cpp
(7.38 KB)
📄
StackLifetime.cpp
(12.22 KB)
📄
StackSafetyAnalysis.cpp
(31.81 KB)
📄
StratifiedSets.h
(18.67 KB)
📄
SyncDependenceAnalysis.cpp
(12.97 KB)
📄
SyntheticCountsUtils.cpp
(3.81 KB)
📄
TFUtils.cpp
(8.99 KB)
📄
TargetLibraryInfo.cpp
(58.98 KB)
📄
TargetTransformInfo.cpp
(48.15 KB)
📄
Trace.cpp
(1.8 KB)
📄
TypeBasedAliasAnalysis.cpp
(26.04 KB)
📄
TypeMetadataUtils.cpp
(5.93 KB)
📄
VFABIDemangling.cpp
(16.46 KB)
📄
ValueLattice.cpp
(1.19 KB)
📄
ValueLatticeUtils.cpp
(1.53 KB)
📄
ValueTracking.cpp
(243.08 KB)
📄
VectorUtils.cpp
(48.57 KB)
📁
models
Editing: DomTreeUpdater.cpp
//===- DomTreeUpdater.cpp - DomTree/Post DomTree Updater --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the DomTreeUpdater class, which provides a uniform way // to update dominator tree related data structures. // //===----------------------------------------------------------------------===// #include "llvm/Analysis/DomTreeUpdater.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/GenericDomTree.h" #include <algorithm> #include <functional> #include <utility> namespace llvm { bool DomTreeUpdater::isUpdateValid( const DominatorTree::UpdateType Update) const { const auto *From = Update.getFrom(); const auto *To = Update.getTo(); const auto Kind = Update.getKind(); // Discard updates by inspecting the current state of successors of From. // Since isUpdateValid() must be called *after* the Terminator of From is // altered we can determine if the update is unnecessary for batch updates // or invalid for a single update. const bool HasEdge = llvm::any_of( successors(From), [To](const BasicBlock *B) { return B == To; }); // If the IR does not match the update, // 1. In batch updates, this update is unnecessary. // 2. When called by insertEdge*()/deleteEdge*(), this update is invalid. // Edge does not exist in IR. if (Kind == DominatorTree::Insert && !HasEdge) return false; // Edge exists in IR. if (Kind == DominatorTree::Delete && HasEdge) return false; return true; } bool DomTreeUpdater::isSelfDominance( const DominatorTree::UpdateType Update) const { // Won't affect DomTree and PostDomTree. return Update.getFrom() == Update.getTo(); } void DomTreeUpdater::applyDomTreeUpdates() { // No pending DomTreeUpdates. if (Strategy != UpdateStrategy::Lazy || !DT) return; // Only apply updates not are applied by DomTree. if (hasPendingDomTreeUpdates()) { const auto I = PendUpdates.begin() + PendDTUpdateIndex; const auto E = PendUpdates.end(); assert(I < E && "Iterator range invalid; there should be DomTree updates."); DT->applyUpdates(ArrayRef<DominatorTree::UpdateType>(I, E)); PendDTUpdateIndex = PendUpdates.size(); } } void DomTreeUpdater::flush() { applyDomTreeUpdates(); applyPostDomTreeUpdates(); dropOutOfDateUpdates(); } void DomTreeUpdater::applyPostDomTreeUpdates() { // No pending PostDomTreeUpdates. if (Strategy != UpdateStrategy::Lazy || !PDT) return; // Only apply updates not are applied by PostDomTree. if (hasPendingPostDomTreeUpdates()) { const auto I = PendUpdates.begin() + PendPDTUpdateIndex; const auto E = PendUpdates.end(); assert(I < E && "Iterator range invalid; there should be PostDomTree updates."); PDT->applyUpdates(ArrayRef<DominatorTree::UpdateType>(I, E)); PendPDTUpdateIndex = PendUpdates.size(); } } void DomTreeUpdater::tryFlushDeletedBB() { if (!hasPendingUpdates()) forceFlushDeletedBB(); } bool DomTreeUpdater::forceFlushDeletedBB() { if (DeletedBBs.empty()) return false; for (auto *BB : DeletedBBs) { // After calling deleteBB or callbackDeleteBB under Lazy UpdateStrategy, // validateDeleteBB() removes all instructions of DelBB and adds an // UnreachableInst as its terminator. So we check whether the BasicBlock to // delete only has an UnreachableInst inside. assert(BB->getInstList().size() == 1 && isa<UnreachableInst>(BB->getTerminator()) && "DelBB has been modified while awaiting deletion."); BB->removeFromParent(); eraseDelBBNode(BB); delete BB; } DeletedBBs.clear(); Callbacks.clear(); return true; } void DomTreeUpdater::recalculate(Function &F) { if (Strategy == UpdateStrategy::Eager) { if (DT) DT->recalculate(F); if (PDT) PDT->recalculate(F); return; } // There is little performance gain if we pend the recalculation under // Lazy UpdateStrategy so we recalculate available trees immediately. // Prevent forceFlushDeletedBB() from erasing DomTree or PostDomTree nodes. IsRecalculatingDomTree = IsRecalculatingPostDomTree = true; // Because all trees are going to be up-to-date after recalculation, // flush awaiting deleted BasicBlocks. forceFlushDeletedBB(); if (DT) DT->recalculate(F); if (PDT) PDT->recalculate(F); // Resume forceFlushDeletedBB() to erase DomTree or PostDomTree nodes. IsRecalculatingDomTree = IsRecalculatingPostDomTree = false; PendDTUpdateIndex = PendPDTUpdateIndex = PendUpdates.size(); dropOutOfDateUpdates(); } bool DomTreeUpdater::hasPendingUpdates() const { return hasPendingDomTreeUpdates() || hasPendingPostDomTreeUpdates(); } bool DomTreeUpdater::hasPendingDomTreeUpdates() const { if (!DT) return false; return PendUpdates.size() != PendDTUpdateIndex; } bool DomTreeUpdater::hasPendingPostDomTreeUpdates() const { if (!PDT) return false; return PendUpdates.size() != PendPDTUpdateIndex; } bool DomTreeUpdater::isBBPendingDeletion(llvm::BasicBlock *DelBB) const { if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty()) return false; return DeletedBBs.count(DelBB) != 0; } // The DT and PDT require the nodes related to updates // are not deleted when update functions are called. // So BasicBlock deletions must be pended when the // UpdateStrategy is Lazy. When the UpdateStrategy is // Eager, the BasicBlock will be deleted immediately. void DomTreeUpdater::deleteBB(BasicBlock *DelBB) { validateDeleteBB(DelBB); if (Strategy == UpdateStrategy::Lazy) { DeletedBBs.insert(DelBB); return; } DelBB->removeFromParent(); eraseDelBBNode(DelBB); delete DelBB; } void DomTreeUpdater::callbackDeleteBB( BasicBlock *DelBB, std::function<void(BasicBlock *)> Callback) { validateDeleteBB(DelBB); if (Strategy == UpdateStrategy::Lazy) { Callbacks.push_back(CallBackOnDeletion(DelBB, Callback)); DeletedBBs.insert(DelBB); return; } DelBB->removeFromParent(); eraseDelBBNode(DelBB); Callback(DelBB); delete DelBB; } void DomTreeUpdater::eraseDelBBNode(BasicBlock *DelBB) { if (DT && !IsRecalculatingDomTree) if (DT->getNode(DelBB)) DT->eraseNode(DelBB); if (PDT && !IsRecalculatingPostDomTree) if (PDT->getNode(DelBB)) PDT->eraseNode(DelBB); } void DomTreeUpdater::validateDeleteBB(BasicBlock *DelBB) { assert(DelBB && "Invalid push_back of nullptr DelBB."); assert(pred_empty(DelBB) && "DelBB has one or more predecessors."); // DelBB is unreachable and all its instructions are dead. while (!DelBB->empty()) { Instruction &I = DelBB->back(); // Replace used instructions with an arbitrary value (undef). if (!I.use_empty()) I.replaceAllUsesWith(llvm::UndefValue::get(I.getType())); DelBB->getInstList().pop_back(); } // Make sure DelBB has a valid terminator instruction. As long as DelBB is a // Child of Function F it must contain valid IR. new UnreachableInst(DelBB->getContext(), DelBB); } void DomTreeUpdater::applyUpdates(ArrayRef<DominatorTree::UpdateType> Updates) { if (!DT && !PDT) return; if (Strategy == UpdateStrategy::Lazy) { for (const auto &U : Updates) if (!isSelfDominance(U)) PendUpdates.push_back(U); return; } if (DT) DT->applyUpdates(Updates); if (PDT) PDT->applyUpdates(Updates); } void DomTreeUpdater::applyUpdatesPermissive( ArrayRef<DominatorTree::UpdateType> Updates) { if (!DT && !PDT) return; SmallSet<std::pair<BasicBlock *, BasicBlock *>, 8> Seen; SmallVector<DominatorTree::UpdateType, 8> DeduplicatedUpdates; for (const auto &U : Updates) { auto Edge = std::make_pair(U.getFrom(), U.getTo()); // Because it is illegal to submit updates that have already been applied // and updates to an edge need to be strictly ordered, // it is safe to infer the existence of an edge from the first update // to this edge. // If the first update to an edge is "Delete", it means that the edge // existed before. If the first update to an edge is "Insert", it means // that the edge didn't exist before. // // For example, if the user submits {{Delete, A, B}, {Insert, A, B}}, // because // 1. it is illegal to submit updates that have already been applied, // i.e., user cannot delete an nonexistent edge, // 2. updates to an edge need to be strictly ordered, // So, initially edge A -> B existed. // We can then safely ignore future updates to this edge and directly // inspect the current CFG: // a. If the edge still exists, because the user cannot insert an existent // edge, so both {Delete, A, B}, {Insert, A, B} actually happened and // resulted in a no-op. DTU won't submit any update in this case. // b. If the edge doesn't exist, we can then infer that {Delete, A, B} // actually happened but {Insert, A, B} was an invalid update which never // happened. DTU will submit {Delete, A, B} in this case. if (!isSelfDominance(U) && Seen.count(Edge) == 0) { Seen.insert(Edge); // If the update doesn't appear in the CFG, it means that // either the change isn't made or relevant operations // result in a no-op. if (isUpdateValid(U)) { if (isLazy()) PendUpdates.push_back(U); else DeduplicatedUpdates.push_back(U); } } } if (Strategy == UpdateStrategy::Lazy) return; if (DT) DT->applyUpdates(DeduplicatedUpdates); if (PDT) PDT->applyUpdates(DeduplicatedUpdates); } DominatorTree &DomTreeUpdater::getDomTree() { assert(DT && "Invalid acquisition of a null DomTree"); applyDomTreeUpdates(); dropOutOfDateUpdates(); return *DT; } PostDominatorTree &DomTreeUpdater::getPostDomTree() { assert(PDT && "Invalid acquisition of a null PostDomTree"); applyPostDomTreeUpdates(); dropOutOfDateUpdates(); return *PDT; } void DomTreeUpdater::insertEdge(BasicBlock *From, BasicBlock *To) { #ifndef NDEBUG assert(isUpdateValid({DominatorTree::Insert, From, To}) && "Inserted edge does not appear in the CFG"); #endif if (!DT && !PDT) return; // Won't affect DomTree and PostDomTree; discard update. if (From == To) return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->insertEdge(From, To); if (PDT) PDT->insertEdge(From, To); return; } PendUpdates.push_back({DominatorTree::Insert, From, To}); } void DomTreeUpdater::insertEdgeRelaxed(BasicBlock *From, BasicBlock *To) { if (From == To) return; if (!DT && !PDT) return; if (!isUpdateValid({DominatorTree::Insert, From, To})) return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->insertEdge(From, To); if (PDT) PDT->insertEdge(From, To); return; } PendUpdates.push_back({DominatorTree::Insert, From, To}); } void DomTreeUpdater::deleteEdge(BasicBlock *From, BasicBlock *To) { #ifndef NDEBUG assert(isUpdateValid({DominatorTree::Delete, From, To}) && "Deleted edge still exists in the CFG!"); #endif if (!DT && !PDT) return; // Won't affect DomTree and PostDomTree; discard update. if (From == To) return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->deleteEdge(From, To); if (PDT) PDT->deleteEdge(From, To); return; } PendUpdates.push_back({DominatorTree::Delete, From, To}); } void DomTreeUpdater::deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To) { if (From == To) return; if (!DT && !PDT) return; if (!isUpdateValid({DominatorTree::Delete, From, To})) return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->deleteEdge(From, To); if (PDT) PDT->deleteEdge(From, To); return; } PendUpdates.push_back({DominatorTree::Delete, From, To}); } void DomTreeUpdater::dropOutOfDateUpdates() { if (Strategy == DomTreeUpdater::UpdateStrategy::Eager) return; tryFlushDeletedBB(); // Drop all updates applied by both trees. if (!DT) PendDTUpdateIndex = PendUpdates.size(); if (!PDT) PendPDTUpdateIndex = PendUpdates.size(); const size_t dropIndex = std::min(PendDTUpdateIndex, PendPDTUpdateIndex); const auto B = PendUpdates.begin(); const auto E = PendUpdates.begin() + dropIndex; assert(B <= E && "Iterator out of range."); PendUpdates.erase(B, E); // Calculate current index. PendDTUpdateIndex -= dropIndex; PendPDTUpdateIndex -= dropIndex; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void DomTreeUpdater::dump() const { raw_ostream &OS = llvm::dbgs(); OS << "Available Trees: "; if (DT || PDT) { if (DT) OS << "DomTree "; if (PDT) OS << "PostDomTree "; OS << "\n"; } else OS << "None\n"; OS << "UpdateStrategy: "; if (Strategy == UpdateStrategy::Eager) { OS << "Eager\n"; return; } else OS << "Lazy\n"; int Index = 0; auto printUpdates = [&](ArrayRef<DominatorTree::UpdateType>::const_iterator begin, ArrayRef<DominatorTree::UpdateType>::const_iterator end) { if (begin == end) OS << " None\n"; Index = 0; for (auto It = begin, ItEnd = end; It != ItEnd; ++It) { auto U = *It; OS << " " << Index << " : "; ++Index; if (U.getKind() == DominatorTree::Insert) OS << "Insert, "; else OS << "Delete, "; BasicBlock *From = U.getFrom(); if (From) { auto S = From->getName(); if (!From->hasName()) S = "(no name)"; OS << S << "(" << From << "), "; } else { OS << "(badref), "; } BasicBlock *To = U.getTo(); if (To) { auto S = To->getName(); if (!To->hasName()) S = "(no_name)"; OS << S << "(" << To << ")\n"; } else { OS << "(badref)\n"; } } }; if (DT) { const auto I = PendUpdates.begin() + PendDTUpdateIndex; assert(PendUpdates.begin() <= I && I <= PendUpdates.end() && "Iterator out of range."); OS << "Applied but not cleared DomTreeUpdates:\n"; printUpdates(PendUpdates.begin(), I); OS << "Pending DomTreeUpdates:\n"; printUpdates(I, PendUpdates.end()); } if (PDT) { const auto I = PendUpdates.begin() + PendPDTUpdateIndex; assert(PendUpdates.begin() <= I && I <= PendUpdates.end() && "Iterator out of range."); OS << "Applied but not cleared PostDomTreeUpdates:\n"; printUpdates(PendUpdates.begin(), I); OS << "Pending PostDomTreeUpdates:\n"; printUpdates(I, PendUpdates.end()); } OS << "Pending DeletedBBs:\n"; Index = 0; for (const auto *BB : DeletedBBs) { OS << " " << Index << " : "; ++Index; if (BB->hasName()) OS << BB->getName() << "("; else OS << "(no_name)("; OS << BB << ")\n"; } OS << "Pending Callbacks:\n"; Index = 0; for (const auto &BB : Callbacks) { OS << " " << Index << " : "; ++Index; if (BB->hasName()) OS << BB->getName() << "("; else OS << "(no_name)("; OS << BB << ")\n"; } } #endif } // namespace llvm
Upload File
Create Folder