summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-08-23 08:52:31 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-08-23 08:52:31 +0000
commit6892195b1f94b64e9749f52e2af4bf4c663e8dde (patch)
tree4b01e3826788f09889a7c4ada9c1420a943a4ed0 /src
parentd4e44a65651a1a45a5aae10af601cffbc27bd5f0 (diff)
downloadscala-6892195b1f94b64e9749f52e2af4bf4c663e8dde.tar.gz
scala-6892195b1f94b64e9749f52e2af4bf4c663e8dde.tar.bz2
scala-6892195b1f94b64e9749f52e2af4bf4c663e8dde.zip
Various fixes to optimizations, and mainly much...
Various fixes to optimizations, and mainly much better heuristics for inlining. Now even the compiler is some 3% faster! Yeah!
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala26
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTable.scala2
5 files changed, 29 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 8e3fe907a8..228ece4ea8 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -149,7 +149,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
def informTime(msg: String, start: Long) =
informProgress(msg + " in " + (currentTime - start) + "ms")
- def log(msg: AnyRef) {
+ /*@inline final*/ def log(msg: => AnyRef) {
if (settings.log contains phase.name) inform("[log " + phase + "] " + msg)
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index a5e2e978a3..91e1b4eb8a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -338,10 +338,10 @@ trait BasicBlocks {
* is closed, which sets the DIRTYSUCCS flag.
*/
def emit(instr: Instruction, pos: Position) {
- if (closed) {
+/* if (closed) {
print()
Console.println("trying to emit: " + instr)
- }
+ } */
assert(!closed || ignore, "BasicBlock closed")
if (!ignore) {
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index 0897b94a15..bbb84430c4 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -179,9 +179,9 @@ abstract class ClosureElimination extends SubComponent {
()
}
case Boxed(LocalVar(loc1)) :: _ =>
- val value = info.getBinding(loc1)
- bb.replaceInstruction(i, DROP(icodes.AnyRefReference) :: valueToInstruction(value) :: Nil)
- log("replaced " + i + " with " + value)
+ val loc2 = info.getAlias(loc1)
+ bb.replaceInstruction(i, DROP(icodes.AnyRefReference) :: valueToInstruction(Deref(LocalVar(loc2))) :: Nil)
+ log("replaced " + i + " with " + LocalVar(loc2))
case _ =>
()
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index 155bc17491..c0146bcd0c 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -118,6 +118,8 @@ abstract class Inliners extends SubComponent {
}
def analyzeMethod(m: IMethod): Unit = {
+ var sizeBeforeInlining = if (m.code ne null) m.code.blocks.length else 0
+ var instrBeforeInlining = if (m.code ne null) m.code.blocks.foldLeft(0)(_ + _.length) else 0
var retry = false
var count = 0
fresh.clear
@@ -170,6 +172,8 @@ abstract class Inliners extends SubComponent {
count += 1
pair.doInline(bb, i)
+ if (!inc.inline || inc.isMonadic)
+ caller.inlinedCalls += 1
inlinedMethodCount(inc.sym) += 1
/* Remove this method from the cache, as the calls-private relation
@@ -229,6 +233,12 @@ abstract class Inliners extends SubComponent {
while (retry && count < MAX_INLINE_RETRY)
m.normalize
+ if (sizeBeforeInlining > 0) {
+ val instrAfterInlining = m.code.blocks.foldLeft(0)(_ + _.length)
+ val prefix = if ((instrAfterInlining > 2 * instrBeforeInlining) && (instrAfterInlining > 200)) " !! " else ""
+ log(prefix + " %s blocks before inlining: %d (%d) after: %d (%d)".format(
+ m.symbol.fullName, sizeBeforeInlining, instrBeforeInlining, m.code.blocks.length, instrAfterInlining))
+ }
}
private def isMonadicMethod(sym: Symbol) = sym.name match {
@@ -297,13 +307,16 @@ abstract class Inliners extends SubComponent {
def instructions = blocks.flatten
def linearized = linearizer linearize m
- def isSmall = length <= SMALL_METHOD_SIZE
+ def isSmall = (length <= SMALL_METHOD_SIZE) && blocks(0).length < 10
def isLarge = length > MAX_INLINE_SIZE
def isRecursive = m.recursive
def hasCode = m.code != null
def hasSourceFile = m.sourceFile != null
def hasHandlers = handlers.nonEmpty
+ // the number of inlined calls in 'm', used by 'shouldInline'
+ var inlinedCalls = 0
+
def addLocals(ls: List[Local]) = m.locals ++= ls
def addLocal(l: Local) = addLocals(List(l))
def addHandlers(exhs: List[ExceptionHandler]) = m.exh = exhs ::: m.exh
@@ -622,6 +635,12 @@ abstract class Inliners extends SubComponent {
log("shouldInline: " + caller.m + " with " + inc.m)
var score = 0
+
+ // better not inline inside closures, but hope that the closure itself
+ // is repeatedly inlined
+ if (caller.isInClosure) score -= 2
+ else if (caller.inlinedCalls < 1) score -= 1 // only monadic methods can trigger the first inline
+
if (inc.isSmall)
score += 1
if (caller.isSmall && isLargeSum) {
@@ -633,7 +652,7 @@ abstract class Inliners extends SubComponent {
score -= 1
if (inc.isMonadic)
- score += 2
+ score += 3
else if (inc.isHigherOrder)
score += 1
if (inc.isInClosure)
@@ -641,8 +660,7 @@ abstract class Inliners extends SubComponent {
if (inc.numInlined > 2)
score -= 2
- if (settings.debug.value)
- log("shouldInline(" + inc.m + ") score: " + score)
+ log("shouldInline(" + inc.m + ") score: " + score)
score > 0
})
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
index 0fdbeae98f..04bc0564b8 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala
@@ -29,7 +29,7 @@ abstract class SymbolTable extends reflect.generic.Universe
{
def settings: Settings
def rootLoader: LazyType
- def log(msg: AnyRef)
+ def log(msg: => AnyRef)
def abort(msg: String) = throw new Error(msg)
def abort() = throw new Error()