001/*
002 * Copyright (c) 2011, 2014, 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 jdk.internal.jvmci.common.*;
026
027import org.junit.*;
028
029import sun.misc.*;
030
031import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
032import com.oracle.graal.nodes.extended.*;
033import com.oracle.graal.nodes.java.*;
034import com.oracle.graal.phases.common.*;
035import com.oracle.graal.phases.common.inlining.*;
036import com.oracle.graal.phases.tiers.*;
037import com.oracle.graal.virtual.phases.ea.*;
038
039public class PEAReadEliminationTest extends EarlyReadEliminationTest {
040
041    public static int testIndexed1Snippet(int[] array) {
042        array[1] = 1;
043        array[2] = 2;
044        array[3] = 3;
045        array[4] = 4;
046        array[5] = 5;
047        array[6] = 6;
048        return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
049    }
050
051    @Test
052    public void testIndexed1() {
053        processMethod("testIndexed1Snippet");
054        assertDeepEquals(0, graph.getNodes().filter(LoadIndexedNode.class).count());
055    }
056
057    public static int testIndexed2Snippet(int v, int[] array) {
058        array[1] = 1;
059        array[2] = 2;
060        array[3] = 3;
061        array[v] = 0;
062        array[4] = 4;
063        array[5] = 5;
064        array[6] = 6;
065        array[4] = 4;
066        array[5] = 5;
067        array[6] = 6;
068        return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
069    }
070
071    @Test
072    public void testIndexed2() {
073        processMethod("testIndexed2Snippet");
074        assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
075        assertDeepEquals(7, graph.getNodes().filter(StoreIndexedNode.class).count());
076    }
077
078    public static int testIndexed3Snippet(int v, int[] array, short[] array2) {
079        array[1] = 1;
080        array2[1] = 1;
081        array[2] = 2;
082        array2[2] = 2;
083        array[3] = 3;
084        array2[3] = 3;
085        array[v] = 0;
086        array[4] = 4;
087        array2[4] = 4;
088        array[5] = 5;
089        array2[5] = 5;
090        array[6] = 6;
091        array2[6] = 6;
092        return array[1] + array[2] + array[3] + array[4] + array[5] + array[6] + array2[1] + array2[2] + array2[3] + array2[4] + array2[5] + array2[6];
093    }
094
095    @Test
096    public void testIndexed3() {
097        processMethod("testIndexed3Snippet");
098        assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
099    }
100
101    private static native void nonInlineable();
102
103    public static int testIndexed4Snippet(int[] array) {
104        array[1] = 1;
105        array[2] = 2;
106        array[3] = 3;
107        nonInlineable();
108        array[4] = 4;
109        array[5] = 5;
110        array[6] = 6;
111        return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
112    }
113
114    @Test
115    public void testIndexed4() {
116        processMethod("testIndexed4Snippet");
117        assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
118    }
119
120    private static final long offsetInt1 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 1;
121    private static final long offsetInt2 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 2;
122
123    public static int testUnsafe1Snippet(int v, int[] array) {
124        int s = UnsafeAccess.unsafe.getInt(array, offsetInt1);
125        UnsafeAccess.unsafe.putInt(array, offsetInt1, v);
126        UnsafeAccess.unsafe.putInt(array, offsetInt2, v);
127        return s + UnsafeAccess.unsafe.getInt(array, offsetInt1) + UnsafeAccess.unsafe.getInt(array, offsetInt2);
128    }
129
130    @Test
131    public void testUnsafe1() {
132        processMethod("testUnsafe1Snippet");
133        assertDeepEquals(1, graph.getNodes().filter(UnsafeLoadNode.class).count());
134    }
135
136    public static int testUnsafe2Snippet(int v, Object array) {
137        int s = UnsafeAccess.unsafe.getInt(array, offsetInt1);
138        UnsafeAccess.unsafe.putInt(array, offsetInt1, v);
139        UnsafeAccess.unsafe.putInt(array, offsetInt2, v);
140        return s + UnsafeAccess.unsafe.getInt(array, offsetInt1) + UnsafeAccess.unsafe.getInt(array, offsetInt2);
141    }
142
143    @Test
144    public void testUnsafe2() {
145        processMethod("testUnsafe2Snippet");
146        assertDeepEquals(3, graph.getNodes().filter(UnsafeLoadNode.class).count());
147    }
148
149    private static final long offsetObject1 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 1;
150    private static final long offsetObject2 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 2;
151
152    public static int testUnsafe3Snippet(int v, Object[] array) {
153        int s = (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject1);
154        UnsafeAccess.unsafe.putObject(array, offsetObject1, v);
155        UnsafeAccess.unsafe.putObject(array, offsetObject2, v);
156        return s + (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject1) + (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject2);
157    }
158
159    @Test
160    public void testUnsafe3() {
161        processMethod("testUnsafe3Snippet");
162        assertDeepEquals(1, graph.getNodes().filter(UnsafeLoadNode.class).count());
163    }
164
165    public static int testUnsafe4Snippet(int v, Object[] array) {
166        int s = (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject1);
167        UnsafeAccess.unsafe.putObject(array, offsetObject1, v);
168        UnsafeAccess.unsafe.putObject(array, offsetObject2, v);
169        array[v] = null;
170        return s + (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject1) + (Integer) UnsafeAccess.unsafe.getObject(array, offsetObject2);
171    }
172
173    @Test
174    public void testUnsafe4() {
175        processMethod("testUnsafe4Snippet");
176        assertDeepEquals(3, graph.getNodes().filter(UnsafeLoadNode.class).count());
177    }
178
179    private static final long offsetLong1 = Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * 1;
180    private static final long offsetLong2 = Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE * 2;
181
182    public static int testUnsafe5Snippet(int v, long[] array) {
183        int s = UnsafeAccess.unsafe.getInt(array, offsetLong1);
184        UnsafeAccess.unsafe.putInt(array, offsetLong1, v);
185        UnsafeAccess.unsafe.putInt(array, offsetLong2, v);
186        return s + UnsafeAccess.unsafe.getInt(array, offsetLong1) + UnsafeAccess.unsafe.getInt(array, offsetLong2);
187    }
188
189    @Test
190    public void testUnsafe5() {
191        processMethod("testUnsafe5Snippet");
192        assertDeepEquals(1, graph.getNodes().filter(UnsafeLoadNode.class).count());
193    }
194
195    @Override
196    protected void processMethod(final String snippet) {
197        graph = parseEager(snippet, AllowAssumptions.NO);
198        HighTierContext context = getDefaultHighTierContext();
199        new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
200        new PartialEscapePhase(false, true, new CanonicalizerPhase(), null).apply(graph, context);
201    }
202}