15#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_DATAFLOW_H
16#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_DATAFLOW_H
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/TimeProfiler.h"
56template <
typename Derived,
typename LatticeType, Direction Dir>
67 llvm::DenseMap<const CFGBlock *, Lattice> InStates;
69 llvm::DenseMap<const CFGBlock *, Lattice> OutStates;
73 llvm::DenseMap<ProgramPoint, Lattice> PerPointStates;
86 Derived &D =
static_cast<Derived &
>(*this);
87 llvm::TimeTraceScope Time(D.getAnalysisName());
94 const CFGBlock *Start = isForward() ? &Cfg.getEntry() : &Cfg.getExit();
95 InStates[Start] = D.getInitialState();
96 W.enqueueBlock(Start);
98 while (
const CFGBlock *B = W.dequeue()) {
100 Lattice StateOut = transferBlock(B, StateIn);
101 OutStates[B] = StateOut;
102 for (
const CFGBlock *AdjacentB : isForward() ? B->
succs() : B->preds()) {
105 std::optional<Lattice> OldInState =
getInState(AdjacentB);
107 !OldInState ? StateOut : D.join(*OldInState, StateOut);
110 if (!OldInState || NewInState != *OldInState) {
111 InStates[AdjacentB] = NewInState;
112 W.enqueueBlock(AdjacentB);
122 auto It = InStates.find(B);
123 if (It == InStates.end())
131 const Derived *D =
static_cast<const Derived *
>(
this);
132 llvm::dbgs() <<
"==========================================\n";
133 llvm::dbgs() << D->getAnalysisName() <<
" results:\n";
134 llvm::dbgs() <<
"==========================================\n";
135 const CFGBlock &B = isForward() ? Cfg.getExit() : Cfg.getEntry();
142 Lattice transferBlock(
const CFGBlock *
Block, Lattice State) {
144 if constexpr (isForward()) {
145 for (
const Fact *F : Facts) {
146 State = transferFact(State, F);
147 PerPointStates[F] = State;
150 for (
const Fact *F : llvm::reverse(Facts)) {
152 PerPointStates[F] = State;
153 State = transferFact(State, F);
161 Derived *D =
static_cast<Derived *
>(
this);
162 switch (F->getKind()) {
164 return D->transfer(In, *F->getAs<IssueFact>());
166 return D->transfer(In, *F->getAs<ExpireFact>());
168 return D->transfer(In, *F->getAs<OriginFlowFact>());
170 return D->transfer(In, *F->getAs<ReturnOfOriginFact>());
172 return D->transfer(In, *F->getAs<UseFact>());
174 return D->transfer(In, *F->getAs<TestPointFact>());
176 llvm_unreachable(
"Unknown fact kind");
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a single basic block in a source-level CFG.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
DataflowAnalysis(const CFG &Cfg, AnalysisDeclContext &AC, FactManager &FactMgr)
std::optional< Lattice > getInState(const CFGBlock *B) const
Lattice transfer(Lattice In, const OriginFlowFact &)
Lattice transfer(Lattice In, const TestPointFact &)
Lattice getOutState(const CFGBlock *B) const
Lattice transfer(Lattice In, const ReturnOfOriginFact &)
Lattice transfer(Lattice In, const UseFact &)
Lattice transfer(Lattice In, const IssueFact &)
Lattice transfer(Lattice In, const ExpireFact &)
DataflowAnalysis< Derived, Lattice, Dir > Base
Lattice getState(ProgramPoint P) const
llvm::ArrayRef< const Fact * > getFacts(const CFGBlock *B) const
An abstract base class for a single, atomic lifetime-relevant event.
@ TestPoint
A marker for a specific point in the code, for testing.
@ Expire
A loan expires as its underlying storage is freed (e.g., variable goes out of scope).
@ ReturnOfOrigin
An origin escapes the function by flowing into the return value.
@ Issue
A new loan is issued from a borrow expression (e.g., &x).
@ OriginFlow
An origin is propagated from a source to a destination (e.g., p = q).
@ Use
An origin is used (eg. appears as l-value expression like DeclRefExpr).
A dummy-fact used to mark a specific point in the code for testing.
const Fact * ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
A worklist implementation for backward dataflow analysis.
A worklist implementation for forward dataflow analysis.