Skip to content

Commit 667242a

Browse files
committed
try_emplace
1 parent 11055e3 commit 667242a

File tree

7 files changed

+43
-24
lines changed

7 files changed

+43
-24
lines changed

clang/include/clang/Analysis/Analyses/LifetimeSafety/Facts.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,19 +144,18 @@ class ReturnOfOriginFact : public Fact {
144144

145145
class UseFact : public Fact {
146146
const Expr *UseExpr;
147+
OriginID OID;
147148
// True if this use is a write operation (e.g., left-hand side of assignment).
148149
// Write operations are exempted from use-after-free checks.
149150
bool IsWritten = false;
150151

151152
public:
152153
static bool classof(const Fact *F) { return F->getKind() == Kind::Use; }
153154

154-
UseFact(const Expr *UseExpr) : Fact(Kind::Use), UseExpr(UseExpr) {}
155+
UseFact(const Expr *UseExpr, OriginManager &OM)
156+
: Fact(Kind::Use), UseExpr(UseExpr), OID(OM.get(*UseExpr)) {}
155157

156-
OriginID getUsedOrigin(const OriginManager &OM) const {
157-
// TODO: Remove const cast and make OriginManager::get as const.
158-
return const_cast<OriginManager &>(OM).get(*UseExpr);
159-
}
158+
OriginID getUsedOrigin() const { return OID; }
160159
const Expr *getUseExpr() const { return UseExpr; }
161160
void markAsWritten() { IsWritten = true; }
162161
bool isWritten() const { return IsWritten; }

clang/include/clang/Analysis/Analyses/LifetimeSafety/Origins.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class OriginManager {
7474

7575
OriginID getOrCreate(const ValueDecl &D);
7676

77+
unsigned getNumOrigins() const { return NextOriginID.Value; }
78+
7779
void dump(OriginID OID, llvm::raw_ostream &OS) const;
7880

7981
private:

clang/lib/Analysis/LifetimeSafety/Facts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void ReturnOfOriginFact::dump(llvm::raw_ostream &OS, const LoanManager &,
5353
void UseFact::dump(llvm::raw_ostream &OS, const LoanManager &,
5454
const OriginManager &OM) const {
5555
OS << "Use (";
56-
OM.dump(getUsedOrigin(OM), OS);
56+
OM.dump(getUsedOrigin(), OS);
5757
OS << ", " << (isWritten() ? "Write" : "Read") << ")\n";
5858
}
5959

clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ void FactsGenerator::handleAssignment(const Expr *LHSExpr,
333333
// (e.g. on the left-hand side of an assignment).
334334
void FactsGenerator::handleUse(const DeclRefExpr *DRE) {
335335
if (isPointerType(DRE->getType())) {
336-
UseFact *UF = FactMgr.createFact<UseFact>(DRE);
336+
UseFact *UF = FactMgr.createFact<UseFact>(DRE, FactMgr.getOriginMgr());
337337
CurrentBlockFacts.push_back(UF);
338338
assert(!UseFacts.contains(DRE));
339339
UseFacts[DRE] = UF;

clang/lib/Analysis/LifetimeSafety/LiveOrigins.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class AnalysisImpl
111111
/// dominates this program point. A write operation kills the liveness of
112112
/// the origin since it overwrites the value.
113113
Lattice transfer(Lattice In, const UseFact &UF) {
114-
OriginID OID = UF.getUsedOrigin(FactMgr.getOriginMgr());
114+
OriginID OID = UF.getUsedOrigin();
115115
// Write kills liveness.
116116
if (UF.isWritten())
117117
return Lattice(Factory.remove(In.LiveOrigins, OID));

clang/lib/Analysis/LifetimeSafety/LoanPropagation.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,44 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h"
8+
#include <cassert>
9+
#include <memory>
10+
911
#include "Dataflow.h"
12+
#include "clang/Analysis/Analyses/LifetimeSafety/Facts.h"
13+
#include "clang/Analysis/Analyses/LifetimeSafety/LoanPropagation.h"
14+
#include "clang/Analysis/Analyses/LifetimeSafety/Loans.h"
15+
#include "clang/Analysis/Analyses/LifetimeSafety/Origins.h"
16+
#include "clang/Analysis/Analyses/LifetimeSafety/Utils.h"
17+
#include "clang/Analysis/AnalysisDeclContext.h"
18+
#include "clang/Analysis/CFG.h"
19+
#include "clang/Basic/LLVM.h"
1020
#include "llvm/ADT/BitVector.h"
21+
#include "llvm/ADT/SmallVector.h"
1122
#include "llvm/Support/TimeProfiler.h"
12-
#include <memory>
23+
#include "llvm/Support/raw_ostream.h"
1324

1425
namespace clang::lifetimes::internal {
1526

16-
// Pre-pass to find persistent origins. An origin is persistent if it is
27+
// Prepass to find persistent origins. An origin is persistent if it is
1728
// referenced in more than one basic block.
18-
static llvm::BitVector computePersistentOrigins(FactManager &FactMgr,
29+
static llvm::BitVector computePersistentOrigins(const FactManager &FactMgr,
1930
const CFG &C) {
2031
llvm::TimeTraceScope("ComputePersistentOrigins");
21-
llvm::BitVector PersistentOrigins(FactMgr.getOriginMgr().getOrigins().size() +
22-
1);
32+
unsigned NumOrigins = FactMgr.getOriginMgr().getNumOrigins();
33+
llvm::BitVector PersistentOrigins(NumOrigins);
2334

24-
llvm::DenseMap<OriginID, const CFGBlock *> OriginToBlock;
35+
llvm::SmallVector<const CFGBlock *> OriginToFirstSeenBlock(NumOrigins,
36+
nullptr);
2537
for (const CFGBlock *B : C) {
2638
for (const Fact *F : FactMgr.getFacts(B)) {
2739
auto CheckOrigin = [&](OriginID OID) {
2840
if (PersistentOrigins.test(OID.Value))
2941
return;
30-
auto It = OriginToBlock.find(OID);
31-
if (It == OriginToBlock.end())
32-
OriginToBlock[OID] = B;
33-
else if (It->second != B) {
42+
auto &FirstSeenBlock = OriginToFirstSeenBlock[OID.Value];
43+
if (FirstSeenBlock == nullptr)
44+
FirstSeenBlock = B;
45+
if (FirstSeenBlock != B) {
3446
// We saw this origin in more than one block.
3547
PersistentOrigins.set(OID.Value);
3648
}
@@ -50,7 +62,7 @@ static llvm::BitVector computePersistentOrigins(FactManager &FactMgr,
5062
CheckOrigin(F->getAs<ReturnOfOriginFact>()->getReturnedOriginID());
5163
break;
5264
case Fact::Kind::Use:
53-
CheckOrigin(F->getAs<UseFact>()->getUsedOrigin(FactMgr.getOriginMgr()));
65+
CheckOrigin(F->getAs<UseFact>()->getUsedOrigin());
5466
break;
5567
case Fact::Kind::Expire:
5668
case Fact::Kind::TestPoint:
@@ -195,9 +207,9 @@ class AnalysisImpl
195207

196208
OriginLoanMap::Factory &OriginLoanMapFactory;
197209
LoanSet::Factory &LoanSetFactory;
198-
/// Origins that appear in multiple basic blocks and must participate in join
199-
/// operations. Origins not in this set are block-local and can be discarded
200-
/// at block boundaries.
210+
/// Boolean vector indexed by origin ID. If true, the origin appears in
211+
/// multiple basic blocks and must participate in join operations. If false,
212+
/// the origin is block-local and can be discarded at block boundaries.
201213
llvm::BitVector PersistentOrigins;
202214
};
203215
} // namespace

clang/unittests/Analysis/LifetimeSafetyTest.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,8 @@ TEST_F(LifetimeAnalysisTest, PointersInACycle) {
529529
MyObj* temp = p1;
530530
p1 = p2;
531531
p2 = p3;
532-
p3 = temp;
532+
p3 = temp;B
533+
POINT(in_loop);
533534
}
534535
POINT(after_loop);
535536
}
@@ -543,6 +544,11 @@ TEST_F(LifetimeAnalysisTest, PointersInACycle) {
543544
EXPECT_THAT(Origin("p1"), HasLoansTo({"v1", "v2", "v3"}, "after_loop"));
544545
EXPECT_THAT(Origin("p2"), HasLoansTo({"v1", "v2", "v3"}, "after_loop"));
545546
EXPECT_THAT(Origin("p3"), HasLoansTo({"v1", "v2", "v3"}, "after_loop"));
547+
548+
EXPECT_THAT(Origin("temp"), HasLoansTo({"v1", "v2", "v3"}, "in_loop"));
549+
// 'temp' is a block-local origin and it's loans are not tracked outside the
550+
// block.
551+
EXPECT_THAT(Origin("temp"), HasLoansTo({}, "after_loop"));
546552
}
547553

548554
TEST_F(LifetimeAnalysisTest, PointersAndExpirationInACycle) {

0 commit comments

Comments
 (0)