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

Defunkify lifter and related middle-IR code #290

Merged
merged 2 commits into from
Mar 12, 2025

Conversation

LPTK
Copy link
Contributor

@LPTK LPTK commented Mar 11, 2025

There was a bunch of funky stuff happening both in the lifter and in related middle-IR code.

The only reason I made this a PR is for @CAG2Mark to have a chance to review it and learn a bit in the process.

@@ -347,12 +351,10 @@ final case class ClsLikeDefn(
parentPath: Opt[Path],
methods: Ls[FunDefn],
privateFields: Ls[TermSymbol],
publicFields: Ls[TermDefinition],
publicFields: Ls[BlockMemberSymbol],
Copy link
Contributor Author

@LPTK LPTK Mar 11, 2025

Choose a reason for hiding this comment

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

The only reason we were storing TermDefinitions here was to remember which things are supposed to be public fields. But clearly it's wrong to store elaborated terms in a middle-IR data structure. All we needed here was just the symbol.

@@ -147,14 +147,17 @@ class BlockTransformer(subst: SymbolSubst):
if (own2 is fun.owner) && (sym2 is fun.sym) && (params2 is fun.params) && (body2 is fun.body)
then fun else FunDefn(own2, sym2, params2, body2)

def applyValDefn(defn: ValDefn): ValDefn =
Copy link
Contributor Author

@LPTK LPTK Mar 11, 2025

Choose a reason for hiding this comment

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

(Only reason I extracted this is because it used to be needed in my previous refactoring; I kept it for consistency with FunDefn.)

Copy link
Contributor

@CAG2Mark CAG2Mark Mar 12, 2025

Choose a reason for hiding this comment

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

For consistency, we should also probably extract applyClsLikeDefn. Note that this may require some changes to overridden applyDefn methods.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know but ain't nobody got time for dat.

@@ -10,9 +10,12 @@ import os.write.over
// These all work like BlockTransformer and its derivatives, but do not rewrite the block. See BlockTransformer.scala.
// Please use this instead of BlockTransformer for static analysis.

class BlockTraverser(subst: SymbolSubst):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why would you need a symbol substitution in a block traverser? 🤔

)
.toMap

val varsList = cap.toList
Copy link
Contributor Author

Choose a reason for hiding this comment

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

You can't toList a set to get some arbitrary order, because that order is not well-defined. It could change depending on the object's memory address next time the compiler runs after minor modifications. But we need stable and reproducible compilation outputs.

@@ -234,55 +236,38 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
val FreeVars(_, cap) = ctx.usedLocals(f.sym)

val fresh = FreshInt()

val varsMap = cap.map: s =>
Copy link
Contributor Author

@LPTK LPTK Mar 11, 2025

Choose a reason for hiding this comment

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

The creation and subsequent repeated querying of this intermediate map was entirely gratuitous and resulted in needless overhead.

Comment on lines +240 to +257
val sortedVars = cap.toArray.sortBy(_.uid).map: sym =>
val id = fresh.make
val nme = sym.nme + id + "$"

val varSym = VarSymbol(Tree.Ident(nme))
val fldSym = BlockMemberSymbol(nme, Nil)

val p = Param(FldFlags.empty.copy(value = true), varSym, None)
varSym.decl = S(p) // * Currently this is only accessed to create the class' toString method

val vd = ValDefn(
S(clsSym),
syntax.ImmutVal,
fldSym,
Value.Ref(varSym)
)

(sym -> varSym, p, vd)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I now compute all the relevant things in one place that's much easier to inspect and understand.

sym.decl = S(p)
p
)),
S(PlainParamList(sortedVars.iterator.map(_._2).toList)),
Copy link
Contributor Author

@LPTK LPTK Mar 11, 2025

Choose a reason for hiding this comment

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

I use iterator here and below to avoid allocating intermediate collections.

@LPTK LPTK requested a review from CAG2Mark March 11, 2025 10:35
Copy link
Contributor

@CAG2Mark CAG2Mark left a comment

Choose a reason for hiding this comment

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

Looks good. There's just some small things you may have overlooked in addition to @FlandiaYingman's comments.

@@ -147,14 +147,17 @@ class BlockTransformer(subst: SymbolSubst):
if (own2 is fun.owner) && (sym2 is fun.sym) && (params2 is fun.params) && (body2 is fun.body)
then fun else FunDefn(own2, sym2, params2, body2)

def applyValDefn(defn: ValDefn): ValDefn =
Copy link
Contributor

@CAG2Mark CAG2Mark Mar 12, 2025

Choose a reason for hiding this comment

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

For consistency, we should also probably extract applyClsLikeDefn. Note that this may require some changes to overridden applyDefn methods.

@@ -120,12 +127,12 @@ class BlockTraverser(subst: SymbolSubst):
applySubBlock(lam.body)

def applyTermDefinition(td: TermDefinition): Unit =
Copy link
Contributor

Choose a reason for hiding this comment

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

This can now be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, I missed that one!

@LPTK LPTK merged commit d22a2b1 into hkust-taco:hkmc2 Mar 12, 2025
1 check passed
@LPTK LPTK deleted the defunkify-lifter branch March 12, 2025 13:57
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.

3 participants