Skip to content

Commit a07da67

Browse files
committed
[AliasAnalysis] Cache the results of TBAA.
Add a cache for calls to typesMayAlias. We never invalidate this cache because type aliasing relations never change. The hit rate of this cache is really high.
1 parent d99b9d1 commit a07da67

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

include/swift/SILAnalysis/AliasAnalysis.h

+13
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ class AliasAnalysis : public SILAnalysis {
5959
SILModule *Mod;
6060
SideEffectAnalysis *SEA;
6161

62+
using TBAACacheKey = std::pair<SILType, SILType>;
63+
64+
/// A cache for the computation of TBAA. True means that the types may
65+
/// alias. False means that the types must not alias.
66+
///
67+
/// We don't need to invalidate this cache because type aliasing relations
68+
/// never change.
69+
llvm::DenseMap<TBAACacheKey, bool> TypesMayAliasCache;
70+
6271
using MemoryBehavior = SILInstruction::MemoryBehavior;
6372

6473
AliasResult aliasAddressProjection(SILValue V1, SILValue V2,
@@ -68,6 +77,10 @@ class AliasAnalysis : public SILAnalysis {
6877
AliasResult aliasInner(SILValue V1, SILValue V2,
6978
SILType TBAAType1 = SILType(),
7079
SILType TBAAType2 = SILType());
80+
81+
/// Returns True if memory of type \p T1 and \p T2 may alias.
82+
bool typesMayAlias(SILType T1, SILType T2);
83+
7184
public:
7285
AliasAnalysis(SILModule *M) :
7386
SILAnalysis(AnalysisKind::Alias), Mod(M), SEA(nullptr) {}

lib/SILAnalysis/AliasAnalysis.cpp

+15-10
Original file line numberDiff line numberDiff line change
@@ -585,16 +585,21 @@ static bool typedAccessTBAAMayAlias(SILType LTy, SILType RTy, SILModule &Mod) {
585585
return true;
586586
}
587587

588-
static bool typesMayAlias(SILType T1, SILType T2, SILType TBAA1Ty,
589-
SILType TBAA2Ty, SILModule &Mod) {
590-
// Perform type access based TBAA if we have TBAA info.
591-
if (TBAA1Ty && TBAA2Ty)
592-
return typedAccessTBAAMayAlias(TBAA1Ty, TBAA2Ty, Mod);
588+
bool AliasAnalysis::typesMayAlias(SILType T1, SILType T2) {
589+
// Both types need to be valid.
590+
if (!T2 || !T1)
591+
return true;
593592

594-
// Otherwise perform class based TBAA on the passed in refs.
595-
//
596-
// FIXME: Implement class based TBAA.
597-
return true;
593+
// Check if we've already computed the TBAA relation.
594+
auto Key = std::make_pair(T1, T2);
595+
auto Res = TypesMayAliasCache.find(Key);
596+
if (Res != TypesMayAliasCache.end()) {
597+
return Res->second;
598+
}
599+
600+
bool MA = typedAccessTBAAMayAlias(T1, T2, *Mod);
601+
TypesMayAliasCache[Key] = MA;
602+
return MA;
598603
}
599604

600605
//===----------------------------------------------------------------------===//
@@ -629,7 +634,7 @@ AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2,
629634

630635
// Pass in both the TBAA types so we can perform typed access TBAA and the
631636
// actual types of V1, V2 so we can perform class based TBAA.
632-
if (!typesMayAlias(V1.getType(), V2.getType(), TBAAType1, TBAAType2, *Mod))
637+
if (!typesMayAlias(TBAAType1, TBAAType2))
633638
return AliasResult::NoAlias;
634639

635640
#ifndef NDEBUG

0 commit comments

Comments
 (0)