Skip to content

Commit 6de509d

Browse files
committed
Inline by-name parameters directly
Do not bind them to an auxiliary method. This has the advantage that we pass the actual quoted arguments to a macro implementation instead of passing proxies. To avoid code duplication, inline methods using an argument more than once should create a local auxiliary method instead. This is done in `trace.scala` and `Stats.scala`.
1 parent db8c875 commit 6de509d

File tree

3 files changed

+42
-36
lines changed

3 files changed

+42
-36
lines changed

compiler/src/dotty/tools/dotc/reporting/trace.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ object trace {
1414
conditionally(ctx.settings.YdebugTrace.value, question, false)(op)
1515

1616
@inline
17-
def conditionally[TC](cond: Boolean, question: => String, show: Boolean)(op: => TC)(implicit ctx: Context): TC =
18-
if (Config.tracingEnabled && cond) apply[TC](question, Printers.default, show)(op)
19-
else op
17+
def conditionally[TC](cond: Boolean, question: => String, show: Boolean)(op: => TC)(implicit ctx: Context): TC = {
18+
def op1 = op
19+
if (Config.tracingEnabled && cond) apply[TC](question, Printers.default, show)(op1)
20+
else op1
21+
}
2022

2123
@inline
22-
def apply[T](question: => String, printer: Printers.Printer, show: Boolean)(op: => T)(implicit ctx: Context): T =
23-
if (!Config.tracingEnabled || printer.eq(config.Printers.noPrinter)) op
24-
else doTrace[T](question, printer, show)(op)
24+
def apply[T](question: => String, printer: Printers.Printer, show: Boolean)(op: => T)(implicit ctx: Context): T = {
25+
def op1 = op
26+
if (!Config.tracingEnabled || printer.eq(config.Printers.noPrinter)) op1
27+
else doTrace[T](question, printer, show)(op1)
28+
}
2529

2630
@inline
2731
def apply[T](question: => String, printer: Printers.Printer)(op: => T)(implicit ctx: Context): T =

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -493,32 +493,34 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
493493
val expansion1 = InlineTyper.typed(expansion, pt)(inlineCtx)
494494

495495
/** Does given definition bind a closure that will be inlined? */
496-
def bindsDeadClosure(defn: ValOrDefDef) = Ident(defn.symbol.termRef) match {
497-
case InlineableClosure(_) => !InlineTyper.retainedClosures.contains(defn.symbol)
496+
def bindsDeadInlineable(defn: ValOrDefDef) = Ident(defn.symbol.termRef) match {
497+
case InlineableArg(_) => !InlineTyper.retainedInlineables.contains(defn.symbol)
498498
case _ => false
499499
}
500500

501501
/** All bindings in `bindingsBuf` except bindings of inlineable closures */
502-
val bindings = bindingsBuf.toList.filterNot(bindsDeadClosure).map(_.withPos(call.pos))
502+
val bindings = bindingsBuf.toList.filterNot(bindsDeadInlineable).map(_.withPos(call.pos))
503503

504504
tpd.Inlined(call, bindings, expansion1)
505505
}
506506
}
507507

508-
/** An extractor for references to closure arguments that refer to `@inline` methods */
509-
private object InlineableClosure {
508+
/** An extractor for references to inlineable arguments. These are :
509+
* - by-value arguments marked with `inline`
510+
* - all by-name arguments
511+
*/
512+
private object InlineableArg {
510513
lazy val paramProxies = paramProxy.values.toSet
511514
def unapply(tree: Ident)(implicit ctx: Context): Option[Tree] =
512-
if (paramProxies.contains(tree.tpe)) {
515+
if (paramProxies.contains(tree.tpe))
513516
bindingsBuf.find(_.name == tree.name) match {
514-
case Some(ddef: ValDef) if ddef.symbol.is(Inline) =>
515-
ddef.rhs match {
516-
case closure(_, meth, _) => Some(meth)
517-
case _ => None
518-
}
517+
case Some(vdef: ValDef) if vdef.symbol.is(Inline) =>
518+
Some(vdef.rhs.changeOwner(vdef.symbol, ctx.owner))
519+
case Some(ddef: DefDef) =>
520+
Some(ddef.rhs.changeOwner(ddef.symbol, ctx.owner))
519521
case _ => None
520522
}
521-
} else None
523+
else None
522524
}
523525

524526
/** A typer for inlined code. Its purpose is:
@@ -530,16 +532,13 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
530532
*/
531533
private object InlineTyper extends ReTyper {
532534

533-
var retainedClosures = Set[Symbol]()
535+
var retainedInlineables = Set[Symbol]()
534536

535-
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context) = {
536-
val tree1 = super.typedIdent(tree, pt)
537-
tree1 match {
538-
case InlineableClosure(_) => retainedClosures += tree.symbol
539-
case _ =>
537+
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context) =
538+
tree.asInstanceOf[tpd.Tree] match {
539+
case InlineableArg(rhs) => inlining.println(i"inline arg $tree -> $rhs"); rhs
540+
case _ => super.typedIdent(tree, pt)
540541
}
541-
tree1
542-
}
543542

544543
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
545544
assert(tree.hasType, tree)
@@ -562,12 +561,13 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
562561
}
563562
}
564563

565-
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context) = tree.asInstanceOf[tpd.Tree] match {
566-
case Apply(Select(InlineableClosure(fn), nme.apply), args) =>
567-
inlining.println(i"reducing $tree with closure $fn")
568-
typed(fn.appliedToArgs(args), pt)
569-
case _ =>
570-
super.typedApply(tree, pt)
571-
}
564+
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context) =
565+
tree.asInstanceOf[tpd.Tree] match {
566+
case Apply(Select(InlineableArg(closure(_, fn, _)), nme.apply), args) =>
567+
inlining.println(i"reducing $tree with closure $fn")
568+
typed(fn.appliedToArgs(args), pt)
569+
case _ =>
570+
super.typedApply(tree, pt)
571+
}
572572
}
573573
}

compiler/src/dotty/tools/dotc/util/Stats.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ import collection.mutable
4646
def trackTime[T](fn: String)(op: => T) =
4747
if (enabled) doTrackTime(fn)(op) else op
4848

49-
def doTrackTime[T](fn: String)(op: => T) =
49+
def doTrackTime[T](fn: String)(op: => T) = {
50+
def op1 = op
5051
if (monitored) {
5152
val start = System.nanoTime
52-
try op finally record(fn, ((System.nanoTime - start) / 1000).toInt)
53-
} else op
53+
try op1 finally record(fn, ((System.nanoTime - start) / 1000).toInt)
54+
} else op1
55+
}
5456

5557
class HeartBeat extends Thread() {
5658
@volatile private[Stats] var continue = true

0 commit comments

Comments
 (0)