001/*
002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test.ea;
024
025import java.util.*;
026
027import org.junit.*;
028
029import com.oracle.graal.compiler.test.*;
030import com.oracle.graal.nodes.*;
031import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
032import com.oracle.graal.nodes.java.*;
033import com.oracle.graal.phases.common.*;
034import com.oracle.graal.phases.common.inlining.*;
035import com.oracle.graal.phases.tiers.*;
036import com.oracle.graal.virtual.phases.ea.*;
037
038public class EarlyReadEliminationTest extends GraalCompilerTest {
039
040    protected StructuredGraph graph;
041
042    public static Object staticField;
043
044    public static class TestObject {
045
046        public int x;
047        public int y;
048
049        public TestObject(int x, int y) {
050            this.x = x;
051            this.y = y;
052        }
053    }
054
055    public static class TestObject2 {
056
057        public Object x;
058        public Object y;
059
060        public TestObject2(Object x, Object y) {
061            this.x = x;
062            this.y = y;
063        }
064    }
065
066    public static class TestObject3 extends TestObject {
067
068        public int z;
069
070        public TestObject3(int x, int y, int z) {
071            super(x, y);
072            this.z = z;
073        }
074    }
075
076    @SuppressWarnings("all")
077    public static int testSimpleSnippet(TestObject a) {
078        a.x = 2;
079        staticField = a;
080        return a.x;
081    }
082
083    @Test
084    public void testSimple() {
085        ValueNode result = getReturn("testSimpleSnippet").result();
086        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
087        assertTrue(result.isConstant());
088        assertDeepEquals(2, result.asJavaConstant().asInt());
089    }
090
091    @SuppressWarnings("all")
092    public static int testSimpleConflictSnippet(TestObject a, TestObject b) {
093        a.x = 2;
094        b.x = 3;
095        staticField = a;
096        return a.x;
097    }
098
099    @Test
100    public void testSimpleConflict() {
101        ValueNode result = getReturn("testSimpleConflictSnippet").result();
102        assertFalse(result.isConstant());
103        assertTrue(result instanceof LoadFieldNode);
104    }
105
106    @SuppressWarnings("all")
107    public static int testParamSnippet(TestObject a, int b) {
108        a.x = b;
109        return a.x;
110    }
111
112    @Test
113    public void testParam() {
114        ValueNode result = getReturn("testParamSnippet").result();
115        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
116        assertDeepEquals(graph.getParameter(1), result);
117    }
118
119    @SuppressWarnings("all")
120    public static int testMaterializedSnippet(int a) {
121        TestObject obj = new TestObject(a, 0);
122        staticField = obj;
123        return obj.x;
124    }
125
126    @Test
127    public void testMaterialized() {
128        ValueNode result = getReturn("testMaterializedSnippet").result();
129        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
130        assertDeepEquals(graph.getParameter(0), result);
131    }
132
133    @SuppressWarnings("all")
134    public static int testSimpleLoopSnippet(TestObject obj, int a, int b) {
135        obj.x = a;
136        for (int i = 0; i < 10; i++) {
137            staticField = obj;
138        }
139        return obj.x;
140    }
141
142    @Test
143    public void testSimpleLoop() {
144        ValueNode result = getReturn("testSimpleLoopSnippet").result();
145        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
146        assertDeepEquals(graph.getParameter(1), result);
147    }
148
149    @SuppressWarnings("all")
150    public static int testBadLoopSnippet(TestObject obj, TestObject obj2, int a, int b) {
151        obj.x = a;
152        for (int i = 0; i < 10; i++) {
153            staticField = obj;
154            obj2.x = 10;
155            obj.x = 0;
156        }
157        return obj.x;
158    }
159
160    @Test
161    public void testBadLoop() {
162        ValueNode result = getReturn("testBadLoopSnippet").result();
163        assertDeepEquals(0, graph.getNodes().filter(LoadFieldNode.class).count());
164        assertTrue(result instanceof ProxyNode);
165        assertTrue(((ProxyNode) result).value() instanceof ValuePhiNode);
166    }
167
168    @SuppressWarnings("all")
169    public static int testBadLoop2Snippet(TestObject obj, TestObject obj2, int a, int b) {
170        obj.x = a;
171        for (int i = 0; i < 10; i++) {
172            obj.x = 0;
173            obj2.x = 10;
174        }
175        return obj.x;
176    }
177
178    @Test
179    public void testBadLoop2() {
180        ValueNode result = getReturn("testBadLoop2Snippet").result();
181        assertDeepEquals(1, graph.getNodes().filter(LoadFieldNode.class).count());
182        assertTrue(result instanceof LoadFieldNode);
183    }
184
185    @SuppressWarnings("all")
186    public static int testPhiSnippet(TestObject a, int b) {
187        if (b < 0) {
188            a.x = 1;
189        } else {
190            a.x = 2;
191        }
192        return a.x;
193    }
194
195    @Test
196    public void testPhi() {
197        processMethod("testPhiSnippet");
198        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
199        List<ReturnNode> returnNodes = graph.getNodes(ReturnNode.TYPE).snapshot();
200        assertDeepEquals(2, returnNodes.size());
201        assertTrue(returnNodes.get(0).predecessor() instanceof StoreFieldNode);
202        assertTrue(returnNodes.get(1).predecessor() instanceof StoreFieldNode);
203        assertTrue(returnNodes.get(0).result().isConstant());
204        assertTrue(returnNodes.get(1).result().isConstant());
205    }
206
207    @SuppressWarnings("all")
208    public static void testSimpleStoreSnippet(TestObject a, int b) {
209        a.x = b;
210        a.x = b;
211    }
212
213    @Test
214    public void testSimpleStore() {
215        processMethod("testSimpleStoreSnippet");
216        assertDeepEquals(1, graph.getNodes().filter(StoreFieldNode.class).count());
217    }
218
219    public static int testValueProxySnippet(boolean b, TestObject o) {
220        int sum = 0;
221        if (b) {
222            sum += o.x;
223        } else {
224            TestObject3 p = (TestObject3) o;
225            sum += p.x;
226        }
227        sum += o.x;
228        return sum;
229    }
230
231    @Test
232    public void testValueProxy() {
233        processMethod("testValueProxySnippet");
234        assertDeepEquals(2, graph.getNodes().filter(LoadFieldNode.class).count());
235    }
236
237    ReturnNode getReturn(String snippet) {
238        processMethod(snippet);
239        assertDeepEquals(1, graph.getNodes(ReturnNode.TYPE).count());
240        return graph.getNodes(ReturnNode.TYPE).first();
241    }
242
243    protected void processMethod(String snippet) {
244        graph = parseEager(getResolvedJavaMethod(snippet), AllowAssumptions.NO);
245        HighTierContext context = getDefaultHighTierContext();
246        new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
247        new EarlyReadEliminationPhase(new CanonicalizerPhase()).apply(graph, context);
248    }
249}