[PATCH] D150038: [Clang] Improve compile times when forming a DeclRef outside of a capturing scope.
Corentin Jabot via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat May 6 06:28:20 PDT 2023
cor3ntin created this revision.
Herald added a project: All.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
The logic of whether an entity needs to be captured has become
quite complex and the recent changes in https://reviews.llvm.org/D124351
ad a mesurable negative impact on compile times.
However, in the absence of capturing scopes (lambda, block, region)
we usually can avoid running most of that logic
(except that we do need to diagnostic when a nested function
refers to a local variable in the scope of the outer function.).
This patch track whether there is currently an active capturing
scope and exit `tryCaptureVariable` early when there isn't.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D150038
Files:
clang/include/clang/Sema/Sema.h
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaExpr.cpp
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -19190,6 +19190,15 @@
// An init-capture is notionally from the context surrounding its
// declaration, but its parent DC is the lambda class.
DeclContext *VarDC = Var->getDeclContext();
+ DeclContext *DC = CurContext;
+
+ // tryCaptureVariable is called ever ytime a DeclRef is formed,
+ // it can therefore have non-negigible impact on performances.
+ // For local variables and when there is no capturing scope,
+ // we can bailout early.
+ if(CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == DC))
+ return true;
+
const auto *VD = dyn_cast<VarDecl>(Var);
if (VD) {
if (VD->isInitCapture())
@@ -19199,7 +19208,6 @@
}
assert(VD && "Cannot capture a null variable");
- DeclContext *DC = CurContext;
const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1;
// We need to sync up the Declaration Context with the
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -2137,11 +2137,13 @@
void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(),
BlockScope, Block));
+ CapturingFunctionScopes++;
}
LambdaScopeInfo *Sema::PushLambdaScope() {
LambdaScopeInfo *const LSI = new LambdaScopeInfo(getDiagnostics());
FunctionScopes.push_back(LSI);
+ CapturingFunctionScopes++;
return LSI;
}
@@ -2263,6 +2265,8 @@
void Sema::PoppedFunctionScopeDeleter::
operator()(sema::FunctionScopeInfo *Scope) const {
+ if(!Scope->isPlainFunction())
+ Self->CapturingFunctionScopes--;
// Stash the function scope for later reuse if it's for a normal function.
if (Scope->isPlainFunction() && !Self->CachedFunctionScope)
Self->CachedFunctionScope.reset(Scope);
@@ -2693,6 +2697,7 @@
OpenMPCaptureLevel);
CSI->ReturnType = Context.VoidTy;
FunctionScopes.push_back(CSI);
+ CapturingFunctionScopes++;
}
CapturedRegionScopeInfo *Sema::getCurCapturedRegion() {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -806,6 +806,9 @@
/// context.
unsigned FunctionScopesStart = 0;
+ /// Track the number of currently active capturing scopes.
+ unsigned CapturingFunctionScopes = 0;
+
ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const {
return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart,
FunctionScopes.end());
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150038.520082.patch
Type: text/x-patch
Size: 2863 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230506/acb54d95/attachment.bin>
More information about the cfe-commits
mailing list