Skip to content
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

Remove ICode (re-submission) #4838

Merged
merged 6 commits into from
Nov 10, 2015
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
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/ant/Scalac.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ class Scalac extends ScalaMatchingTask with ScalacShared {
val values = List("namer", "typer", "pickler", "refchecks",
"uncurry", "tailcalls", "specialize", "explicitouter",
"erasure", "lazyvals", "lambdalift", "constructors",
"flatten", "mixin", "delambdafy", "cleanup", "icode", "inliner",
"closelim", "dce", "jvm", "terminal")
"flatten", "mixin", "delambdafy", "cleanup", "icode",
"jvm", "terminal")
}

/** Defines valid values for the `target` property. */
Expand Down
4 changes: 1 addition & 3 deletions src/compiler/scala/tools/nsc/CompilationUnits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,7 @@ trait CompilationUnits { global: Global =>
*/
def targetPos: Position = NoPosition

/** The icode representation of classes in this compilation unit.
* It is empty up to phase 'icode'.
*/
/** For sbt compatibility (https://github.com/scala/scala/pull/4588) */
val icode: LinkedHashSet[icodes.IClass] = new LinkedHashSet

@deprecated("Call global.reporter.echo directly instead.", "2.11.2")
Expand Down
141 changes: 14 additions & 127 deletions src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ package scala
package tools
package nsc

import java.io.{ File, FileOutputStream, PrintWriter, IOException, FileNotFoundException }
import java.io.{ File, IOException, FileNotFoundException }
import java.net.URL
import java.nio.charset.{ Charset, CharsetDecoder, IllegalCharsetNameException, UnsupportedCharsetException }
import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
import reporters.Reporter
import util.{ ClassFileLookup, ClassPath, MergedClassPath, StatisticsInfo, returning }
import scala.reflect.ClassTag
import scala.reflect.internal.util.{ ScalaClassLoader, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile }
Expand All @@ -25,11 +25,8 @@ import ast.parser._
import typechecker._
import transform.patmat.PatternMatching
import transform._
import backend.icode.{ ICodes, GenICode, ICodeCheckers }
import backend.{ ScalaPrimitives, JavaPlatform }
import backend.jvm.GenBCode
import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
import scala.language.postfixOps
import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
import scala.tools.nsc.classpath.FlatClassPath
Expand Down Expand Up @@ -139,12 +136,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val global: Global.this.type = Global.this
} with ConstantFolder

/** ICode generator */
object icodes extends {
val global: Global.this.type = Global.this
} with ICodes
/** For sbt compatibility (https://github.com/scala/scala/pull/4588) */
object icodes {
class IClass(val symbol: Symbol)
}

/** Scala primitives, used in genicode */
/** Scala primitives, used the backend */
object scalaPrimitives extends {
val global: Global.this.type = Global.this
} with ScalaPrimitives
Expand All @@ -156,18 +153,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)

type SymbolPair = overridingPairs.SymbolPair

// Optimizer components

/** ICode analysis for optimization */
object analysis extends {
val global: Global.this.type = Global.this
} with TypeFlowAnalysis

/** Copy propagation for optimization */
object copyPropagation extends {
val global: Global.this.type = Global.this
} with CopyPropagation

// Components for collecting and generating output

/** Some statistics (normally disabled) set with -Ystatistics */
Expand Down Expand Up @@ -590,52 +575,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val runsRightAfter = None
} with Delambdafy

// phaseName = "icode"
object genicode extends {
val global: Global.this.type = Global.this
val runsAfter = List("cleanup")
val runsRightAfter = None
} with GenICode

// phaseName = "inliner"
object inliner extends {
val global: Global.this.type = Global.this
val runsAfter = List("icode")
val runsRightAfter = None
} with Inliners

// phaseName = "inlinehandlers"
object inlineExceptionHandlers extends {
val global: Global.this.type = Global.this
val runsAfter = List("inliner")
val runsRightAfter = None
} with InlineExceptionHandlers

// phaseName = "closelim"
object closureElimination extends {
val global: Global.this.type = Global.this
val runsAfter = List("inlinehandlers")
val runsRightAfter = None
} with ClosureElimination

// phaseName = "constopt"
object constantOptimization extends {
val global: Global.this.type = Global.this
val runsAfter = List("closelim")
val runsRightAfter = None
} with ConstantOptimization

// phaseName = "dce"
object deadCode extends {
val global: Global.this.type = Global.this
val runsAfter = List("closelim")
val runsRightAfter = None
} with DeadCodeElimination

// phaseName = "bcode"
object genBCode extends {
val global: Global.this.type = Global.this
val runsAfter = List("dce")
val runsAfter = List("cleanup")
val runsRightAfter = None
} with GenBCode

Expand Down Expand Up @@ -666,13 +609,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val global: Global.this.type = Global.this
} with TreeCheckers

/** Icode verification */
object icodeCheckers extends {
val global: Global.this.type = Global.this
} with ICodeCheckers

object icodeChecker extends icodeCheckers.ICodeChecker()

object typer extends analyzer.Typer(
analyzer.NoContext.make(EmptyTree, RootClass, newScope)
)
Expand Down Expand Up @@ -705,12 +641,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
mixer -> "mixin composition",
delambdafy -> "remove lambdas",
cleanup -> "platform-specific cleanups, generate reflective calls",
genicode -> "generate portable intermediate code",
inliner -> "optimization: do inlining",
inlineExceptionHandlers -> "optimization: inline exception handlers",
closureElimination -> "optimization: eliminate uncalled closures",
constantOptimization -> "optimization: optimize null and other constants",
deadCode -> "optimization: eliminate dead code",
terminal -> "the last phase during a compilation run"
)

Expand Down Expand Up @@ -1049,9 +979,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
@inline final def enteringErasure[T](op: => T): T = enteringPhase(currentRun.erasurePhase)(op)
@inline final def enteringExplicitOuter[T](op: => T): T = enteringPhase(currentRun.explicitouterPhase)(op)
@inline final def enteringFlatten[T](op: => T): T = enteringPhase(currentRun.flattenPhase)(op)
@inline final def enteringIcode[T](op: => T): T = enteringPhase(currentRun.icodePhase)(op)
@inline final def enteringMixin[T](op: => T): T = enteringPhase(currentRun.mixinPhase)(op)
@inline final def enteringDelambdafy[T](op: => T): T = enteringPhase(currentRun.delambdafyPhase)(op)
@inline final def enteringJVM[T](op: => T): T = enteringPhase(currentRun.jvmPhase)(op)
@inline final def enteringPickler[T](op: => T): T = enteringPhase(currentRun.picklerPhase)(op)
@inline final def enteringSpecialize[T](op: => T): T = enteringPhase(currentRun.specializePhase)(op)
@inline final def enteringTyper[T](op: => T): T = enteringPhase(currentRun.typerPhase)(op)
Expand Down Expand Up @@ -1325,8 +1255,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// val superaccessorsPhase = phaseNamed("superaccessors")
val picklerPhase = phaseNamed("pickler")
val refchecksPhase = phaseNamed("refchecks")
// val selectiveanfPhase = phaseNamed("selectiveanf")
// val selectivecpsPhase = phaseNamed("selectivecps")
val uncurryPhase = phaseNamed("uncurry")
// val tailcallsPhase = phaseNamed("tailcalls")
val specializePhase = phaseNamed("specialize")
Expand All @@ -1340,20 +1268,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val mixinPhase = phaseNamed("mixin")
val delambdafyPhase = phaseNamed("delambdafy")
val cleanupPhase = phaseNamed("cleanup")
val icodePhase = phaseNamed("icode")
val inlinerPhase = phaseNamed("inliner")
val inlineExceptionHandlersPhase = phaseNamed("inlinehandlers")
val closelimPhase = phaseNamed("closelim")
val dcePhase = phaseNamed("dce")
// val jvmPhase = phaseNamed("jvm")
val jvmPhase = phaseNamed("jvm")

def runIsAt(ph: Phase) = globalPhase.id == ph.id
def runIsAtOptimiz = {
runIsAt(inlinerPhase) || // listing phases in full for robustness when -Ystop-after has been given.
runIsAt(inlineExceptionHandlersPhase) ||
runIsAt(closelimPhase) ||
runIsAt(dcePhase)
}
def runIsAtOptimiz = runIsAt(jvmPhase)

isDefined = true

Expand Down Expand Up @@ -1416,8 +1334,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)

if (canCheck) {
phase = globalPhase
if (globalPhase.id >= icodePhase.id) icodeChecker.checkICodes()
else treeChecker.checkTrees()
if (globalPhase.id <= cleanupPhase.id)
treeChecker.checkTrees()
}
}

Expand Down Expand Up @@ -1498,14 +1416,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)

// progress update
informTime(globalPhase.description, startTime)
val shouldWriteIcode = (
(settings.writeICode.isSetByUser && (settings.writeICode containsPhase globalPhase))
|| (!settings.Xprint.doAllPhases && (settings.Xprint containsPhase globalPhase) && runIsAtOptimiz)
)
if (shouldWriteIcode) {
// Write *.icode files when -Xprint-icode or -Xprint:<some-optimiz-phase> was given.
writeICode()
} else if ((settings.Xprint containsPhase globalPhase) || settings.printLate && runIsAt(cleanupPhase)) {
if ((settings.Xprint containsPhase globalPhase) || settings.printLate && runIsAt(cleanupPhase)) {
// print trees
if (settings.Xshowtrees || settings.XshowtreesCompact || settings.XshowtreesStringified) nodePrinters.printAll()
else printAllUnits()
Expand Down Expand Up @@ -1670,30 +1581,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Returns the file with the given suffix for the given class. Used for icode writing. */
def getFile(clazz: Symbol, suffix: String): File = getFile(clazz.sourceFile, clazz.fullName split '.', suffix)

private def writeICode() {
val printer = new icodes.TextPrinter(writer = null, icodes.linearizer)
icodes.classes.values foreach { cls =>
val file = {
val module = if (cls.symbol.hasModuleFlag) "$" else ""
val faze = if (settings.debug) phase.name else f"${phase.id}%02d" // avoid breaking windows build with long filename
getFile(cls.symbol, s"$module-$faze.icode")
}

try {
val stream = new FileOutputStream(file)
printer.setWriter(new PrintWriter(stream, true))
try
printer.printClass(cls)
finally
stream.close()
informProgress(s"wrote $file")
} catch {
case e: IOException =>
if (settings.debug) e.printStackTrace()
globalError(s"could not write file $file")
}
}
}
def createJavadoc = false
}

Expand Down
43 changes: 9 additions & 34 deletions src/compiler/scala/tools/nsc/backend/ScalaPrimitives.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ abstract class ScalaPrimitives {

import global._
import definitions._
import global.icodes._

// Arithmetic unary operations
final val POS = 1 // +x
Expand Down Expand Up @@ -457,18 +456,6 @@ abstract class ScalaPrimitives {

def isCoercion(code: Int): Boolean = (code >= B2B) && (code <= D2D)

final val typeOfArrayOp: Map[Int, TypeKind] = Map(
(List(ZARRAY_LENGTH, ZARRAY_GET, ZARRAY_SET) map (_ -> BOOL)) ++
(List(BARRAY_LENGTH, BARRAY_GET, BARRAY_SET) map (_ -> BYTE)) ++
(List(SARRAY_LENGTH, SARRAY_GET, SARRAY_SET) map (_ -> SHORT)) ++
(List(CARRAY_LENGTH, CARRAY_GET, CARRAY_SET) map (_ -> CHAR)) ++
(List(IARRAY_LENGTH, IARRAY_GET, IARRAY_SET) map (_ -> INT)) ++
(List(LARRAY_LENGTH, LARRAY_GET, LARRAY_SET) map (_ -> LONG)) ++
(List(FARRAY_LENGTH, FARRAY_GET, FARRAY_SET) map (_ -> FLOAT)) ++
(List(DARRAY_LENGTH, DARRAY_GET, DARRAY_SET) map (_ -> DOUBLE)) ++
(List(OARRAY_LENGTH, OARRAY_GET, OARRAY_SET) map (_ -> REFERENCE(AnyRefClass))) : _*
)

/** Check whether the given operation code is an array operation. */
def isArrayOp(code: Int): Boolean =
isArrayNew(code) | isArrayLength(code) | isArrayGet(code) | isArraySet(code)
Expand Down Expand Up @@ -535,24 +522,11 @@ abstract class ScalaPrimitives {
case _ => false
}

/** If code is a coercion primitive, the result type */
def generatedKind(code: Int): TypeKind = code match {
case B2B | C2B | S2B | I2B | L2B | F2B | D2B => BYTE
case B2C | C2C | S2C | I2C | L2C | F2C | D2C => CHAR
case B2S | C2S | S2S | I2S | L2S | F2S | D2S => SHORT
case B2I | C2I | S2I | I2I | L2I | F2I | D2I => INT
case B2L | C2L | S2L | I2L | L2L | F2L | D2L => LONG
case B2F | C2F | S2F | I2F | L2F | F2F | D2F => FLOAT
case B2D | C2D | S2D | I2D | L2D | F2D | D2D => DOUBLE
}

def isPrimitive(sym: Symbol): Boolean = primitives contains sym

/** Return the code for the given symbol. */
def getPrimitive(sym: Symbol): Int = {
assert(isPrimitive(sym), "Unknown primitive " + sym)
primitives(sym)
}
def getPrimitive(sym: Symbol): Int =
primitives.getOrElse(sym, throw new AssertionError(s"Unknown primitive $sym"))

/**
* Return the primitive code of the given operation. If the
Expand All @@ -565,6 +539,7 @@ abstract class ScalaPrimitives {
*/
def getPrimitive(fun: Symbol, tpe: Type): Int = {
import definitions._
import genBCode.bTypes._
val code = getPrimitive(fun)

def elementType = enteringTyper {
Expand All @@ -577,7 +552,7 @@ abstract class ScalaPrimitives {
code match {

case APPLY =>
toTypeKind(elementType) match {
typeToBType(elementType) match {
case BOOL => ZARRAY_GET
case BYTE => BARRAY_GET
case SHORT => SARRAY_GET
Expand All @@ -586,13 +561,13 @@ abstract class ScalaPrimitives {
case LONG => LARRAY_GET
case FLOAT => FARRAY_GET
case DOUBLE => DARRAY_GET
case REFERENCE(_) | ARRAY(_) => OARRAY_GET
case _: ClassBType | _: ArrayBType => OARRAY_GET
case _ =>
abort("Unexpected array element type: " + elementType)
}

case UPDATE =>
toTypeKind(elementType) match {
typeToBType(elementType) match {
case BOOL => ZARRAY_SET
case BYTE => BARRAY_SET
case SHORT => SARRAY_SET
Expand All @@ -601,13 +576,13 @@ abstract class ScalaPrimitives {
case LONG => LARRAY_SET
case FLOAT => FARRAY_SET
case DOUBLE => DARRAY_SET
case REFERENCE(_) | ARRAY(_) => OARRAY_SET
case _: ClassBType | _: ArrayBType => OARRAY_SET
case _ =>
abort("Unexpected array element type: " + elementType)
}

case LENGTH =>
toTypeKind(elementType) match {
typeToBType(elementType) match {
case BOOL => ZARRAY_LENGTH
case BYTE => BARRAY_LENGTH
case SHORT => SARRAY_LENGTH
Expand All @@ -616,7 +591,7 @@ abstract class ScalaPrimitives {
case LONG => LARRAY_LENGTH
case FLOAT => FARRAY_LENGTH
case DOUBLE => DARRAY_LENGTH
case REFERENCE(_) | ARRAY(_) => OARRAY_LENGTH
case _: ClassBType | _: ArrayBType => OARRAY_LENGTH
case _ =>
abort("Unexpected array element type: " + elementType)
}
Expand Down
Loading