Skip to content

Commit 0d4d579

Browse files
cor3ntinahatanaka
authored andcommitted
[Clang] Improve compile times when forming a DeclRef outside of a capturing scope.
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. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D150038 (cherry picked from commit a7579b2)
1 parent 965cc90 commit 0d4d579

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,9 @@ class Sema final {
805805
/// context.
806806
unsigned FunctionScopesStart = 0;
807807

808+
/// Track the number of currently active capturing scopes.
809+
unsigned CapturingFunctionScopes = 0;
810+
808811
ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const {
809812
return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart,
810813
FunctionScopes.end());

clang/lib/Sema/Sema.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,11 +2112,13 @@ void Sema::PushFunctionScope() {
21122112
void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
21132113
FunctionScopes.push_back(new BlockScopeInfo(getDiagnostics(),
21142114
BlockScope, Block));
2115+
CapturingFunctionScopes++;
21152116
}
21162117

21172118
LambdaScopeInfo *Sema::PushLambdaScope() {
21182119
LambdaScopeInfo *const LSI = new LambdaScopeInfo(getDiagnostics());
21192120
FunctionScopes.push_back(LSI);
2121+
CapturingFunctionScopes++;
21202122
return LSI;
21212123
}
21222124

@@ -2238,6 +2240,8 @@ Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
22382240

22392241
void Sema::PoppedFunctionScopeDeleter::
22402242
operator()(sema::FunctionScopeInfo *Scope) const {
2243+
if (!Scope->isPlainFunction())
2244+
Self->CapturingFunctionScopes--;
22412245
// Stash the function scope for later reuse if it's for a normal function.
22422246
if (Scope->isPlainFunction() && !Self->CachedFunctionScope)
22432247
Self->CachedFunctionScope.reset(Scope);
@@ -2660,6 +2664,7 @@ void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD,
26602664
OpenMPCaptureLevel);
26612665
CSI->ReturnType = Context.VoidTy;
26622666
FunctionScopes.push_back(CSI);
2667+
CapturingFunctionScopes++;
26632668
}
26642669

26652670
CapturedRegionScopeInfo *Sema::getCurCapturedRegion() {

clang/lib/Sema/SemaExpr.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18835,6 +18835,15 @@ bool Sema::tryCaptureVariable(
1883518835
// An init-capture is notionally from the context surrounding its
1883618836
// declaration, but its parent DC is the lambda class.
1883718837
DeclContext *VarDC = Var->getDeclContext();
18838+
DeclContext *DC = CurContext;
18839+
18840+
// tryCaptureVariable is called every time a DeclRef is formed,
18841+
// it can therefore have non-negigible impact on performances.
18842+
// For local variables and when there is no capturing scope,
18843+
// we can bailout early.
18844+
if (CapturingFunctionScopes == 0 && (!BuildAndDiagnose || VarDC == DC))
18845+
return true;
18846+
1883818847
const auto *VD = dyn_cast<VarDecl>(Var);
1883918848
if (VD) {
1884018849
if (VD->isInitCapture())
@@ -18845,7 +18854,6 @@ bool Sema::tryCaptureVariable(
1884518854
}
1884618855
assert(VD && "Cannot capture a null variable");
1884718856

18848-
DeclContext *DC = CurContext;
1884918857
const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
1885018858
? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1;
1885118859
// We need to sync up the Declaration Context with the

0 commit comments

Comments
 (0)