Skip to content
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

Extract Lets from LetRec #30974

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

frankmcsherry
Copy link
Contributor

Our let normalization consolidates let and letrec stages, partly on account of tracking the same thing two different ways is annoying and makes the code complicated. At the same time, other parts of the code prefer to have as much extracted from letrec stages as possible, both because transforms can be less effective with letrec stages, and because once we have ArrangeBy stages they should be hoisted as high out of letrec stages as is possible, to maximize their availability.

Both of these feel like glitches that we should solve closer to the problems (e.g. improving the transforms to achieve parity, and hoisting arrangements in lowering to renderable plans). This PR is first to see what the plan changes are and whether we like them, and if we are lucky to address some complaints we have around arrangements not being found come render time.

cc: @ggevay

Motivation

Tips for reviewer

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered. (trigger-ci for additional test/nightly runs)
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • If this PR includes major user-facing behavior changes, I have pinged the relevant PM to schedule a changelog post.

@frankmcsherry frankmcsherry requested a review from a team as a code owner January 8, 2025 18:46
Comment on lines -157 to 163
Join on=(#2 = (#0 % 2)) type=differential // { arity: 3 }
implementation
%1:l0[#0]UK » %0:t2[(#0 % 2)]K
ArrangeBy keys=[[(#0 % 2)]] // { arity: 2 }
ReadStorage materialize.public.t2 // { arity: 2 }
ArrangeBy keys=[[#0]] // { arity: 1 }
With Mutually Recursive
cte l1 =
Distinct project=[#0..=#2] // { arity: 3 }
Union // { arity: 3 }
Get l1 // { arity: 3 }
Project (#0, #0, #0) // { arity: 3 }
Get l0 // { arity: 1 }
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Who knows, but potentially redundant join elimination not operating in LetRec blocks?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds plausible.

@frankmcsherry frankmcsherry force-pushed the extract_lets_from_letrec branch from 5304bc2 to b77fddc Compare January 8, 2025 20:15
@ggevay ggevay self-requested a review January 9, 2025 09:06
// This is unsafe when applied to expressions which contain `ArrangeBy`,
// as if the extracted suffixes reference arrangements they will not be
// able to access those arrangements from outside the `LetRec` scope.
// It happens to work at the moment, so we don't touch it but should fix.
let bindings = let_motion::harvest_nonrec_suffix(relation)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

When the new code above wraps a LetRec into a Let, this can make the harvest_nonrec_suffix call ineffective, because relation is no longer a LetRec, but harvest_nonrec_suffix just wants to match LetRec at the root. This seems to be happening in the output change in normalize_lets.spec below, where l2 used to come out of the WMR, but now it remains in there (and similarly in aoc_1204.slt with l7, and in aoc_1203.slt with all of l10 .. l19 of the old version). Would it be possible to tweak the code to be able to still do harvest_nonrec_suffix in this case? It might be as simple as doing the harvest_nonrec_suffix call and the below code block not on relation, but on the innermost relation of the Let stack that is being assembled above?

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