Skip to content

Commit 1636ee8

Browse files
committed
[CSStep] Conjunction: Give each conjunction step a fresh timer
Original timer cannot be used each expression in the multi-statement closure is type-checked independently.
1 parent d003140 commit 1636ee8

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,10 @@ struct RestrictionOrFix {
167167

168168

169169
class ExpressionTimer {
170+
public:
170171
using AnchorType = llvm::PointerUnion<Expr *, ConstraintLocator *>;
171172

173+
private:
172174
AnchorType Anchor;
173175
ASTContext &Context;
174176
llvm::TimeRecord StartTime;
@@ -188,6 +190,8 @@ class ExpressionTimer {
188190

189191
~ExpressionTimer();
190192

193+
AnchorType getAnchor() const { return Anchor; }
194+
191195
unsigned getWarnLimit() const {
192196
return Context.TypeCheckerOpts.WarnLongExpressionTypeChecking;
193197
}
@@ -5681,6 +5685,8 @@ class ConjunctionElement {
56815685

56825686
bool attempt(ConstraintSystem &cs) const;
56835687

5688+
ConstraintLocator *getLocator() const { return Element->getLocator(); }
5689+
56845690
void print(llvm::raw_ostream &Out, SourceManager *SM) const {
56855691
Out << "conjunction element ";
56865692
Element->print(Out, SM);

lib/Sema/CSStep.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,14 @@ bool ConjunctionStep::attempt(const ConjunctionElement &element) {
820820
// when closure has a lot of elements in the body.
821821
CS.CountScopes = 0;
822822

823+
// If timer is enabled, let's reset it so that each element
824+
// (expression) gets a fresh time slice to get solved. This
825+
// is important for closures with large number of statements
826+
// in them.
827+
if (CS.Timer) {
828+
CS.Timer.emplace(element.getLocator(), CS);
829+
}
830+
823831
auto success = element.attempt(CS);
824832

825833
// If element attempt has failed, mark whole conjunction

lib/Sema/CSStep.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,11 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
861861
/// before accepting this conjunction.
862862
llvm::SaveAndRestore<unsigned> OuterScopeCount;
863863

864+
/// The number of milliseconds until outer constraint system
865+
/// is considered "too complex" if timer is enabled.
866+
Optional<std::pair<ExpressionTimer::AnchorType, unsigned>>
867+
OuterTimeRemaining = None;
868+
864869
/// Conjunction constraint associated with this step.
865870
Constraint *Conjunction;
866871
/// Position of the conjunction in the inactive constraints
@@ -900,6 +905,11 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
900905
// Make a snapshot of the constraint system state before conjunction.
901906
if (conjunction->isIsolated())
902907
Snapshot.emplace(cs, conjunction);
908+
909+
if (cs.Timer) {
910+
auto remainingTime = cs.Timer->getRemainingProcessTimeInMillis();
911+
OuterTimeRemaining.emplace(cs.Timer->getAnchor(), remainingTime);
912+
}
903913
}
904914

905915
~ConjunctionStep() override {
@@ -915,6 +925,12 @@ class ConjunctionStep : public BindingStep<ConjunctionElementProducer> {
915925
// successful outcome should keep a score set by `restoreOuterState`.
916926
if (HadFailure)
917927
restoreOriginalScores();
928+
929+
if (OuterTimeRemaining) {
930+
auto anchor = OuterTimeRemaining->first;
931+
auto remainingTime = OuterTimeRemaining->second;
932+
CS.Timer.emplace(anchor, CS, remainingTime);
933+
}
918934
}
919935

920936
StepResult resume(bool prevFailed) override;

0 commit comments

Comments
 (0)