Skip to content

Commit e2095de

Browse files
authored
Reduce special cases in Deadcode (#1379)
Since the optimizer calls `Deadcode(main)` explicitly, this also means that all unused show-related functions get removed when optimising :)
1 parent 1bae57f commit e2095de

3 files changed

Lines changed: 22 additions & 9 deletions

File tree

effekt/shared/src/main/scala/effekt/core/Show.scala

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ object Show extends Phase[CoreTransformed, CoreTransformed] {
1414
override val phaseName: String = "show"
1515

1616
private final val FUNCTION_NAME: String = "show"
17+
private final val FUNCTION_BUILTIN_NAME: String = "showBuiltin"
18+
private final val STRING_CONCAT_NAME: String = "infixPlusPlus"
19+
20+
/** Names that [[Deadcode]] must preserve for the [[Show]] pass to function correctly. */
21+
def requiredNames(core: ModuleDecl): Set[Id] = {
22+
val requiredExternNames = Set(FUNCTION_NAME, FUNCTION_BUILTIN_NAME, STRING_CONCAT_NAME)
23+
24+
core.externs.collect {
25+
case Extern.Def(id, _, _, _, _, _, _, _) if requiredExternNames.contains(id.name.name) => id
26+
}.toSet
27+
}
1728

1829
case class ShowContext(showNames: collection.mutable.Map[ValueType, Id], showDefns: collection.mutable.Map[ValueType, Toplevel.Def], tparamLookup: collection.mutable.Map[Id, ValueType]) {
1930

@@ -270,7 +281,7 @@ object Show extends Phase[CoreTransformed, CoreTransformed] {
270281
}
271282

272283
def findExternShowDef(valueType: ValueType)(using dctx: DeclarationContext)(using Context): Block.BlockVar =
273-
findExternDef("showBuiltin", List(valueType))
284+
findExternDef(FUNCTION_BUILTIN_NAME, List(valueType))
274285

275286
def findExternDef(name: String, vts: List[ValueType])(using dctx: DeclarationContext)(using Context): Block.BlockVar =
276287
dctx.findExternDef(name, vts) match
@@ -334,7 +345,7 @@ object Show extends Phase[CoreTransformed, CoreTransformed] {
334345

335346
def constructorStmt(constr: Constructor)(using ctx: ShowContext, dctx: DeclarationContext)(using Context): Stmt = constr match
336347
case Constructor(id, tparams, fields) =>
337-
val infixConcatBlockVar: Block.BlockVar = findExternDef("infixPlusPlus", List(TString, TString))
348+
val infixConcatBlockVar: Block.BlockVar = findExternDef(STRING_CONCAT_NAME, List(TString, TString))
338349
val pureFields = fields map fieldPure
339350
val concatenated = PureApp(infixConcatBlockVar, List.empty, List(Literal(id.name.name ++ "(", TString), concatPure(pureFields)))
340351

@@ -351,7 +362,7 @@ object Show extends Phase[CoreTransformed, CoreTransformed] {
351362
// =>
352363
// PureApp(concat, List(Literal("Just("), PureApp(concat, List(PureApp(show, x), PureApp(concat, List(Literal(", "), ...))))
353364
def concatPure(pures: List[(Id, Stmt.App)])(using ctx: ShowContext)(using Context, DeclarationContext): Expr =
354-
val infixConcatDef = findExternDef("infixPlusPlus", List(TString, TString))
365+
val infixConcatDef = findExternDef(STRING_CONCAT_NAME, List(TString, TString))
355366
pures match
356367
case (fieldId, _) :: next :: rest => PureApp(infixConcatDef, List.empty, List(Expr.ValueVar(fieldId, TString), PureApp(infixConcatDef, List.empty, List(Literal(", ", TString), concatPure(next :: rest)))))
357368
case (fieldId, _) :: Nil => PureApp(infixConcatDef, List.empty, List(Expr.ValueVar(fieldId, TString), Literal(")", TString)))

effekt/shared/src/main/scala/effekt/core/optimizer/Deadcode.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ class Deadcode(reachable: Map[Id, Usage])
4949
},
5050
// drop unreachable externs
5151
m.externs.collect {
52-
// We need to keep "show", "showBuiltin" & "infixPlusPlus" for generating show definitions (see #1123)
53-
case e: Extern.Def if used(e.id) || List("show", "showBuiltin", "infixPlusPlus").contains(e.id.name.name) => e
52+
case e: Extern.Def if used(e.id) => e
5453
case e: Extern.Include => e
5554
case e: Extern.Data if used(e.id) => e
5655
case e: Extern.Interface if used(e.id) => e
@@ -80,8 +79,11 @@ object Deadcode extends Phase[CoreTransformed, CoreTransformed] {
8079
input match {
8180
case CoreTransformed(source, tree, mod, core) =>
8281
val term = Context.ensureMainExists(mod)
82+
// when ran "directly" (i.e., before the 'Show' pass),
83+
// we add the functions required by subsequent passes
84+
val required = Set(term) ++ Show.requiredNames(core)
8385
val dce = Context.timed("deadcode-elimination", source.name) {
84-
Deadcode.remove(term, core)
86+
Deadcode.remove(required, core)
8587
}
8688
Some(CoreTransformed(source, tree, mod, dce))
8789
}

effekt/shared/src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package generator
33
package chez
44

55
import effekt.context.Context
6-
import effekt.core.optimizer.{DropBindings, Optimizer}
6+
import effekt.core.optimizer.{Optimizer, Deadcode}
77
import kiama.util.Source
88
import kiama.output.PrettyPrinterTypes.Document
99

@@ -37,7 +37,7 @@ class ChezSchemeCPS extends Compiler[String] {
3737
Frontend andThen Middleend
3838
}
3939

40-
lazy val Optimized = allToCore(Core) andThen Aggregate andThen Optimizer andThen core.Show map {
40+
lazy val Optimized = allToCore(Core) andThen Aggregate andThen Deadcode andThen core.Show andThen Optimizer map {
4141
case input @ CoreTransformed(source, tree, mod, core) =>
4242
val mainSymbol = Context.ensureMainExists(mod)
4343
val mainFile = path(mod)
@@ -66,4 +66,4 @@ class ChezSchemeCPS extends Compiler[String] {
6666

6767
def pretty(expr: chez.Expr): Document =
6868
chez.PrettyPrinter.pretty(chez.PrettyPrinter.toDoc(expr), 100)
69-
}
69+
}

0 commit comments

Comments
 (0)