Skip to content

Commit a853fe9

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 16c98cd commit a853fe9

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
@@ -496,32 +496,34 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
496496
val expansion1 = InlineTyper.typed(expansion, pt)(inlineCtx)
497497

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

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

507507
tpd.Inlined(call, bindings, expansion1)
508508
}
509509
}
510510

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

527529
/** A typer for inlined code. Its purpose is:
@@ -533,16 +535,13 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
533535
*/
534536
private object InlineTyper extends ReTyper {
535537

536-
var retainedClosures = Set[Symbol]()
538+
var retainedInlineables = Set[Symbol]()
537539

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

547546
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
548547
assert(tree.hasType, tree)
@@ -565,12 +564,13 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
565564
}
566565
}
567566

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

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)