~ubuntu-branches/debian/sid/scala/sid

« back to all changes in this revision

Viewing changes to src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg, Mehdi Dogguy, Lucas Satabin, Frank S. Thomas, Emmanuel Bourg
  • Date: 2015-06-05 23:52:59 UTC
  • mfrom: (1.2.11)
  • Revision ID: package-import@ubuntu.com-20150605235259-wk00vgk83dh8o19g
Tags: 2.10.5-1
* Team upload.

[ Mehdi Dogguy ]
* New upstream release (Closes: #744278).

[ Lucas Satabin ]
* Update patches
* Update the clean target
* Update paths of elements to install
* Update watch file

[ Frank S. Thomas ]
* Remove myself from Uploaders.

[ Emmanuel Bourg ]
* The package has been adopted by the Java Team (Closes: #754935)
* Patched the build to avoid downloading libraries from the Internet
* Replaced the minified JavaScript files with unobfuscated ones
* No longer build scala-partest.jar until diffutils is packaged or replaced
* debian/watch: Fixed the versions matched (x.y.z instead of x.y.z..z)
* debian/rules:
  - Added the missing get-orig-source target (Closes: #724704)
  - Improved the clean target
* debian/control:
  - Build depend on scala (>= 2.10) and bnd
  - Use canonical URLs for the Vcs-* fields
  - Standards-Version updated to 3.9.6 (no changes)
* Switch to debhelper level 9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 /* NSC -- new Scala compiler
2
 
 * Copyright 2005-2011 LAMP/EPFL
 
2
 * Copyright 2005-2013 LAMP/EPFL
3
3
 * @author  Iulian Dragos
4
4
 */
5
5
 
6
 
 
7
6
package scala.tools.nsc
8
7
package backend.opt
9
8
 
10
 
import scala.collection.mutable.{Map, HashMap}
11
9
import scala.tools.nsc.backend.icode.analysis.LubException
12
10
import scala.tools.nsc.symtab._
13
11
 
37
35
      case (STORE_LOCAL(x), LOAD_LOCAL(y)) if (x == y) =>
38
36
        var liveOut = liveness.out(bb)
39
37
        if (!liveOut(x)) {
40
 
          log("store/load to a dead local? " + x)
 
38
          debuglog("store/load to a dead local? " + x)
41
39
          val instrs = bb.getArray
42
40
          var idx = instrs.length - 1
43
41
          while (idx > 0 && (instrs(idx) ne i2)) {
45
43
            idx -= 1
46
44
          }
47
45
          if (!liveOut(x)) {
48
 
            log("removing dead store/load " + x)
 
46
            log("Removing dead store/load of " + x.sym.initialize.defString)
49
47
            Some(Nil)
50
48
          } else None
51
49
        } else
86
84
   */
87
85
  class ClosureElim {
88
86
    def analyzeClass(cls: IClass): Unit = if (settings.Xcloselim.value) {
 
87
      log(s"Analyzing ${cls.methods.size} methods in $cls.")
89
88
      cls.methods foreach { m =>
90
89
        analyzeMethod(m)
91
90
        peephole(m)
96
95
    import copyPropagation._
97
96
 
98
97
    /* Some embryonic copy propagation. */
99
 
    def analyzeMethod(m: IMethod): Unit = try {if (m.code ne null) {
100
 
      log("Analyzing " + m)
 
98
    def analyzeMethod(m: IMethod): Unit = try {if (m.hasCode) {
101
99
      cpp.init(m)
102
100
      cpp.run
103
101
 
104
 
      for (bb <- linearizer.linearize(m)) {
 
102
      m.linearizedBlocks() foreach { bb =>
105
103
        var info = cpp.in(bb)
106
 
        if (settings.debug.value) log("Cpp info at entry to block " + bb + ": " + info)
 
104
        debuglog("Cpp info at entry to block " + bb + ": " + info)
107
105
 
108
106
        for (i <- bb) {
109
107
          i match {
110
108
            case LOAD_LOCAL(l) if info.bindings isDefinedAt LocalVar(l) =>
111
109
              val t = info.getBinding(l)
112
110
              t match {
113
 
                case Deref(LocalVar(_)) | Deref(This) | Const(_) =>
 
111
                case Deref(This) | Const(_) =>
114
112
                  bb.replaceInstruction(i, valueToInstruction(t));
115
 
                  log("replaced " + i + " with " + t)
 
113
                  debuglog(s"replaced $i with $t")
116
114
 
117
115
                case _ =>
118
 
                  bb.replaceInstruction(i, LOAD_LOCAL(info.getAlias(l)))
119
 
                  log("replaced " + i + " with " + info.getAlias(l))
120
 
 
 
116
                  val t = info.getAlias(l)
 
117
                  bb.replaceInstruction(i, LOAD_LOCAL(t))
 
118
                  debuglog(s"replaced $i with $t")
121
119
              }
122
120
 
123
121
            case LOAD_FIELD(f, false) /* if accessible(f, m.symbol) */ =>
124
122
              def replaceFieldAccess(r: Record) {
125
123
                val Record(cls, bindings) = r
126
 
                info.getFieldNonRecordValue(r, f) match {
127
 
                        case Some(v) =>
128
 
                                bb.replaceInstruction(i,
129
 
                                                DROP(REFERENCE(cls)) :: valueToInstruction(v) :: Nil);
130
 
                                log("Replaced " + i + " with " + info.getFieldNonRecordValue(r, f));
131
 
                        case None =>
 
124
                info.getFieldNonRecordValue(r, f) foreach { v =>
 
125
                        bb.replaceInstruction(i, DROP(REFERENCE(cls)) :: valueToInstruction(v) :: Nil)
 
126
                        debuglog(s"replaced $i with $v")
132
127
                }
133
128
              }
134
129
 
152
147
                case _ =>
153
148
              }
154
149
 
155
 
            case UNBOX(_) =>
 
150
            case UNBOX(boxType) =>
156
151
              info.stack match {
157
152
                case Deref(LocalVar(loc1)) :: _ if info.bindings isDefinedAt LocalVar(loc1) =>
158
153
                  val value = info.getBinding(loc1)
159
154
                  value match {
160
 
                    case Boxed(LocalVar(loc2)) =>
 
155
                    case Boxed(LocalVar(loc2)) if loc2.kind == boxType =>
161
156
                      bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(info.getBinding(loc2)) :: Nil)
162
 
                      log("replaced " + i + " with " + info.getBinding(loc2))
 
157
                      debuglog("replaced " + i + " with " + info.getBinding(loc2))
163
158
                    case _ =>
164
159
                      ()
165
160
                  }
166
 
                case Boxed(LocalVar(loc1)) :: _ =>
 
161
                case Boxed(LocalVar(loc1)) :: _ if loc1.kind == boxType =>
167
162
                  val loc2 = info.getAlias(loc1)
168
163
                  bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(Deref(LocalVar(loc2))) :: Nil)
169
 
                  log("replaced " + i + " with " + LocalVar(loc2))
 
164
                  debuglog("replaced " + i + " with " + LocalVar(loc2))
170
165
                case _ =>
171
166
              }
172
167
 
203
198
  /** Peephole optimization. */
204
199
  abstract class PeepholeOpt {
205
200
 
206
 
    private var method: IMethod = null
 
201
    private var method: IMethod = NoIMethod
207
202
 
208
203
    /** Concrete implementations will perform their optimizations here */
209
204
    def peep(bb: BasicBlock, i1: Instruction, i2: Instruction): Option[List[Instruction]]
210
205
 
211
206
    var liveness: global.icodes.liveness.LivenessAnalysis = null
212
207
 
213
 
    def apply(m: IMethod): Unit = if (m.code ne null) {
 
208
    def apply(m: IMethod): Unit = if (m.hasCode) {
214
209
      method = m
215
210
      liveness = new global.icodes.liveness.LivenessAnalysis
216
211
      liveness.init(m)
217
212
      liveness.run
218
 
      for (b <- m.code.blocks)
219
 
        transformBlock(b)
 
213
      m foreachBlock transformBlock
220
214
    }
221
215
 
222
216
    def transformBlock(b: BasicBlock): Unit = if (b.size >= 2) {
223
 
      var newInstructions: List[Instruction] = Nil
224
 
 
225
 
      newInstructions = b.toList
226
 
 
 
217
      var newInstructions: List[Instruction] = b.toList
227
218
      var redo = false
 
219
 
228
220
      do {
229
221
        var h = newInstructions.head
230
222
        var t = newInstructions.tail
234
226
        while (t != Nil) {
235
227
          peep(b, h, t.head) match {
236
228
            case Some(newInstrs) =>
237
 
              newInstructions = seen.reverse ::: newInstrs ::: t.tail;
 
229
              newInstructions = seen reverse_::: newInstrs ::: t.tail
238
230
              redo = true
239
231
            case None =>
240
232
                ()