Skip to content

Commit

Permalink
Merge pull request scala#4552 from lrytz/opt/closureInlining
Browse files Browse the repository at this point in the history
Closure elimination for new backend
  • Loading branch information
retronym committed Jun 24, 2015
2 parents 1b09e12 + 3e7776e commit 950bb26
Show file tree
Hide file tree
Showing 17 changed files with 1,268 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
if (AsmUtils.traceClassEnabled && cnode.name.contains(AsmUtils.traceClassPattern))
AsmUtils.traceClass(cnode)

if (settings.YoptInlinerEnabled) {
if (settings.YoptAddToBytecodeRepository) {
// The inliner needs to find all classes in the code repo, also those being compiled
byteCodeRepository.add(cnode, ByteCodeRepository.CompilationUnit)
}
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ abstract class BTypes {

val inliner: Inliner[this.type]

val closureOptimizer: ClosureOptimizer[this.type]

val callGraph: CallGraph[this.type]

val backendReporting: BackendReporting
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package scala.tools.nsc
package backend.jvm

import scala.tools.asm
import scala.tools.nsc.backend.jvm.opt.{LocalOpt, CallGraph, Inliner, ByteCodeRepository}
import scala.tools.nsc.backend.jvm.opt._
import scala.tools.nsc.backend.jvm.BTypes.{InlineInfo, MethodInlineInfo, InternalName}
import BackendReporting._
import scala.tools.nsc.settings.ScalaSettings
Expand Down Expand Up @@ -42,6 +42,8 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {

val inliner: Inliner[this.type] = new Inliner(this)

val closureOptimizer: ClosureOptimizer[this.type] = new ClosureOptimizer(this)

val callGraph: CallGraph[this.type] = new CallGraph(this)

val backendReporting: BackendReporting = new BackendReportingImpl(global)
Expand Down
22 changes: 22 additions & 0 deletions src/compiler/scala/tools/nsc/backend/jvm/BackendReporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,28 @@ object BackendReporting {
case class ResultingMethodTooLarge(calleeDeclarationClass: InternalName, name: String, descriptor: String,
callsiteClass: InternalName, callsiteName: String, callsiteDesc: String) extends CannotInlineWarning

/**
* Used in `rewriteClosureApplyInvocations` when a closure apply callsite cannot be rewritten
* to the closure body method.
*/
trait RewriteClosureApplyToClosureBodyFailed extends OptimizerWarning {
def pos: Position

override def emitWarning(settings: ScalaSettings): Boolean = this match {
case RewriteClosureAccessCheckFailed(_, cause) => cause.emitWarning(settings)
case RewriteClosureIllegalAccess(_, _) => settings.YoptWarningEmitAtInlineFailed
}

override def toString: String = this match {
case RewriteClosureAccessCheckFailed(_, cause) =>
s"Failed to rewrite the closure invocation to its implementation method:\n" + cause
case RewriteClosureIllegalAccess(_, callsiteClass) =>
s"The closure body invocation cannot be rewritten because the target method is not accessible in class $callsiteClass."
}
}
case class RewriteClosureAccessCheckFailed(pos: Position, cause: OptimizerWarning) extends RewriteClosureApplyToClosureBodyFailed
case class RewriteClosureIllegalAccess(pos: Position, callsiteClass: InternalName) extends RewriteClosureApplyToClosureBodyFailed

/**
* Used in the InlineInfo of a ClassBType, when some issue occurred obtaining the inline information.
*/
Expand Down
17 changes: 11 additions & 6 deletions src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -216,20 +216,25 @@ abstract class GenBCode extends BCodeSyncAndTry {
class Worker2 {
def runGlobalOptimizations(): Unit = {
import scala.collection.convert.decorateAsScala._
q2.asScala foreach {
case Item2(_, _, plain, _, _) =>
// skip mirror / bean: wd don't inline into tem, and they are not used in the plain class
if (plain != null) callGraph.addClass(plain)
if (settings.YoptBuildCallGraph) {
q2.asScala foreach {
case Item2(_, _, plain, _, _) =>
// skip mirror / bean: wd don't inline into tem, and they are not used in the plain class
if (plain != null) callGraph.addClass(plain)
}
}
bTypes.inliner.runInliner()
if (settings.YoptInlinerEnabled)
bTypes.inliner.runInliner()
if (settings.YoptClosureElimination)
closureOptimizer.rewriteClosureApplyInvocations()
}

def localOptimizations(classNode: ClassNode): Unit = {
BackendStats.timed(BackendStats.methodOptTimer)(localOpt.methodOptimizations(classNode))
}

def run() {
if (settings.YoptInlinerEnabled) runGlobalOptimizations()
runGlobalOptimizations()

while (true) {
val item = q2.poll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ object InstructionStackEffect {
val isSize2 = peekStack(0).getSize == 2
if (isSize2) t(1, 0) else t(2, 0)

case DUP => t(0, 1)
case DUP => t(1, 2)

case DUP_X1 => t(2, 3)

Expand All @@ -104,7 +104,7 @@ object InstructionStackEffect {

case DUP2 =>
val isSize2 = peekStack(0).getSize == 2
if (isSize2) t(0, 1) else t(0, 2)
if (isSize2) t(1, 2) else t(2, 4)

case DUP2_X1 =>
val isSize2 = peekStack(0).getSize == 2
Expand Down
Loading

0 comments on commit 950bb26

Please sign in to comment.