diff options
| author | Yong He <yonghe@outlook.com> | 2025-02-23 10:31:05 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-23 10:31:05 -0800 |
| commit | 51ad07d1fbffd41c758eba172aa77ebba3204924 (patch) | |
| tree | fadd788714c4ad37830846b0274d56b5ae1eff56 /source/slang/slang-check-overload.cpp | |
| parent | 0101e5ab59a1678ed7212913c3880edfaf039537 (diff) | |
Improve performance when compiling small shaders. (#6396)
Improve performance when compiling small shaders.
Avoid copying witness table entries that are not getting used during linking.
Avoid copying auto-diff related decorations and derivative functions during linking, if the user modules doesn't use autodiff.
Cache operator overload resolution results on global session, so each new Session doesn't need to repetitively run through overload resolution from scratch.
Diffstat (limited to 'source/slang/slang-check-overload.cpp')
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index b75f95f9a..f548fb819 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -2509,27 +2509,6 @@ String SemanticsVisitor::getCallSignatureString(OverloadResolveContext& context) Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) { OverloadResolveContext context; - // check if this is a core module operator call, if so we want to use cached results - // to speed up compilation - bool shouldAddToCache = false; - OperatorOverloadCacheKey key; - TypeCheckingCache* typeCheckingCache = getLinkage()->getTypeCheckingCache(); - if (auto opExpr = as<OperatorExpr>(expr)) - { - if (key.fromOperatorExpr(opExpr)) - { - OverloadCandidate candidate; - if (typeCheckingCache->resolvedOperatorOverloadCache.tryGetValue(key, candidate)) - { - context.bestCandidateStorage = candidate; - context.bestCandidate = &context.bestCandidateStorage; - } - else - { - shouldAddToCache = true; - } - } - } // Look at the base expression for the call, and figure out how to invoke it. auto funcExpr = expr->functionExpr; @@ -2569,6 +2548,43 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) context.loc = expr->loc; context.sourceScope = m_outerScope; context.baseExpr = GetBaseExpr(funcExpr); + + // check if this is a core module operator call, if so we want to use cached results + // to speed up compilation + bool shouldAddToCache = false; + OperatorOverloadCacheKey key; + TypeCheckingCache* typeCheckingCache = getLinkage()->getTypeCheckingCache(); + if (auto opExpr = as<OperatorExpr>(expr)) + { + if (key.fromOperatorExpr(opExpr)) + { + key.isGLSLMode = getShared()->glslModuleDecl != nullptr; + ResolvedOperatorOverload candidate; + if (typeCheckingCache->resolvedOperatorOverloadCache.tryGetValue(key, candidate)) + { + // We should only use the cached candidate if it is persistent direct declref + // created from GlobalSession's ASTBuilder, or it is created in the current Linkage. + if (candidate.cacheVersion == typeCheckingCache->version || + as<DirectDeclRef>(candidate.candidate.item.declRef.declRefBase)) + { + context.bestCandidateStorage = candidate.candidate; + context.bestCandidate = &context.bestCandidateStorage; + } + else + { + LookupResultItem overloadCandidate = {}; + overloadCandidate.declRef = getOuterGenericOrSelf(candidate.decl); + AddDeclRefOverloadCandidates(overloadCandidate, context, 0); + shouldAddToCache = true; + } + } + else + { + shouldAddToCache = true; + } + } + } + // We run a special case here where an `InvokeExpr` // with a single argument where the base/func expression names // a type should always be treated as an explicit type coercion @@ -2731,7 +2747,18 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) // We will report errors for this one candidate, then, to give // the user the most help we can. if (shouldAddToCache) - typeCheckingCache->resolvedOperatorOverloadCache[key] = *context.bestCandidate; + { + if (isFromCoreModule(context.bestCandidate->item.declRef.getDecl()) || + getShared()->glslModuleDecl == + getModuleDecl(context.bestCandidate->item.declRef.getDecl())) + { + ResolvedOperatorOverload overloadResult; + overloadResult.candidate = *context.bestCandidate; + overloadResult.decl = context.bestCandidate->item.declRef.getDecl(); + overloadResult.cacheVersion = typeCheckingCache->version; + typeCheckingCache->resolvedOperatorOverloadCache[key] = overloadResult; + } + } // Now that we have resolved the overload candidate, we need to undo an `openExistential` // operation that was applied to `out` arguments. |
