1 /* 2 * Copyright (c) 2015, 2016, 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.replacements.test; 24 25 import static org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin.InlineInfo.createStandardInlineInfo; 26 27 import org.graalvm.compiler.core.common.type.StampFactory; 28 import org.graalvm.compiler.core.test.GraalCompilerTest; 29 import org.graalvm.compiler.debug.DebugContext; 30 import org.graalvm.compiler.nodes.AbstractBeginNode; 31 import org.graalvm.compiler.nodes.StructuredGraph; 32 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 33 import org.graalvm.compiler.nodes.ValueNode; 34 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration; 35 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; 36 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin; 37 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; 38 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; 39 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; 40 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; 41 import org.graalvm.compiler.nodes.memory.ReadNode; 42 import org.graalvm.compiler.nodes.memory.address.AddressNode; 43 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; 44 import org.graalvm.compiler.phases.OptimisticOptimizations; 45 import org.graalvm.compiler.phases.common.CanonicalizerPhase; 46 import org.graalvm.compiler.phases.tiers.PhaseContext; 47 import org.graalvm.compiler.replacements.CachingPEGraphDecoder; 48 import org.graalvm.word.LocationIdentity; 49 import org.junit.Test; 50 51 import jdk.vm.ci.meta.JavaKind; 52 import jdk.vm.ci.meta.ResolvedJavaMethod; 53 54 public class PEGraphDecoderTest extends GraalCompilerTest { 55 56 /** 57 * This method is intrinsified to a node with a guard dependency on the block it is in. The 58 * various tests ensure that this guard is correctly updated when blocks are merged during 59 * inlining. 60 */ 61 private static native int readInt(Object obj, long offset); 62 63 private static boolean flag; 64 private static int value; 65 66 private static void invokeSimple() { 67 value = 111; 68 } 69 70 private static void invokeComplicated() { 71 if (flag) { 72 value = 0; 73 } else { 74 value = 42; 75 } 76 } 77 78 private static int readInt1(Object obj) { 79 return readInt(obj, 16); 80 } 81 82 private static int readInt2(Object obj) { 83 invokeSimple(); 84 return readInt(obj, 16); 85 } 86 87 private static int readInt3(Object obj) { 88 invokeComplicated(); 89 return readInt(obj, 16); 90 } 91 92 private static int readInt4(Object obj, int n) { 93 if (n > 0) { 94 invokeComplicated(); 95 } 96 return readInt(obj, 16); 97 } 98 99 public static int doTest(Object obj) { 100 int result = 0; 101 result += readInt1(obj); 102 result += readInt2(obj); 103 result += readInt3(obj); 104 result += readInt4(obj, 2); 105 return result; 106 } 107 108 private static void registerPlugins(InvocationPlugins plugins) { 109 Registration r = new Registration(plugins, PEGraphDecoderTest.class); 110 r.register2("readInt", Object.class, long.class, new InvocationPlugin() { 111 @Override 112 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode obj, ValueNode offset) { 113 AddressNode address = b.add(new OffsetAddressNode(obj, offset)); 114 ReadNode read = b.addPush(JavaKind.Int, new ReadNode(address, LocationIdentity.any(), StampFactory.forKind(JavaKind.Int), BarrierType.NONE)); 115 read.setGuard(AbstractBeginNode.prevBegin(read)); 116 return true; 117 } 118 }); 119 } 120 121 class InlineAll implements InlineInvokePlugin { 122 @Override 123 public InlineInfo shouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) { 124 return createStandardInlineInfo(method); 125 } 126 } 127 128 @Test 129 @SuppressWarnings("try") 130 public void test() { 131 ResolvedJavaMethod testMethod = getResolvedJavaMethod(PEGraphDecoderTest.class, "doTest", Object.class); 132 StructuredGraph targetGraph = null; 133 DebugContext debug = getDebugContext(); 134 try (DebugContext.Scope scope = debug.scope("GraphPETest", testMethod)) { 135 GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(getDefaultGraphBuilderPlugins()).withEagerResolving(true).withUnresolvedIsError(true); 136 registerPlugins(graphBuilderConfig.getPlugins().getInvocationPlugins()); 137 targetGraph = new StructuredGraph.Builder(getInitialOptions(), debug, AllowAssumptions.YES).method(testMethod).build(); 138 CachingPEGraphDecoder decoder = new CachingPEGraphDecoder(getTarget().arch, targetGraph, getProviders(), graphBuilderConfig, OptimisticOptimizations.NONE, AllowAssumptions.YES, 139 null, null, new InlineInvokePlugin[]{new InlineAll()}, null, null, null); 140 141 decoder.decode(testMethod); 142 debug.dump(DebugContext.BASIC_LEVEL, targetGraph, "Target Graph"); 143 targetGraph.verify(); 144 145 PhaseContext context = new PhaseContext(getProviders()); 146 new CanonicalizerPhase().apply(targetGraph, context); 147 targetGraph.verify(); 148 149 } catch (Throwable ex) { 150 if (targetGraph != null) { 151 debug.dump(DebugContext.BASIC_LEVEL, targetGraph, ex.toString()); 152 } 153 debug.handle(ex); 154 } 155 } 156 }