Repository navigation
perf: single-pass FileProcessor (drop do-while reprint loop) - #8825
Closed
TomasVotruba wants to merge 3 commits into
Closed
TomasVotruba wants to merge 3 commits into
TomasVotruba wants to merge 3 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Replace the
do { traverse rules; post-rectors; print } while (changed)fixpoint loop inFileProcessor::processFile()with a single pass. The old loop reprinted the whole file (format-preserving print, the expensive step) once per pass until the AST stabilized. This runs the rule traversal and post-rectors once and prints at most once.Also removes the now-unused
File::changeHasChanged()and keepsFile::hasChanged()backed by the real content-change flag (set during print), not by the line-change counter - the two are different signals:rectorWithLineChanges !== []- a rule reported a change (gates diff-object creation)hasChangedflag - printed content actually differs (authoritative for caching / result)Status - DRAFT, CI will be red on purpose
This surfaces the perf idea plus its hard drawbacks. It does not pass CI as-is.
Drawbacks (known failing tests)
The loop existed to converge multi-step transformations. Single pass stops one step short in 6
tests/Issuesfixtures:Rule-chain (two rules, A output must reach B):
AlwaysTrueIfInDeadConstructor- RemoveAlwaysTrueIf empties the ctor, RemoveEmptyClassMethod should then delete it. Pre-order dispatch visits ClassMethod before the innerifis removed, so the ctor is not empty yet.DeadInstanceFlip- ExplicitNullable produces aninstanceof, RemoveDeadInstanceOf should strip it. ExplicitNullable runs last in the visitor list, so RemoveDeadInstanceOf (already run) never sees the produced node.InlineIfReplaceBlock- ReplaceBlock unwraps a bare block via an array return (spliced through$doNodes, never re-traversed that pass), so InlineIf never sees the exposed statements.IndexedStmt- synthetic engine regression: statement index shifts after a removal; inherently needs a re-pass.Post-rector convergence (legitimately multi-pass):
NamespacedUseAutoImportx2 - name import adds ause, then it is normalized on a later pass. This is import convergence in the post-rector chain, not a single rule.Why per-rule idempotency fixes do not cover these: all four rule-chain cases are cross-rule compositions. A fix inside rule A cannot make rule B fire. Folding only works when a rule chains on its own same-class output.
Proposed path to make it work - deferred last-phase rules
Give cleanup / dead-code rules (RemoveEmptyClassMethod, RemoveDeadInstanceOf, ...) a "run last" position: a dedicated final sweep over the tree after the main sweep, instead of an unbounded reprint loop. Precedent: post-rectors are already ordered and run after rules.
Perf note
Not yet benchmarked. The win is dropping repeated format-preserving prints on files that need more than one pass; single-pass files are unaffected. Needs a before/after measurement before this is more than a draft.