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: StackLifetime.cpp
//===- StackLifetime.cpp - Alloca Lifetime Analysis -----------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "llvm/Analysis/StackLifetime.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" #include <algorithm> #include <memory> #include <tuple> using namespace llvm; #define DEBUG_TYPE "stack-lifetime" const StackLifetime::LiveRange & StackLifetime::getLiveRange(const AllocaInst *AI) const { const auto IT = AllocaNumbering.find(AI); assert(IT != AllocaNumbering.end()); return LiveRanges[IT->second]; } bool StackLifetime::isReachable(const Instruction *I) const { return BlockInstRange.find(I->getParent()) != BlockInstRange.end(); } bool StackLifetime::isAliveAfter(const AllocaInst *AI, const Instruction *I) const { const BasicBlock *BB = I->getParent(); auto ItBB = BlockInstRange.find(BB); assert(ItBB != BlockInstRange.end() && "Unreachable is not expected"); // Search the block for the first instruction following 'I'. auto It = std::upper_bound(Instructions.begin() + ItBB->getSecond().first + 1, Instructions.begin() + ItBB->getSecond().second, I, [](const Instruction *L, const Instruction *R) { return L->comesBefore(R); }); --It; unsigned InstNum = It - Instructions.begin(); return getLiveRange(AI).test(InstNum); } static bool readMarker(const Instruction *I, bool *IsStart) { if (!I->isLifetimeStartOrEnd()) return false; auto *II = cast<IntrinsicInst>(I); *IsStart = II->getIntrinsicID() == Intrinsic::lifetime_start; return true; } void StackLifetime::collectMarkers() { InterestingAllocas.resize(NumAllocas); DenseMap<const BasicBlock *, SmallDenseMap<const IntrinsicInst *, Marker>> BBMarkerSet; // Compute the set of start/end markers per basic block. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { const AllocaInst *AI = Allocas[AllocaNo]; SmallVector<const Instruction *, 8> WorkList; WorkList.push_back(AI); while (!WorkList.empty()) { const Instruction *I = WorkList.pop_back_val(); for (const User *U : I->users()) { if (auto *BI = dyn_cast<BitCastInst>(U)) { WorkList.push_back(BI); continue; } auto *UI = dyn_cast<IntrinsicInst>(U); if (!UI) continue; bool IsStart; if (!readMarker(UI, &IsStart)) continue; if (IsStart) InterestingAllocas.set(AllocaNo); BBMarkerSet[UI->getParent()][UI] = {AllocaNo, IsStart}; } } } // Compute instruction numbering. Only the following instructions are // considered: // * Basic block entries // * Lifetime markers // For each basic block, compute // * the list of markers in the instruction order // * the sets of allocas whose lifetime starts or ends in this BB LLVM_DEBUG(dbgs() << "Instructions:\n"); for (const BasicBlock *BB : depth_first(&F)) { LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": BB " << BB->getName() << "\n"); auto BBStart = Instructions.size(); Instructions.push_back(nullptr); BlockLifetimeInfo &BlockInfo = BlockLiveness.try_emplace(BB, NumAllocas).first->getSecond(); auto &BlockMarkerSet = BBMarkerSet[BB]; if (BlockMarkerSet.empty()) { BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size()); continue; } auto ProcessMarker = [&](const IntrinsicInst *I, const Marker &M) { LLVM_DEBUG(dbgs() << " " << Instructions.size() << ": " << (M.IsStart ? "start " : "end ") << M.AllocaNo << ", " << *I << "\n"); BBMarkers[BB].push_back({Instructions.size(), M}); Instructions.push_back(I); if (M.IsStart) { BlockInfo.End.reset(M.AllocaNo); BlockInfo.Begin.set(M.AllocaNo); } else { BlockInfo.Begin.reset(M.AllocaNo); BlockInfo.End.set(M.AllocaNo); } }; if (BlockMarkerSet.size() == 1) { ProcessMarker(BlockMarkerSet.begin()->getFirst(), BlockMarkerSet.begin()->getSecond()); } else { // Scan the BB to determine the marker order. for (const Instruction &I : *BB) { const IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I); if (!II) continue; auto It = BlockMarkerSet.find(II); if (It == BlockMarkerSet.end()) continue; ProcessMarker(II, It->getSecond()); } } BlockInstRange[BB] = std::make_pair(BBStart, Instructions.size()); } } void StackLifetime::calculateLocalLiveness() { bool Changed = true; while (Changed) { Changed = false; for (const BasicBlock *BB : depth_first(&F)) { BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond(); // Compute LiveIn by unioning together the LiveOut sets of all preds. BitVector LocalLiveIn; for (auto *PredBB : predecessors(BB)) { LivenessMap::const_iterator I = BlockLiveness.find(PredBB); // If a predecessor is unreachable, ignore it. if (I == BlockLiveness.end()) continue; switch (Type) { case LivenessType::May: LocalLiveIn |= I->second.LiveOut; break; case LivenessType::Must: if (LocalLiveIn.empty()) LocalLiveIn = I->second.LiveOut; else LocalLiveIn &= I->second.LiveOut; break; } } // Compute LiveOut by subtracting out lifetimes that end in this // block, then adding in lifetimes that begin in this block. If // we have both BEGIN and END markers in the same basic block // then we know that the BEGIN marker comes after the END, // because we already handle the case where the BEGIN comes // before the END when collecting the markers (and building the // BEGIN/END vectors). BitVector LocalLiveOut = LocalLiveIn; LocalLiveOut.reset(BlockInfo.End); LocalLiveOut |= BlockInfo.Begin; // Update block LiveIn set, noting whether it has changed. if (LocalLiveIn.test(BlockInfo.LiveIn)) { BlockInfo.LiveIn |= LocalLiveIn; } // Update block LiveOut set, noting whether it has changed. if (LocalLiveOut.test(BlockInfo.LiveOut)) { Changed = true; BlockInfo.LiveOut |= LocalLiveOut; } } } // while changed. } void StackLifetime::calculateLiveIntervals() { for (auto IT : BlockLiveness) { const BasicBlock *BB = IT.getFirst(); BlockLifetimeInfo &BlockInfo = IT.getSecond(); unsigned BBStart, BBEnd; std::tie(BBStart, BBEnd) = BlockInstRange[BB]; BitVector Started, Ended; Started.resize(NumAllocas); Ended.resize(NumAllocas); SmallVector<unsigned, 8> Start; Start.resize(NumAllocas); // LiveIn ranges start at the first instruction. for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) { if (BlockInfo.LiveIn.test(AllocaNo)) { Started.set(AllocaNo); Start[AllocaNo] = BBStart; } } for (auto &It : BBMarkers[BB]) { unsigned InstNo = It.first; bool IsStart = It.second.IsStart; unsigned AllocaNo = It.second.AllocaNo; if (IsStart) { assert(!Started.test(AllocaNo) || Start[AllocaNo] == BBStart); if (!Started.test(AllocaNo)) { Started.set(AllocaNo); Ended.reset(AllocaNo); Start[AllocaNo] = InstNo; } } else { assert(!Ended.test(AllocaNo)); if (Started.test(AllocaNo)) { LiveRanges[AllocaNo].addRange(Start[AllocaNo], InstNo); Started.reset(AllocaNo); } Ended.set(AllocaNo); } } for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) if (Started.test(AllocaNo)) LiveRanges[AllocaNo].addRange(Start[AllocaNo], BBEnd); } } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void StackLifetime::dumpAllocas() const { dbgs() << "Allocas:\n"; for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) dbgs() << " " << AllocaNo << ": " << *Allocas[AllocaNo] << "\n"; } LLVM_DUMP_METHOD void StackLifetime::dumpBlockLiveness() const { dbgs() << "Block liveness:\n"; for (auto IT : BlockLiveness) { const BasicBlock *BB = IT.getFirst(); const BlockLifetimeInfo &BlockInfo = BlockLiveness.find(BB)->getSecond(); auto BlockRange = BlockInstRange.find(BB)->getSecond(); dbgs() << " BB [" << BlockRange.first << ", " << BlockRange.second << "): begin " << BlockInfo.Begin << ", end " << BlockInfo.End << ", livein " << BlockInfo.LiveIn << ", liveout " << BlockInfo.LiveOut << "\n"; } } LLVM_DUMP_METHOD void StackLifetime::dumpLiveRanges() const { dbgs() << "Alloca liveness:\n"; for (unsigned AllocaNo = 0; AllocaNo < NumAllocas; ++AllocaNo) dbgs() << " " << AllocaNo << ": " << LiveRanges[AllocaNo] << "\n"; } #endif StackLifetime::StackLifetime(const Function &F, ArrayRef<const AllocaInst *> Allocas, LivenessType Type) : F(F), Type(Type), Allocas(Allocas), NumAllocas(Allocas.size()) { LLVM_DEBUG(dumpAllocas()); for (unsigned I = 0; I < NumAllocas; ++I) AllocaNumbering[Allocas[I]] = I; collectMarkers(); } void StackLifetime::run() { LiveRanges.resize(NumAllocas, LiveRange(Instructions.size())); for (unsigned I = 0; I < NumAllocas; ++I) if (!InterestingAllocas.test(I)) LiveRanges[I] = getFullLiveRange(); calculateLocalLiveness(); LLVM_DEBUG(dumpBlockLiveness()); calculateLiveIntervals(); LLVM_DEBUG(dumpLiveRanges()); } class StackLifetime::LifetimeAnnotationWriter : public AssemblyAnnotationWriter { const StackLifetime &SL; void printInstrAlive(unsigned InstrNo, formatted_raw_ostream &OS) { SmallVector<StringRef, 16> Names; for (const auto &KV : SL.AllocaNumbering) { if (SL.LiveRanges[KV.getSecond()].test(InstrNo)) Names.push_back(KV.getFirst()->getName()); } llvm::sort(Names); OS << " ; Alive: <" << llvm::join(Names, " ") << ">\n"; } void emitBasicBlockStartAnnot(const BasicBlock *BB, formatted_raw_ostream &OS) override { auto ItBB = SL.BlockInstRange.find(BB); if (ItBB == SL.BlockInstRange.end()) return; // Unreachable. printInstrAlive(ItBB->getSecond().first, OS); } void printInfoComment(const Value &V, formatted_raw_ostream &OS) override { const Instruction *Instr = dyn_cast<Instruction>(&V); if (!Instr || !SL.isReachable(Instr)) return; SmallVector<StringRef, 16> Names; for (const auto &KV : SL.AllocaNumbering) { if (SL.isAliveAfter(KV.getFirst(), Instr)) Names.push_back(KV.getFirst()->getName()); } llvm::sort(Names); OS << "\n ; Alive: <" << llvm::join(Names, " ") << ">\n"; } public: LifetimeAnnotationWriter(const StackLifetime &SL) : SL(SL) {} }; void StackLifetime::print(raw_ostream &OS) { LifetimeAnnotationWriter AAW(*this); F.print(OS, &AAW); } PreservedAnalyses StackLifetimePrinterPass::run(Function &F, FunctionAnalysisManager &AM) { SmallVector<const AllocaInst *, 8> Allocas; for (auto &I : instructions(F)) if (const AllocaInst *AI = dyn_cast<AllocaInst>(&I)) Allocas.push_back(AI); StackLifetime SL(F, Allocas, Type); SL.run(); SL.print(OS); return PreservedAnalyses::all(); }
Upload File
Create Folder