clang 23.0.0git
MovedLoans.cpp
Go to the documentation of this file.
1//===- MovedLoans.cpp - Moved Loans Analysis --------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the MovedLoansAnalysis, a forward dataflow analysis that
10// tracks which loans have been moved out of their original storage location
11// at each program point.
12//
13//===----------------------------------------------------------------------===//
14
16#include "Dataflow.h"
22
24namespace {
25struct Lattice {
26 MovedLoansMap MovedLoans = MovedLoansMap(nullptr);
27
28 explicit Lattice(MovedLoansMap MovedLoans) : MovedLoans(MovedLoans) {}
29
30 Lattice() = default;
31
32 bool operator==(const Lattice &Other) const {
33 return MovedLoans == Other.MovedLoans;
34 }
35 bool operator!=(const Lattice &Other) const { return !(*this == Other); }
36};
37
38class AnalysisImpl
39 : public DataflowAnalysis<AnalysisImpl, Lattice, Direction::Forward> {
40public:
41 AnalysisImpl(const CFG &C, AnalysisDeclContext &AC, FactManager &F,
42 const LoanPropagationAnalysis &LoanPropagation,
43 const LiveOriginsAnalysis &LiveOrigins,
44 const LoanManager &LoanMgr,
45 MovedLoansMap::Factory &MovedLoansMapFactory)
46 : DataflowAnalysis(C, AC, F), LoanPropagation(LoanPropagation),
47 LiveOrigins(LiveOrigins), LoanMgr(LoanMgr),
48 MovedLoansMapFactory(MovedLoansMapFactory) {}
49
50 using Base::transfer;
51
52 StringRef getAnalysisName() const { return "MovedLoans"; }
53
54 Lattice getInitialState() { return Lattice{}; }
55
56 /// Merges moved loan state from different control flow paths. When a loan
57 /// is moved on multiple paths, picks the lexically earliest move expression.
58 Lattice join(Lattice A, Lattice B) {
59 MovedLoansMap MovedLoans = utils::join(
60 A.MovedLoans, B.MovedLoans, MovedLoansMapFactory,
61 [](const Expr *const *MoveA, const Expr *const *MoveB) -> const Expr * {
62 assert(MoveA || MoveB);
63 if (!MoveA)
64 return *MoveB;
65 if (!MoveB)
66 return *MoveA;
67 return (*MoveA)->getExprLoc() < (*MoveB)->getExprLoc() ? *MoveA
68 : *MoveB;
69 },
71 return Lattice(MovedLoans);
72 }
73
74 /// Marks all live loans sharing the same access path as the moved origin as
75 /// potentially moved.
76 Lattice transfer(Lattice In, const MovedOriginFact &F) {
77 MovedLoansMap MovedLoans = In.MovedLoans;
78 OriginID MovedOrigin = F.getMovedOrigin();
79 LoanSet ImmediatelyMovedLoans = LoanPropagation.getLoans(MovedOrigin, &F);
80 auto IsInvalidated = [&](const AccessPath &Path) {
81 for (LoanID LID : ImmediatelyMovedLoans) {
82 const Loan *MovedLoan = LoanMgr.getLoan(LID);
83 auto *PL = dyn_cast<PathLoan>(MovedLoan);
84 if (!PL)
85 continue;
86 if (PL->getAccessPath() == Path)
87 return true;
88 }
89 return false;
90 };
91 for (auto [O, _] : LiveOrigins.getLiveOriginsAt(&F))
92 for (LoanID LiveLoan : LoanPropagation.getLoans(O, &F)) {
93 const Loan *LiveLoanPtr = LoanMgr.getLoan(LiveLoan);
94 auto *PL = dyn_cast<PathLoan>(LiveLoanPtr);
95 if (!PL)
96 continue;
97 if (IsInvalidated(PL->getAccessPath()))
98 MovedLoans =
99 MovedLoansMapFactory.add(MovedLoans, LiveLoan, F.getMoveExpr());
100 }
101 return Lattice(MovedLoans);
102 }
103
104 MovedLoansMap getMovedLoans(ProgramPoint P) { return getState(P).MovedLoans; }
105
106private:
107 const LoanPropagationAnalysis &LoanPropagation;
108 const LiveOriginsAnalysis &LiveOrigins;
109 const LoanManager &LoanMgr;
110 MovedLoansMap::Factory &MovedLoansMapFactory;
111};
112} // namespace
113
114class MovedLoansAnalysis::Impl final : public AnalysisImpl {
115 using AnalysisImpl::AnalysisImpl;
116};
117
119 const CFG &C, AnalysisDeclContext &AC, FactManager &F,
120 const LoanPropagationAnalysis &LoanPropagation,
121 const LiveOriginsAnalysis &LiveOrigins, const LoanManager &LoanMgr,
122 MovedLoansMap::Factory &MovedLoansMapFactory)
123 : PImpl(std::make_unique<Impl>(C, AC, F, LoanPropagation, LiveOrigins,
124 LoanMgr, MovedLoansMapFactory)) {
125 PImpl->run();
126}
127
129
131 return PImpl->getMovedLoans(P);
132}
133} // namespace clang::lifetimes::internal
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition CFG.h:1250
A generic, policy-based driver for dataflow analyses.
Definition Dataflow.h:57
Manages the creation, storage and retrieval of loans.
Definition Loans.h:147
MovedLoansAnalysis(const CFG &C, AnalysisDeclContext &AC, FactManager &F, const LoanPropagationAnalysis &LoanPropagation, const LiveOriginsAnalysis &LiveOrigins, const LoanManager &LoanMgr, MovedLoansMap::Factory &MovedLoansMapFactory)
MovedLoansMap getMovedLoans(ProgramPoint P) const
void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, Environment::ValueModel &Model)
Evaluates S and updates Env accordingly.
Definition Transfer.cpp:984
@ Asymmetric
An asymmetric join preserves keys unique to the first map as-is, while applying the JoinValues operat...
Definition Utils.h:62
static llvm::ImmutableSet< T > join(llvm::ImmutableSet< T > A, llvm::ImmutableSet< T > B, typename llvm::ImmutableSet< T >::Factory &F)
Computes the union of two ImmutableSets.
Definition Utils.h:39
const Fact * ProgramPoint
A ProgramPoint identifies a location in the CFG by pointing to a specific Fact.
Definition Facts.h:87
llvm::ImmutableSet< LoanID > LoanSet
utils::ID< struct LoanTag > LoanID
Definition Loans.h:25
utils::ID< struct OriginTag > OriginID
Definition Origins.h:27
llvm::ImmutableMap< LoanID, const Expr * > MovedLoansMap
Definition MovedLoans.h:26
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
Definition CallGraph.h:206
bool operator!=(CanQual< T > x, CanQual< U > y)
@ Other
Other implicit parameter.
Definition Decl.h:1746