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());
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());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits