Skip to content

Improve indentation in type checker debugging output #62053

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

abdulowork
Copy link
Contributor

I was looking at the reason behind the performance bug in #58955 and found that the compiler was spending most of the time in the type checker. While investing, I found the DebugConstraints flag very useful; however, the output of this flag was not always indented, which made the debugging log hard to fold and read.

This PR improves indentation in some of the debugging output.

I noticed the debugging output is mostly untested. Should I try to add tests for the indentation?

@@ -375,8 +377,10 @@ bool ConstraintSystem::simplify() {
retireFailedConstraint(constraint);
if (isDebugMode()) {
auto &log = llvm::errs();
log.indent(solverState->getCurrentIndent() + 2) << ")\n";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would print an unbalanced brace if constrain was ConstraintKind::Disjunction || ConstraintKind::Conjunction

Screenshot 2022-11-11 at 17 43 54

choice.print(log, &ctx.SourceMgr);
log << '\n';
choice.print(log, &ctx.SourceMgr, 0, CS.getCurrentIndent());
log << ")\n";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This brace was unbalanced

// Print all type variables as $T0 instead of _ here.
PrintOptions PO;
PO.PrintTypesForDebugging = true;

Out.indent(firstLineIndent);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constraints where previously printed unindented, which interfered with folding

Screenshot 2022-11-11 at 17 43 32

if (result.getKind() == SolutionResult::Success) {
llvm::errs() << "\n---Solution---\n";
result.getSolution().dump(llvm::errs());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solutions where printed unindented:

Screenshot 2022-11-11 at 17 02 34

@abdulowork
Copy link
Contributor Author

The log is now easier to traverse with set foldmethod=indent in vim

Screenshot 2022-11-12 at 12 54 45

@xedin
Copy link
Contributor

xedin commented Nov 12, 2022

Thank you! I will take a look on monday!

@xedin xedin self-requested a review November 12, 2022 04:57
@abdulowork abdulowork marked this pull request as ready for review November 14, 2022 07:54
@@ -3438,6 +3438,10 @@ class ConstraintSystem {
return findSelectedOverloadFor(calleeLoc);
}

unsigned int getCurrentIndent() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't do this before because indent is not really a property of the constraint system. If you want to refactor this, I think it would be reasonable to do what CSStep currently does, where it would return a properly indented getDebugLogger(). Also please separate refactoring changes like this into a commit to make it easier to review functional changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I decided to move this logic to the ConstraintSystem was that I noticed a couple of places like this one and this one with similar code that was checking for solverState existence. Since I needed to fetch indentation in numerous other places, it felt like moving this logic to ConstraintSystem would reduce duplication.

I am not sure how to employ getDebugLogger() approach here. There is still a need to get the indentation to pass it on to print constraints.

I can leave the getCurrentIndent() refactoring out of the scope of this pull request and revert to checking for solverState externally where appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please separate refactoring changes

I split this PR into three commits. If it is too large, I can break it down into several PRs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using llvm::errs() directly and setting .indent(solverState ? ...) everywhere we could just ask a constraint system for debug logger which would set appropriate indent internally. It's always possible to change indent when necessary.

I am not sure how to employ getDebugLogger() approach here. There is still a need to get the indentation to pass it on to print constraints.

This would effectively stay the same where getCurrentIndent is kept on the SolverState.

I can leave the getCurrentIndent() refactoring out of the scope of this pull request and revert to checking for solverState externally where appropriate.

I think that would be appropriate, it's effectively NFC refactoring and could be done separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's effectively NFC refactoring and could be done separately

I reverted the getCurrentIndent() refactoring

@@ -891,7 +891,8 @@ class Constraint final : public llvm::ilist_node<Constraint>,
/// Print constraint placed on type and constraint properties.
///
/// \c skipLocator skips printing of locators.
void print(llvm::raw_ostream &Out, SourceManager *sm, unsigned indent = 0,
void print(llvm::raw_ostream &Out, SourceManager *sm,
unsigned firstLineIndent = 0, unsigned indent = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I remember correctly the idea here is that the Out is indented when it's passed in that's why indent is used only if the constraint spans multiple lines to be able to indent everything after \n so we need to make sure that this happens correctly instead of adding firstLineIndent here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. I removed firstLineIndent and indented Out where it was appropriate.

@abdulowork abdulowork force-pushed the improve-type-checker-debugging-indentation branch 3 times, most recently from c9310be to ff706c6 Compare November 15, 2022 17:32
@@ -353,6 +353,10 @@ bool ConstraintSystem::simplify() {
auto *constraint = &ActiveConstraints.front();
deactivateConstraint(constraint);

auto hasSimplificationResult =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think isSimplifiable might be a better name here.

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes besides ConstraintSystem::getCurrentIdent look good to me, thank you!

@abdulowork abdulowork force-pushed the improve-type-checker-debugging-indentation branch from ff706c6 to d738958 Compare November 17, 2022 15:25
@abdulowork abdulowork force-pushed the improve-type-checker-debugging-indentation branch from d738958 to 3f36694 Compare November 17, 2022 15:25
Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@xedin
Copy link
Contributor

xedin commented Nov 17, 2022

@swift-ci please smoke test

@xedin
Copy link
Contributor

xedin commented Nov 29, 2022

@swift-ci please smoke test macOS platform

@xedin xedin merged commit 6b37764 into swiftlang:main Nov 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants