Skip to content

Move inlining into ReifyQuotes and remove Inlined from TASTy #5241

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions compiler/src/dotty/tools/dotc/CompilationUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,10 @@ class CompilationUnit(val source: SourceFile) {
/** Pickled TASTY binaries, indexed by class. */
var pickled: Map[ClassSymbol, Array[Byte]] = Map()

/** Will be reset to `true` if `tpdTree` contains a call to an inline method. The information
* is used in phase InlineCalls in order to avoid traversing an inline-less tree.
/** Will be set to `true` if contains `Quote`, `Splice` or calls to inline methods.
* The information is used in phase `Staging` in order to avoid traversing a quote-less tree.
*/
var containsInlineCalls: Boolean = false

/** Will be reset to `true` if `untpdTree` contains `Quote` trees. The information
* is used in phase ReifyQuotes in order to avoid traversing a quote-less tree.
*/
var containsQuotesOrSplices: Boolean = false
var needsStaging: Boolean = false

/** A structure containing a temporary map for generating inline accessors */
val inlineAccessors: InlineAccessors = new InlineAccessors
Expand All @@ -53,21 +48,18 @@ object CompilationUnit {
if (forceTrees) {
val force = new Force
force.traverse(unit1.tpdTree)
unit1.containsInlineCalls = force.containsInline
unit1.containsQuotesOrSplices = force.containsQuotes
unit1.needsStaging = force.needsStaging
}
unit1
}

/** Force the tree to be loaded */
private class Force extends TreeTraverser {
var containsInline = false
var containsQuotes = false
var needsStaging = false
def traverse(tree: Tree)(implicit ctx: Context): Unit = {
if (tree.symbol.isQuote)
containsQuotes = true
if (tpd.isInlineCall(tree))
containsInline = true
// Note that top-level splices are still inside the inline methods
if (tree.symbol.isQuote || tpd.isInlineCall(tree))
needsStaging = true
traverseChildren(tree)
}
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ class Compiler {
/** Phases dealing with TASTY tree pickling and unpickling */
protected def picklerPhases: List[List[Phase]] =
List(new Pickler) :: // Generate TASTY info
List(new InlineCalls) :: // β-reduce inline calls
List(new ReifyQuotes) :: // Turn quoted trees into explicit run-time data structures
List(new Staging) :: // Inline calls, expand macros and turn quoted trees into explicit run-time data structures
Nil

/** Phases dealing with the transformation from pickled trees to backend trees */
Expand Down
107 changes: 50 additions & 57 deletions compiler/src/dotty/tools/dotc/core/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ Standard-Section: "ASTs" TopLevelStat*
TYPED Length expr_Term ascriptionType_Tern
ASSIGN Length lhs_Term rhs_Term
BLOCK Length expr_Term Stat*
INLINED Length expr_Term call_Term? ValOrDefDef*
LAMBDA Length meth_Term target_Type?
IF Length cond_Term then_Term else_Term
MATCH Length sel_Term CaseDef*
Expand Down Expand Up @@ -185,7 +184,6 @@ Standard-Section: "ASTs" TopLevelStat*
OVERRIDE
INLINE
MACRO // inline method containing toplevel splices
INLINEPROXY // symbol of binding representing an inline parameter
STATIC // mapped to static Java member
OBJECT // an object or its class
TRAIT // a trait
Expand Down Expand Up @@ -236,7 +234,7 @@ Standard Section: "Comments" Comment*
object TastyFormat {

final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
val MajorVersion: Int = 11
val MajorVersion: Int = 12
val MinorVersion: Int = 0

/** Tags used to serialize names */
Expand Down Expand Up @@ -289,27 +287,26 @@ object TastyFormat {
final val IMPLICIT = 13
final val LAZY = 14
final val OVERRIDE = 15
final val INLINEPROXY = 16
final val INLINE = 17
final val STATIC = 18
final val OBJECT = 19
final val TRAIT = 20
final val ENUM = 21
final val LOCAL = 22
final val SYNTHETIC = 23
final val ARTIFACT = 24
final val MUTABLE = 25
final val LABEL = 26
final val FIELDaccessor = 27
final val CASEaccessor = 28
final val COVARIANT = 29
final val CONTRAVARIANT = 30
final val SCALA2X = 31
final val DEFAULTparameterized = 32
final val STABLE = 33
final val MACRO = 34
final val ERASED = 35
final val PARAMsetter = 36
final val INLINE = 16
final val STATIC = 17
final val OBJECT = 18
final val TRAIT = 19
final val ENUM = 20
final val LOCAL = 21
final val SYNTHETIC = 22
final val ARTIFACT = 23
final val MUTABLE = 24
final val LABEL = 25
final val FIELDaccessor = 26
final val CASEaccessor = 27
final val COVARIANT = 28
final val CONTRAVARIANT = 29
final val SCALA2X = 30
final val DEFAULTparameterized = 31
final val STABLE = 32
final val MACRO = 33
final val ERASED = 34
final val PARAMsetter = 35

// Cat. 2: tag Nat

Expand Down Expand Up @@ -383,36 +380,35 @@ object TastyFormat {
final val RETURN = 144
final val WHILE = 145
final val TRY = 146
final val INLINED = 147
final val SELECTouter = 148
final val REPEATED = 149
final val BIND = 150
final val ALTERNATIVE = 151
final val UNAPPLY = 152
final val ANNOTATEDtype = 153
final val ANNOTATEDtpt = 154
final val CASEDEF = 155
final val TEMPLATE = 156
final val SUPER = 157
final val SUPERtype = 158
final val REFINEDtype = 159
final val REFINEDtpt = 160
final val APPLIEDtype = 161
final val APPLIEDtpt = 162
final val TYPEBOUNDS = 163
final val TYPEBOUNDStpt = 164
final val ANDtype = 165
final val ANDtpt = 166
final val ORtype = 167
final val ORtpt = 168
final val POLYtype = 169
final val TYPELAMBDAtype = 170
final val LAMBDAtpt = 171
final val PARAMtype = 172
final val ANNOTATION = 173
final val TERMREFin = 174
final val TYPEREFin = 175
final val OBJECTDEF = 176
final val SELECTouter = 147
final val REPEATED = 148
final val BIND = 149
final val ALTERNATIVE = 150
final val UNAPPLY = 151
final val ANNOTATEDtype = 152
final val ANNOTATEDtpt = 153
final val CASEDEF = 154
final val TEMPLATE = 155
final val SUPER = 156
final val SUPERtype = 157
final val REFINEDtype = 158
final val REFINEDtpt = 159
final val APPLIEDtype = 160
final val APPLIEDtpt = 161
final val TYPEBOUNDS = 162
final val TYPEBOUNDStpt = 163
final val ANDtype = 164
final val ANDtpt = 165
final val ORtype = 166
final val ORtpt = 167
final val POLYtype = 168
final val TYPELAMBDAtype = 169
final val LAMBDAtpt = 170
final val PARAMtype = 171
final val ANNOTATION = 172
final val TERMREFin = 173
final val TYPEREFin = 174
final val OBJECTDEF = 175

// In binary: 101101EI
// I = implicit method type
Expand Down Expand Up @@ -462,7 +458,6 @@ object TastyFormat {
| LAZY
| OVERRIDE
| INLINE
| INLINEPROXY
| MACRO
| STATIC
| OBJECT
Expand Down Expand Up @@ -520,7 +515,6 @@ object TastyFormat {
case LAZY => "LAZY"
case OVERRIDE => "OVERRIDE"
case INLINE => "INLINE"
case INLINEPROXY => "INLINEPROXY"
case MACRO => "MACRO"
case STATIC => "STATIC"
case OBJECT => "OBJECT"
Expand Down Expand Up @@ -589,7 +583,6 @@ object TastyFormat {
case MATCH => "MATCH"
case RETURN => "RETURN"
case WHILE => "WHILE"
case INLINED => "INLINED"
case SELECTouter => "SELECTouter"
case TRY => "TRY"
case REPEATED => "REPEATED"
Expand Down
12 changes: 0 additions & 12 deletions compiler/src/dotty/tools/dotc/core/tasty/TreePickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -442,17 +442,6 @@ class TreePickler(pickler: TastyPickler) {
case SeqLiteral(elems, elemtpt) =>
writeByte(REPEATED)
withLength { pickleTree(elemtpt); elems.foreach(pickleTree) }
case Inlined(call, bindings, expansion) =>
writeByte(INLINED)
bindings.foreach(preRegister)
withLength {
pickleTree(expansion)
if (!call.isEmpty) pickleTree(call)
bindings.foreach { b =>
assert(b.isInstanceOf[DefDef] || b.isInstanceOf[ValDef])
pickleTree(b)
}
}
case Bind(name, body) =>
registerDef(tree.symbol)
writeByte(BIND)
Expand Down Expand Up @@ -619,7 +608,6 @@ class TreePickler(pickler: TastyPickler) {
if (flags is Case) writeByte(CASE)
if (flags is Override) writeByte(OVERRIDE)
if (flags is Inline) writeByte(INLINE)
if (flags is InlineProxy) writeByte(INLINEPROXY)
if (flags is Macro) writeByte(MACRO)
if (flags is JavaStatic) writeByte(STATIC)
if (flags is Module) writeByte(OBJECT)
Expand Down
12 changes: 0 additions & 12 deletions compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,6 @@ class TreeUnpickler(reader: TastyReader,
case LAZY => addFlag(Lazy)
case OVERRIDE => addFlag(Override)
case INLINE => addFlag(Inline)
case INLINEPROXY => addFlag(InlineProxy)
case MACRO => addFlag(Macro)
case STATIC => addFlag(JavaStatic)
case OBJECT => addFlag(Module)
Expand Down Expand Up @@ -1074,17 +1073,6 @@ class TreeUnpickler(reader: TastyReader,
val stats = readStats(ctx.owner, end)
val expr = exprReader.readTerm()
Block(stats, expr)
case INLINED =>
val exprReader = fork
skipTree()
def maybeCall = nextUnsharedTag match {
case VALDEF | DEFDEF => EmptyTree
case _ => readTerm()
}
val call = ifBefore(end)(maybeCall, EmptyTree)
val bindings = readStats(ctx.owner, end).asInstanceOf[List[ValOrDefDef]]
val expansion = exprReader.readTerm() // need bindings in scope, so needs to be read before
Inlined(call, bindings, expansion)
case IF =>
If(readTerm(), readTerm(), readTerm())
case LAMBDA =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dotty.tools.dotc.decompiler

import dotty.tools.dotc.fromtasty._
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.transform.InlineCalls

/** Compiler from tasty to user readable high text representation
* of the compiled scala code.
Expand All @@ -15,9 +14,7 @@ class TASTYDecompiler extends TASTYCompiler {
List(new ReadTastyTreesFromClasses) :: // Load classes from tasty
Nil

override protected def picklerPhases: List[List[Phase]] =
List(new InlineCalls) :: // TODO should we really inline for the decompiler?
Nil
override protected def picklerPhases: List[List[Phase]] = Nil

override protected def transformPhases: List[List[Phase]] = Nil

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import dotty.tools.dotc.core.StdNames.nme
import dotty.tools.dotc.core.Symbols.defn
import dotty.tools.dotc.core.Types.ExprType
import dotty.tools.dotc.core.quoted.PickledQuotes
import dotty.tools.dotc.transform.ReifyQuotes
import dotty.tools.dotc.transform.Staging
import dotty.tools.dotc.typer.FrontEnd
import dotty.tools.dotc.util.Positions.Position
import dotty.tools.dotc.util.SourceFile
Expand All @@ -30,7 +30,7 @@ class QuoteCompiler extends Compiler {
List(List(new QuotedFrontend(putInClass = true)))

override protected def picklerPhases: List[List[Phase]] =
List(List(new ReifyQuotes))
List(List(new Staging))

override def newRun(implicit ctx: Context): ExprRun = {
reset()
Expand Down
45 changes: 0 additions & 45 deletions compiler/src/dotty/tools/dotc/transform/InlineCalls.scala

This file was deleted.

4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase

if (sym.isSplice || sym.isQuote) {
markAsMacro(ctx)
ctx.compilationUnit.containsQuotesOrSplices = true
ctx.compilationUnit.needsStaging = true
}
}

private def handleInlineCall(sym: Symbol)(implicit ctx: Context): Unit = {
if (sym.is(Inline))
ctx.compilationUnit.containsInlineCalls = true
ctx.compilationUnit.needsStaging = true
}

override def transform(tree: Tree)(implicit ctx: Context): Tree =
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ object Splicer {
* and for `~xyz` the tree of `xyz` is interpreted for which the
* resulting expression is returned as a `Tree`
*
* See: `ReifyQuotes`
* See: `Staging`
*/
def splice(tree: Tree, pos: SourcePosition, classLoader: ClassLoader)(implicit ctx: Context): Tree = tree match {
case Quoted(quotedTree) => quotedTree
Expand Down Expand Up @@ -63,7 +63,7 @@ object Splicer {
* and for `~xyz` the tree of `xyz` is interpreted for which the
* resulting expression is returned as a `Tree`
*
* See: `ReifyQuotes`
* See: `Staging`
*/
def canBeSpliced(tree: Tree)(implicit ctx: Context): Boolean = tree match {
case Quoted(_) => true
Expand Down
Loading