1 /*
   2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.core.test.ea;
  24 
  25 import org.graalvm.compiler.core.test.GraalCompilerTest;
  26 import org.junit.Test;
  27 
  28 import sun.misc.Unsafe;
  29 
  30 import org.graalvm.compiler.nodes.StructuredGraph;
  31 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  32 import org.graalvm.compiler.nodes.extended.RawLoadNode;
  33 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
  34 import org.graalvm.compiler.nodes.java.StoreIndexedNode;
  35 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
  36 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
  37 import org.graalvm.compiler.phases.tiers.HighTierContext;
  38 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
  39 
  40 public class PEAReadEliminationTest extends GraalCompilerTest {
  41 
  42     public static int testIndexed1Snippet(int[] array) {
  43         array[1] = 1;
  44         array[2] = 2;
  45         array[3] = 3;
  46         array[4] = 4;
  47         array[5] = 5;
  48         array[6] = 6;
  49         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
  50     }
  51 
  52     @Test
  53     public void testIndexed1() {
  54         StructuredGraph graph = processMethod("testIndexed1Snippet");
  55         assertDeepEquals(0, graph.getNodes().filter(LoadIndexedNode.class).count());
  56     }
  57 
  58     public static int testIndexed2Snippet(int v, int[] array) {
  59         array[1] = 1;
  60         array[2] = 2;
  61         array[3] = 3;
  62         array[v] = 0;
  63         array[4] = 4;
  64         array[5] = 5;
  65         array[6] = 6;
  66         array[4] = 4;
  67         array[5] = 5;
  68         array[6] = 6;
  69         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
  70     }
  71 
  72     @Test
  73     public void testIndexed2() {
  74         StructuredGraph graph = processMethod("testIndexed2Snippet");
  75         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
  76         assertDeepEquals(7, graph.getNodes().filter(StoreIndexedNode.class).count());
  77     }
  78 
  79     public static int testIndexed3Snippet(int v, int[] array, short[] array2) {
  80         array[1] = 1;
  81         array2[1] = 1;
  82         array[2] = 2;
  83         array2[2] = 2;
  84         array[3] = 3;
  85         array2[3] = 3;
  86         array[v] = 0;
  87         array[4] = 4;
  88         array2[4] = 4;
  89         array[5] = 5;
  90         array2[5] = 5;
  91         array[6] = 6;
  92         array2[6] = 6;
  93         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];
  94     }
  95 
  96     @Test
  97     public void testIndexed3() {
  98         StructuredGraph graph = processMethod("testIndexed3Snippet");
  99         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
 100     }
 101 
 102     private static native void nonInlineable();
 103 
 104     public static int testIndexed4Snippet(int[] array) {
 105         array[1] = 1;
 106         array[2] = 2;
 107         array[3] = 3;
 108         nonInlineable();
 109         array[4] = 4;
 110         array[5] = 5;
 111         array[6] = 6;
 112         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
 113     }
 114 
 115     @Test
 116     public void testIndexed4() {
 117         StructuredGraph graph = processMethod("testIndexed4Snippet");
 118         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
 119     }
 120 
 121     private static final long offsetInt1 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 1;
 122     private static final long offsetInt2 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 2;
 123 
 124     public static int testUnsafe1Snippet(int v, int[] array) {
 125         int s = UNSAFE.getInt(array, offsetInt1);
 126         UNSAFE.putInt(array, offsetInt1, v);
 127         UNSAFE.putInt(array, offsetInt2, v);
 128         return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2);
 129     }
 130 
 131     @Test
 132     public void testUnsafe1() {
 133         StructuredGraph graph = processMethod("testUnsafe1Snippet");
 134         assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count());
 135     }
 136 
 137     public static int testUnsafe2Snippet(int v, Object array) {
 138         int s = UNSAFE.getInt(array, offsetInt1);
 139         UNSAFE.putInt(array, offsetInt1, v);
 140         UNSAFE.putInt(array, offsetInt2, v);
 141         return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2);
 142     }
 143 
 144     @Test
 145     public void testUnsafe2() {
 146         StructuredGraph graph = processMethod("testUnsafe2Snippet");
 147         assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count());
 148     }
 149 
 150     private static final long offsetObject1 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 1;
 151     private static final long offsetObject2 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 2;
 152 
 153     public static int testUnsafe3Snippet(int v, Object[] array) {
 154         int s = (Integer) UNSAFE.getObject(array, offsetObject1);
 155         UNSAFE.putObject(array, offsetObject1, v);
 156         UNSAFE.putObject(array, offsetObject2, v);
 157         return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2);
 158     }
 159 
 160     @Test
 161     public void testUnsafe3() {
 162         StructuredGraph graph = processMethod("testUnsafe3Snippet");
 163         assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count());
 164     }
 165 
 166     public static int testUnsafe4Snippet(int v, Object[] array) {
 167         int s = (Integer) UNSAFE.getObject(array, offsetObject1);
 168         UNSAFE.putObject(array, offsetObject1, v);
 169         UNSAFE.putObject(array, offsetObject2, v);
 170         array[v] = null;
 171         return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2);
 172     }
 173 
 174     @Test
 175     public void testUnsafe4() {
 176         StructuredGraph graph = processMethod("testUnsafe4Snippet");
 177         assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count());
 178     }
 179 
 180     protected StructuredGraph processMethod(final String snippet) {
 181         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
 182         HighTierContext context = getDefaultHighTierContext();
 183         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
 184         new PartialEscapePhase(false, true, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
 185         return graph;
 186     }
 187 }