Skip to content

Commit 86a5542

Browse files
committed
Fix cache.
1 parent 312fe80 commit 86a5542

File tree

2 files changed

+61
-24
lines changed

2 files changed

+61
-24
lines changed

source/slang/slang-check-impl.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,28 @@ struct OverloadCandidate
301301
SubstitutionSet subst;
302302
};
303303

304+
struct ResolvedOperatorOverload
305+
{
306+
// The resolved decl.
307+
Decl* decl;
308+
309+
// The cached overload candidate in the current TypeCheckingCache.
310+
// Note that a `OverloadCandidate` object is not migratable over different
311+
// Linkages (compile sessions), so we will need to use `cacheVersion` to track
312+
// if this `candidate` is valid for the current session. If not, we will
313+
// recreate it from `decl`.
314+
OverloadCandidate candidate;
315+
// The version of the TypeCheckingCache for which the cached candidate is valid.
316+
int cacheVersion;
317+
};
318+
304319
struct TypeCheckingCache : public RefObject
305320
{
306-
Dictionary<OperatorOverloadCacheKey, OverloadCandidate> resolvedOperatorOverloadCache;
321+
Dictionary<OperatorOverloadCacheKey, ResolvedOperatorOverload> resolvedOperatorOverloadCache;
307322
Dictionary<BasicTypeKeyPair, ConversionCost> conversionCostCache;
323+
324+
// The version used to invalidate the cached declRefs in ResolvedOperatorOverload entries.
325+
int version = 0;
308326
};
309327

310328
enum class CoercionSite

source/slang/slang-check-overload.cpp

+42-23
Original file line numberDiff line numberDiff line change
@@ -2509,28 +2509,6 @@ String SemanticsVisitor::getCallSignatureString(OverloadResolveContext& context)
25092509
Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
25102510
{
25112511
OverloadResolveContext context;
2512-
// check if this is a core module operator call, if so we want to use cached results
2513-
// to speed up compilation
2514-
bool shouldAddToCache = false;
2515-
OperatorOverloadCacheKey key;
2516-
TypeCheckingCache* typeCheckingCache = getLinkage()->getTypeCheckingCache();
2517-
if (auto opExpr = as<OperatorExpr>(expr))
2518-
{
2519-
if (key.fromOperatorExpr(opExpr))
2520-
{
2521-
key.isGLSLMode = getShared()->glslModuleDecl != nullptr;
2522-
OverloadCandidate candidate;
2523-
if (typeCheckingCache->resolvedOperatorOverloadCache.tryGetValue(key, candidate))
2524-
{
2525-
context.bestCandidateStorage = candidate;
2526-
context.bestCandidate = &context.bestCandidateStorage;
2527-
}
2528-
else
2529-
{
2530-
shouldAddToCache = true;
2531-
}
2532-
}
2533-
}
25342512

25352513
// Look at the base expression for the call, and figure out how to invoke it.
25362514
auto funcExpr = expr->functionExpr;
@@ -2570,6 +2548,43 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
25702548
context.loc = expr->loc;
25712549
context.sourceScope = m_outerScope;
25722550
context.baseExpr = GetBaseExpr(funcExpr);
2551+
2552+
// check if this is a core module operator call, if so we want to use cached results
2553+
// to speed up compilation
2554+
bool shouldAddToCache = false;
2555+
OperatorOverloadCacheKey key;
2556+
TypeCheckingCache* typeCheckingCache = getLinkage()->getTypeCheckingCache();
2557+
if (auto opExpr = as<OperatorExpr>(expr))
2558+
{
2559+
if (key.fromOperatorExpr(opExpr))
2560+
{
2561+
key.isGLSLMode = getShared()->glslModuleDecl != nullptr;
2562+
ResolvedOperatorOverload candidate;
2563+
if (typeCheckingCache->resolvedOperatorOverloadCache.tryGetValue(key, candidate))
2564+
{
2565+
// We should only use the cached candidate if it is persistent direct declref created
2566+
// from GlobalSession's ASTBuilder, or it is created in the current Linkage.
2567+
if (candidate.cacheVersion == typeCheckingCache->version ||
2568+
as<DirectDeclRef>(candidate.candidate.item.declRef.declRefBase))
2569+
{
2570+
context.bestCandidateStorage = candidate.candidate;
2571+
context.bestCandidate = &context.bestCandidateStorage;
2572+
}
2573+
else
2574+
{
2575+
LookupResultItem overloadCandidate = {};
2576+
overloadCandidate.declRef = getOuterGenericOrSelf(candidate.decl);
2577+
AddDeclRefOverloadCandidates(overloadCandidate, context, 0);
2578+
shouldAddToCache = true;
2579+
}
2580+
}
2581+
else
2582+
{
2583+
shouldAddToCache = true;
2584+
}
2585+
}
2586+
}
2587+
25732588
// We run a special case here where an `InvokeExpr`
25742589
// with a single argument where the base/func expression names
25752590
// a type should always be treated as an explicit type coercion
@@ -2737,7 +2752,11 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr)
27372752
getShared()->glslModuleDecl ==
27382753
getModuleDecl(context.bestCandidate->item.declRef.getDecl()))
27392754
{
2740-
typeCheckingCache->resolvedOperatorOverloadCache[key] = *context.bestCandidate;
2755+
ResolvedOperatorOverload overloadResult;
2756+
overloadResult.candidate = *context.bestCandidate;
2757+
overloadResult.decl = context.bestCandidate->item.declRef.getDecl();
2758+
overloadResult.cacheVersion = typeCheckingCache->version;
2759+
typeCheckingCache->resolvedOperatorOverloadCache[key] = overloadResult;
27412760
}
27422761
}
27432762

0 commit comments

Comments
 (0)