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 
  24 
  25 package org.graalvm.compiler.core.test.ea;
  26 
  27 import org.graalvm.compiler.core.test.GraalCompilerTest;
  28 import org.junit.Test;
  29 
  30 import sun.misc.Unsafe;
  31 
  32 import org.graalvm.compiler.nodes.StructuredGraph;
  33 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
  34 import org.graalvm.compiler.nodes.extended.RawLoadNode;
  35 import org.graalvm.compiler.nodes.java.LoadIndexedNode;
  36 import org.graalvm.compiler.nodes.java.StoreIndexedNode;
  37 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
  38 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
  39 import org.graalvm.compiler.phases.tiers.HighTierContext;
  40 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
  41 
  42 public class PEAReadEliminationTest extends GraalCompilerTest {
  43 
  44     public static int testIndexed1Snippet(int[] array) {
  45         array[1] = 1;
  46         array[2] = 2;
  47         array[3] = 3;
  48         array[4] = 4;
  49         array[5] = 5;
  50         array[6] = 6;
  51         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
  52     }
  53 
  54     @Test
  55     public void testIndexed1() {
  56         StructuredGraph graph = processMethod("testIndexed1Snippet");
  57         assertDeepEquals(0, graph.getNodes().filter(LoadIndexedNode.class).count());
  58     }
  59 
  60     public static int testIndexed2Snippet(int v, int[] array) {
  61         array[1] = 1;
  62         array[2] = 2;
  63         array[3] = 3;
  64         array[v] = 0;
  65         array[4] = 4;
  66         array[5] = 5;
  67         array[6] = 6;
  68         array[4] = 4;
  69         array[5] = 5;
  70         array[6] = 6;
  71         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
  72     }
  73 
  74     @Test
  75     public void testIndexed2() {
  76         StructuredGraph graph = processMethod("testIndexed2Snippet");
  77         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
  78         assertDeepEquals(7, graph.getNodes().filter(StoreIndexedNode.class).count());
  79     }
  80 
  81     public static int testIndexed3Snippet(int v, int[] array, short[] array2) {
  82         array[1] = 1;
  83         array2[1] = 1;
  84         array[2] = 2;
  85         array2[2] = 2;
  86         array[3] = 3;
  87         array2[3] = 3;
  88         array[v] = 0;
  89         array[4] = 4;
  90         array2[4] = 4;
  91         array[5] = 5;
  92         array2[5] = 5;
  93         array[6] = 6;
  94         array2[6] = 6;
  95         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];
  96     }
  97 
  98     @Test
  99     public void testIndexed3() {
 100         StructuredGraph graph = processMethod("testIndexed3Snippet");
 101         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
 102     }
 103 
 104     private static native void nonInlineable();
 105 
 106     public static int testIndexed4Snippet(int[] array) {
 107         array[1] = 1;
 108         array[2] = 2;
 109         array[3] = 3;
 110         nonInlineable();
 111         array[4] = 4;
 112         array[5] = 5;
 113         array[6] = 6;
 114         return array[1] + array[2] + array[3] + array[4] + array[5] + array[6];
 115     }
 116 
 117     @Test
 118     public void testIndexed4() {
 119         StructuredGraph graph = processMethod("testIndexed4Snippet");
 120         assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count());
 121     }
 122 
 123     private static final long offsetInt1 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 1;
 124     private static final long offsetInt2 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 2;
 125 
 126     public static int testUnsafe1Snippet(int v, int[] array) {
 127         int s = UNSAFE.getInt(array, offsetInt1);
 128         UNSAFE.putInt(array, offsetInt1, v);
 129         UNSAFE.putInt(array, offsetInt2, v);
 130         return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2);
 131     }
 132 
 133     @Test
 134     public void testUnsafe1() {
 135         StructuredGraph graph = processMethod("testUnsafe1Snippet");
 136         assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count());
 137     }
 138 
 139     public static int testUnsafe2Snippet(int v, Object array) {
 140         int s = UNSAFE.getInt(array, offsetInt1);
 141         UNSAFE.putInt(array, offsetInt1, v);
 142         UNSAFE.putInt(array, offsetInt2, v);
 143         return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2);
 144     }
 145 
 146     @Test
 147     public void testUnsafe2() {
 148         StructuredGraph graph = processMethod("testUnsafe2Snippet");
 149         assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count());
 150     }
 151 
 152     private static final long offsetObject1 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 1;
 153     private static final long offsetObject2 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 2;
 154 
 155     public static int testUnsafe3Snippet(int v, Object[] array) {
 156         int s = (Integer) UNSAFE.getObject(array, offsetObject1);
 157         UNSAFE.putObject(array, offsetObject1, v);
 158         UNSAFE.putObject(array, offsetObject2, v);
 159         return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2);
 160     }
 161 
 162     @Test
 163     public void testUnsafe3() {
 164         StructuredGraph graph = processMethod("testUnsafe3Snippet");
 165         assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count());
 166     }
 167 
 168     public static int testUnsafe4Snippet(int v, Object[] array) {
 169         int s = (Integer) UNSAFE.getObject(array, offsetObject1);
 170         UNSAFE.putObject(array, offsetObject1, v);
 171         UNSAFE.putObject(array, offsetObject2, v);
 172         array[v] = null;
 173         return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2);
 174     }
 175 
 176     @Test
 177     public void testUnsafe4() {
 178         StructuredGraph graph = processMethod("testUnsafe4Snippet");
 179         assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count());
 180     }
 181 
 182     protected StructuredGraph processMethod(final String snippet) {
 183         StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO);
 184         HighTierContext context = getDefaultHighTierContext();
 185         new InliningPhase(new CanonicalizerPhase()).apply(graph, context);
 186         new PartialEscapePhase(false, true, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context);
 187         return graph;
 188     }
 189 }