@@ -91,12 +91,37 @@ sealed abstract class Block extends Product with AutoLocated:
9191 case TryBlock (sub, finallyDo, rest) => sub.freeVars ++ finallyDo.freeVars ++ rest.freeVars
9292 case Assign (lhs, rhs, rest) => Set (lhs) ++ rhs.freeVars ++ rest.freeVars
9393 case AssignField (lhs, nme, rhs, rest) => lhs.freeVars ++ rhs.freeVars ++ rest.freeVars
94+ case AssignDynField (lhs, fld, arrayIdx, rhs, rest) => lhs.freeVars ++ fld.freeVars ++ rhs.freeVars ++ rest.freeVars
9495 case Define (defn, rest) => defn.freeVars ++ rest.freeVars
9596 case HandleBlock (lhs, res, par, args, cls, hdr, bod, rst) =>
9697 (bod.freeVars - lhs) ++ rst.freeVars ++ hdr.flatMap(_.freeVars)
9798 case HandleBlockReturn (res) => res.freeVars
9899 case End (msg) => Set .empty
99100
101+ // TODO: freeVarsLLIR skips `fun` and `cls` in `Call` and `Instantiate` respectively, which is needed in some
102+ // other places. However, adding them breaks some LLIR tests. Supposedly, once the IR uses the new symbol system,
103+ // this should no longer happen. This version should be removed once that is resolved.
104+ lazy val freeVarsLLIR : Set [Local ] = this match
105+ case Match (scrut, arms, dflt, rest) =>
106+ scrut.freeVarsLLIR ++ dflt.toList.flatMap(_.freeVarsLLIR) ++ rest.freeVarsLLIR
107+ ++ arms.flatMap:
108+ (pat, arm) => arm.freeVarsLLIR -- pat.freeVars
109+ case Return (res, implct) => res.freeVarsLLIR
110+ case Throw (exc) => exc.freeVarsLLIR
111+ case Label (label, body, rest) => (body.freeVarsLLIR - label) ++ rest.freeVarsLLIR
112+ case Break (label) => Set (label)
113+ case Continue (label) => Set (label)
114+ case Begin (sub, rest) => sub.freeVarsLLIR ++ rest.freeVarsLLIR
115+ case TryBlock (sub, finallyDo, rest) => sub.freeVarsLLIR ++ finallyDo.freeVarsLLIR ++ rest.freeVarsLLIR
116+ case Assign (lhs, rhs, rest) => Set (lhs) ++ rhs.freeVarsLLIR ++ rest.freeVarsLLIR
117+ case AssignField (lhs, nme, rhs, rest) => lhs.freeVarsLLIR ++ rhs.freeVarsLLIR ++ rest.freeVarsLLIR
118+ case AssignDynField (lhs, fld, arrayIdx, rhs, rest) => lhs.freeVarsLLIR ++ fld.freeVarsLLIR ++ rhs.freeVarsLLIR ++ rest.freeVarsLLIR
119+ case Define (defn, rest) => defn.freeVarsLLIR ++ rest.freeVarsLLIR
120+ case HandleBlock (lhs, res, par, args, cls, hdr, bod, rst) =>
121+ (bod.freeVarsLLIR - lhs) ++ rst.freeVarsLLIR ++ hdr.flatMap(_.freeVars)
122+ case HandleBlockReturn (res) => res.freeVarsLLIR
123+ case End (msg) => Set .empty
124+
100125 lazy val subBlocks : Ls [Block ] = this match
101126 case Match (p, arms, dflt, rest) => p.subBlocks ++ arms.map(_._2) ++ dflt.toList :+ rest
102127 case Begin (sub, rest) => sub :: rest :: Nil
@@ -122,15 +147,19 @@ sealed abstract class Block extends Product with AutoLocated:
122147 // Note that this returns the definitions in reverse order, with the bottommost definiton appearing
123148 // last. This is so that using defns.foldLeft later to add the definitions to the front of a block,
124149 // we don't need to reverse the list again to preserve the order of the definitions.
125- def floatOutDefns =
150+ def floatOutDefns (
151+ ignore : Defn => Bool = _ => false ,
152+ preserve : Defn => Bool = _ => false
153+ ) =
126154 var defns : List [Defn ] = Nil
127155 val transformer = new BlockTransformerShallow (SymbolSubst ()):
128156 override def applyBlock (b : Block ): Block = b match
129- case Define (defn, rest) => defn match
157+ case Define (defn, rest) if ! ignore(defn) => defn match
130158 case v : ValDefn => super .applyBlock(b)
131159 case _ =>
132160 defns ::= defn
133- applyBlock(rest)
161+ if preserve(defn) then super .applyBlock(b)
162+ else applyBlock(rest)
134163 case _ => super .applyBlock(b)
135164
136165 (transformer.applyBlock(this ), defns)
@@ -281,10 +310,20 @@ sealed abstract class Defn:
281310 lazy val freeVars : Set [Local ] = this match
282311 case FunDefn (own, sym, params, body) => body.freeVars -- params.flatMap(_.paramSyms) - sym
283312 case ValDefn (owner, k, sym, rhs) => rhs.freeVars
284- case ClsLikeDefn (own, isym, sym, k, paramsOpt, parentSym, methods, privateFields, publicFields, preCtor, ctor) =>
313+ case ClsLikeDefn (own, isym, sym, k, paramsOpt, auxParams, parentSym,
314+ methods, privateFields, publicFields, preCtor, ctor) =>
285315 preCtor.freeVars
286316 ++ ctor.freeVars ++ methods.flatMap(_.freeVars)
287- -- privateFields -- publicFields.map(_.sym)
317+ -- privateFields -- publicFields.map(_.sym) -- auxParams.flatMap(_.paramSyms)
318+
319+ lazy val freeVarsLLIR : Set [Local ] = this match
320+ case FunDefn (own, sym, params, body) => body.freeVarsLLIR -- params.flatMap(_.paramSyms) - sym
321+ case ValDefn (owner, k, sym, rhs) => rhs.freeVarsLLIR
322+ case ClsLikeDefn (own, isym, sym, k, paramsOpt, auxParams, parentSym,
323+ methods, privateFields, publicFields, preCtor, ctor) =>
324+ preCtor.freeVarsLLIR
325+ ++ ctor.freeVarsLLIR ++ methods.flatMap(_.freeVarsLLIR)
326+ -- privateFields -- publicFields.map(_.sym) -- auxParams.flatMap(_.paramSyms)
288327
289328final case class FunDefn (
290329 owner : Opt [InnerSymbol ],
@@ -304,10 +343,11 @@ final case class ValDefn(
304343
305344final case class ClsLikeDefn (
306345 owner : Opt [InnerSymbol ],
307- isym : MemberSymbol [? <: ClassLikeDef ],
346+ isym : MemberSymbol [? <: ClassLikeDef ] & InnerSymbol ,
308347 sym : BlockMemberSymbol ,
309348 k : syntax.ClsLikeKind ,
310349 paramsOpt : Opt [ParamList ],
350+ auxParams : List [ParamList ],
311351 parentPath : Opt [Path ],
312352 methods : Ls [FunDefn ],
313353 privateFields : Ls [TermSymbol ],
@@ -325,6 +365,7 @@ final case class Handler(
325365 params : Ls [ParamList ],
326366 body : Block ,
327367):
368+ lazy val freeVarsLLIR : Set [Local ] = body.freeVarsLLIR -- params.flatMap(_.paramSyms) - sym - resumeSym
328369 lazy val freeVars : Set [Local ] = body.freeVars -- params.flatMap(_.paramSyms) - sym - resumeSym
329370
330371/* Represents either unreachable code (for functions that must return a result)
@@ -341,6 +382,11 @@ enum Case:
341382 case Cls (_, path) => path.freeVars
342383 case Tup (_, _) => Set .empty
343384
385+ lazy val freeVarsLLIR : Set [Local ] = this match
386+ case Lit (_) => Set .empty
387+ case Cls (_, path) => path.freeVarsLLIR
388+ case Tup (_, _) => Set .empty
389+
344390sealed abstract class Result :
345391
346392 // TODO rm Lam from values and thus the need for this method
@@ -353,14 +399,26 @@ sealed abstract class Result:
353399 case _ => Nil
354400
355401 lazy val freeVars : Set [Local ] = this match
356- case Call (fun, args) => args.flatMap(_.value.freeVars).toSet
357- case Instantiate (cls, args) => args.flatMap(_.freeVars).toSet
402+ case Call (fun, args) => fun.freeVars ++ args.flatMap(_.value.freeVars).toSet
403+ case Instantiate (cls, args) => cls.freeVars ++ args.flatMap(_.freeVars).toSet
358404 case Select (qual, name) => qual.freeVars
359405 case Value .Ref (l) => Set (l)
360406 case Value .This (sym) => Set .empty
361407 case Value .Lit (lit) => Set .empty
362408 case Value .Lam (params, body) => body.freeVars -- params.paramSyms
363409 case Value .Arr (elems) => elems.flatMap(_.value.freeVars).toSet
410+ case DynSelect (qual, fld, arrayIdx) => qual.freeVars ++ fld.freeVars
411+
412+ lazy val freeVarsLLIR : Set [Local ] = this match
413+ case Call (fun, args) => args.flatMap(_.value.freeVarsLLIR).toSet
414+ case Instantiate (cls, args) => args.flatMap(_.freeVarsLLIR).toSet
415+ case Select (qual, name) => qual.freeVarsLLIR
416+ case Value .Ref (l) => Set (l)
417+ case Value .This (sym) => Set .empty
418+ case Value .Lit (lit) => Set .empty
419+ case Value .Lam (params, body) => body.freeVarsLLIR -- params.paramSyms
420+ case Value .Arr (elems) => elems.flatMap(_.value.freeVarsLLIR).toSet
421+ case DynSelect (qual, fld, arrayIdx) => qual.freeVarsLLIR ++ fld.freeVarsLLIR
364422
365423// type Local = LocalSymbol
366424type Local = Symbol
@@ -375,6 +433,7 @@ case class Instantiate(cls: Path, args: Ls[Path]) extends Result
375433
376434sealed abstract class Path extends Result :
377435 def selN (id : Tree .Ident ): Path = Select (this , id)(N )
436+ def sel (id : Tree .Ident , sym : FieldSymbol ): Path = Select (this , id)(S (sym))
378437 def selSN (id : Str ): Path = selN(new Tree .Ident (id))
379438 def asArg = Arg (false , this )
380439
0 commit comments