UnsafeReadEliminationTest.java revision 12651:6ef01bd40ce2
11590Srgrimes/* 2140392Srwatson * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 397377Sdes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41590Srgrimes * 597377Sdes * This code is free software; you can redistribute it and/or modify it 697377Sdes * under the terms of the GNU General Public License version 2 only, as 797377Sdes * published by the Free Software Foundation. 897377Sdes * 997377Sdes * This code is distributed in the hope that it will be useful, but WITHOUT 101590Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 111590Srgrimes * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 121590Srgrimes * version 2 for more details (a copy is included in the LICENSE file that 131590Srgrimes * accompanied this code). 141590Srgrimes * 151590Srgrimes * You should have received a copy of the GNU General Public License version 161590Srgrimes * 2 along with this work; if not, write to the Free Software Foundation, 171590Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18140392Srwatson * 19140392Srwatson * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20140392Srwatson * or visit www.oracle.com if you need additional information or have any 21140392Srwatson * questions. 22140392Srwatson */ 23140392Srwatsonpackage org.graalvm.compiler.core.test; 24140392Srwatson 25140392Srwatsonimport java.lang.reflect.Field; 26140392Srwatson 27140392Srwatsonimport org.junit.Assert; 28140392Srwatsonimport org.junit.Test; 29140392Srwatson 30140392Srwatsonimport org.graalvm.compiler.api.directives.GraalDirectives; 31140392Srwatsonimport org.graalvm.compiler.nodes.StructuredGraph; 32140392Srwatsonimport org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 33140392Srwatsonimport org.graalvm.compiler.nodes.extended.UnsafeAccessNode; 34140392Srwatsonimport org.graalvm.compiler.nodes.memory.ReadNode; 35140392Srwatsonimport org.graalvm.compiler.nodes.memory.WriteNode; 36140392Srwatsonimport org.graalvm.compiler.nodes.spi.LoweringTool; 37140392Srwatsonimport org.graalvm.compiler.phases.common.CanonicalizerPhase; 38140392Srwatsonimport org.graalvm.compiler.phases.common.LoweringPhase; 39140392Srwatsonimport org.graalvm.compiler.phases.tiers.PhaseContext; 40140392Srwatsonimport org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase; 41140392Srwatsonimport org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; 42140392Srwatson 431590Srgrimesimport sun.misc.Unsafe; 441590Srgrimes 451590Srgrimespublic class UnsafeReadEliminationTest extends GraalCompilerTest { 461590Srgrimes 471590Srgrimes public static final Unsafe UNSAFE; 481590Srgrimes static { 491590Srgrimes try { 501590Srgrimes Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); 511590Srgrimes theUnsafe.setAccessible(true); 521590Srgrimes UNSAFE = (Unsafe) theUnsafe.get(Unsafe.class); 531590Srgrimes } catch (Exception e) { 541590Srgrimes throw new RuntimeException("Exception while trying to get Unsafe", e); 551590Srgrimes } 561590Srgrimes } 571590Srgrimes 581590Srgrimes public static long[] Memory = new long[]{1, 2}; 591590Srgrimes public static double SideEffectD; 601590Srgrimes public static double SideEffectL; 6114440Smarkm 621590Srgrimes public static long test1Snippet(double a) { 631590Srgrimes final Object m = Memory; 641590Srgrimes if (a > 0) { 651590Srgrimes UNSAFE.putDouble(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, a); 66127848Scharnier } else { 671590Srgrimes SideEffectL = UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); 681590Srgrimes } 69127848Scharnier return UNSAFE.getLong(m, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); 7028099Scharnier } 711590Srgrimes 72127848Scharnier public static class A { 73127848Scharnier long[][] o; 74127848Scharnier long[][] p; 751590Srgrimes } 761590Srgrimes 771590Srgrimes public static Object test2Snippet(A a, int c) { 7877220Smarkm Object phi = null; 791590Srgrimes if (c != 0) { 80161815Scsjp long[][] r = a.o; 81161815Scsjp phi = r; 82161815Scsjp UNSAFE.putDouble(r, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, 12d); 83161815Scsjp } else { 84161815Scsjp long[][] r = a.p; 851590Srgrimes phi = r; 861590Srgrimes UNSAFE.putLong(r, (long) Unsafe.ARRAY_LONG_BASE_OFFSET, 123); 87200462Sdelphij } 8877220Smarkm GraalDirectives.controlFlowAnchor(); 891590Srgrimes SideEffectD = UNSAFE.getDouble(phi, (long) Unsafe.ARRAY_LONG_BASE_OFFSET); 901590Srgrimes return phi; 9177220Smarkm } 921590Srgrimes 931590Srgrimes @Test 941590Srgrimes public void test01() { 951590Srgrimes StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.NO); 961590Srgrimes testEarlyReadElimination(graph, 3, 2); 97161815Scsjp } 9821646Sdavidn 9974874Smarkm @Test 10091745Sdes public void test02() { 10174874Smarkm StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.NO); 102113262Sdes testPartialEscapeReadElimination(graph, 3, 2); 103113262Sdes } 104113262Sdes 105113262Sdes @Test 106113262Sdes public void test03() { 107113262Sdes StructuredGraph graph = parseEager("test2Snippet", AllowAssumptions.NO); 108113262Sdes testEarlyReadElimination(graph, 3, 3); 109113262Sdes } 110113262Sdes 111113262Sdes @Test 112113262Sdes public void test04() { 113113262Sdes StructuredGraph graph = parseEager("test2Snippet", AllowAssumptions.NO); 114113262Sdes testEarlyReadElimination(graph, 3, 3); 115113262Sdes } 116113262Sdes 117113262Sdes public void testEarlyReadElimination(StructuredGraph graph, int reads, int writes) { 118113262Sdes PhaseContext context = getDefaultHighTierContext(); 119113262Sdes CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); 12077220Smarkm canonicalizer.apply(graph, context); 12174874Smarkm new EarlyReadEliminationPhase(canonicalizer).apply(graph, context); 12274874Smarkm Assert.assertEquals(3, graph.getNodes().filter(UnsafeAccessNode.class).count()); 123113262Sdes // after lowering the same applies for reads and writes 124113262Sdes new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); 125113262Sdes canonicalizer.apply(graph, context); 126113262Sdes new EarlyReadEliminationPhase(canonicalizer).apply(graph, context); 127113262Sdes Assert.assertEquals(reads, graph.getNodes().filter(ReadNode.class).count()); 128113262Sdes Assert.assertEquals(writes, graph.getNodes().filter(WriteNode.class).count()); 129113262Sdes } 130113262Sdes 131130409Smarkm public void testPartialEscapeReadElimination(StructuredGraph graph, int reads, int writes) { 132113262Sdes PhaseContext context = getDefaultHighTierContext(); 13377220Smarkm CanonicalizerPhase canonicalizer = new CanonicalizerPhase(); 1343702Spst canonicalizer.apply(graph, context); 13577220Smarkm new PartialEscapePhase(true, true, canonicalizer, null).apply(graph, context); 1361590Srgrimes Assert.assertEquals(3, graph.getNodes().filter(UnsafeAccessNode.class).count()); 13777220Smarkm // after lowering the same applies for reads and writes 13877220Smarkm new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context); 13977220Smarkm canonicalizer.apply(graph, context); 14077220Smarkm new PartialEscapePhase(true, true, canonicalizer, null).apply(graph, context); 141130409Smarkm Assert.assertEquals(reads, graph.getNodes().filter(ReadNode.class).count()); 142130409Smarkm Assert.assertEquals(writes, graph.getNodes().filter(WriteNode.class).count()); 143130409Smarkm } 14477220Smarkm 14577220Smarkm} 14677220Smarkm