blob: 5b3bc7b7467840abbbfbe1aad1f7ed43410019ff (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/**
* The only change is in the decision to replace a LOAD_LOCAL(l)
* in the copy-propagation performed before ClosureElimination.
*
* In the general case, the local variable 'l' is connected through
* a alias chain with other local variables and at the end of the
* alias chain there may be a Value, call it 'v'.
*
* If 'v' is cheaper to access (it is a Deref(This) or Const(_)), then
* replace the instruction to load it from the cheaper place.
* Otherwise, we use the local variable at the end of the alias chain
* instead of 'l'.
*/
import scala.tools.partest.IcodeTest
object Test extends IcodeTest {
override def printIcodeAfterPhase = "dce"
}
import scala.util.Random._
/**
* The example in the bug report (Issue-5321): an alias chain which store
* an Unknown. Should remove local variable 'y'.
*/
object TestBugReport {
def test(x: Int) = {
val y = x
println(y)
}
}
/**
* The code taken from scala.tools.nsc.settings.Settings:
* After inlining of the setter is performed, there is an opportunity for
* copy-propagation to eliminate some local variables.
*/
object TestSetterInline {
private var _postSetHook: this.type => Unit = (x: this.type) => ()
def withPostSetHook(f: this.type => Unit): this.type = { _postSetHook = f ; this }
}
/**
* The access of the local variable 'y' should be replaced by the
* constant.
*/
object TestAliasChainConstat {
def main(args: Array[String]): Unit = {
val x = 2
val y = x
println(y)
}
}
/**
* At the end of the alias chain we have a reference to 'this'.
* The local variables should be all discarded and replace by a
* direct reference to this
*/
class TestAliasChainDerefThis {
def main(args: Array[String]): Unit = {
val x = this
val y = x
println(y)
}
}
/**
* At the end of the alias chain, there is the value of a field.
* The use of variable 'y' should be replaced by 'x', not by an access
* to the field 'f' since it is more costly.
*/
object TestAliasChainDerefField {
def f = nextInt
def main(args: Array[String]): Unit = {
val x = f
val y = x
println(y)
}
}
/**
* The first time 'println' is called, 'x' is replaced by 'y'
* and the second time, 'y' is replaced by 'x'. But none of them
* can be removed.
*/
object TestDifferentBindings {
def main(args: Array[String]): Unit = {
var x = nextInt
var y = x
println(y)
y = nextInt
x = y
println(x)
}
}
|