From 7e736ed0a8109f00d721cb1a78152c91ef133b2d Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Thu, 6 Nov 2008 17:26:52 +0000 Subject: Fixed optimiser bugs, now all tests pass when u... Fixed optimiser bugs, now all tests pass when using the optimised compiler. --- .../scala/tools/nsc/backend/icode/Printers.scala | 2 +- .../backend/icode/analysis/CopyPropagation.scala | 23 +++++++++++++++++++--- .../tools/nsc/backend/opt/ClosureElimination.scala | 1 + .../scala/tools/nsc/backend/opt/Inliners.scala | 3 +++ test/files/run/infiniteloop.check | 1 + test/files/run/infiniteloop.scala | 13 ++++++++++++ test/files/run/missingparams.check | 1 + test/files/run/missingparams.scala | 21 ++++++++++++++++++++ 8 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 test/files/run/infiniteloop.check create mode 100644 test/files/run/infiniteloop.scala create mode 100644 test/files/run/missingparams.check create mode 100644 test/files/run/missingparams.scala diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala index 0bb634485c..4a5826e550 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala @@ -81,7 +81,7 @@ trait Printers { self: ICodes => def printMethod(m: IMethod): Unit = { print("def "); print(m.symbol.name); - print("("); printList(printParam)(m.params.reverse, ", "); print(")"); + print("("); printList(printParam)(m.params, ", "); print(")"); print(": "); print(m.symbol.info.resultType); if (!m.isDeferred) { diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 44b56dac79..9b9b58c39b 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -499,12 +499,29 @@ abstract class CopyPropagation { var values = in.stack.take(1 + ctor.info.paramTypes.length).reverse.drop(1); val bindings = new HashMap[Symbol, Value]; - if (settings.debug.value) log("getBindings for: " + ctor) + if (settings.debug.value) log("getBindings for: " + ctor + " acc: " + paramAccessors) + + var paramTypes = ctor.tpe.paramTypes + val diff = paramTypes.length - paramAccessors.length + diff match { + case 0 => () + case 1 if ctor.tpe.paramTypes.head == ctor.owner.rawowner.tpe => + // it's an unused outer + log("considering unused outer at position 0 in " + ctor.tpe.paramTypes) + paramTypes = paramTypes.tail + values = values.tail + case _ => + log("giving up on " + ctor + "(diff: " + diff + ")") + return bindings + } + // this relies on having the same order in paramAccessors and // the arguments on the stack. It should be the same! for ((p, i) <- paramAccessors.zipWithIndex) { -// assert(p.tpe == ctor.tpe.paramTypes(i), "In: " + ctor.fullNameString + " having: " + (paramAccessors map (_.tpe))+ " vs. " + ctor.tpe.paramTypes) - if (p.tpe == ctor.tpe.paramTypes(i)) +// assert(p.tpe == paramTypes(i), "In: " + ctor.fullNameString +// + " having acc: " + (paramAccessors map (_.tpe))+ " vs. params" + paramTypes +// + "\n\t failed at pos " + i + " with " + p.tpe + " == " + paramTypes(i)) + if (p.tpe == paramTypes(i)) bindings += (p -> values.head); values = values.tail; } diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index a041fa76fb..9a777ae413 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -99,6 +99,7 @@ abstract class ClosureElimination extends SubComponent { for (bb <- linearizer.linearize(m)) { var info = cpp.in(bb) + log("Cpp info at entry to block " + bb + ": " + info) for (i <- bb.toList) { i match { diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 62ae82797c..6cbfb8ce3a 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -149,6 +149,9 @@ abstract class Inliners extends SubComponent { case THIS(clasz) => LOAD_LOCAL(inlinedThis); + case STORE_THIS(_) => + STORE_LOCAL(inlinedThis) + case JUMP(whereto) => JUMP(inlinedBlock(whereto)); diff --git a/test/files/run/infiniteloop.check b/test/files/run/infiniteloop.check new file mode 100644 index 0000000000..be0b1437f1 --- /dev/null +++ b/test/files/run/infiniteloop.check @@ -0,0 +1 @@ +Stream(512, ?) diff --git a/test/files/run/infiniteloop.scala b/test/files/run/infiniteloop.scala new file mode 100644 index 0000000000..f15674a676 --- /dev/null +++ b/test/files/run/infiniteloop.scala @@ -0,0 +1,13 @@ +/** Tests the optimiser (not to loop on 'reverse'). */ + +object Test extends Application { + def foo { + val s3 = Stream.range(1, 1000) //100000 (ticket #153: Stackoverflow) + + // ticket #153 + def powers(x: Int) = if ((x&(x-1)) == 0) Some(x) else None + println(s3.flatMap(powers).reverse) + } + + foo +} diff --git a/test/files/run/missingparams.check b/test/files/run/missingparams.check new file mode 100644 index 0000000000..b0047fa49f --- /dev/null +++ b/test/files/run/missingparams.check @@ -0,0 +1 @@ +None diff --git a/test/files/run/missingparams.scala b/test/files/run/missingparams.scala new file mode 100644 index 0000000000..3672fdf76f --- /dev/null +++ b/test/files/run/missingparams.scala @@ -0,0 +1,21 @@ +/** Tests the optimiser. */ + +final class Foo(val x: Int) { + def filter(p: Int => Boolean) = + if (p(x)) Some(x) else None + + // test that the closure elimination is not wrongly replacing + // 'that' by 'this' + def intersect(that: Foo) = + filter { dummy => +// x // dummy + that.x > 0 + } +} + +object Test extends Application { + val foo1 = new Foo(42) + val foo2 = new Foo(-42) + + println(foo1 intersect foo2) +} -- cgit v1.2.3