001/* 002 * Copyright (c) 2013, 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.truffle.test; 024 025import com.oracle.graal.debug.*; 026import com.oracle.graal.debug.Debug.*; 027 028import org.junit.*; 029 030import com.oracle.graal.compiler.test.*; 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 033import com.oracle.graal.nodes.java.*; 034import com.oracle.graal.phases.common.*; 035import com.oracle.graal.phases.tiers.*; 036import com.oracle.graal.truffle.*; 037import com.oracle.truffle.api.*; 038import com.oracle.truffle.api.nodes.*; 039 040public class PartialEvaluationTest extends GraalCompilerTest { 041 private final TruffleCompiler truffleCompiler; 042 043 public PartialEvaluationTest() { 044 // Make sure Truffle runtime is initialized. 045 Assert.assertTrue(Truffle.getRuntime() != null); 046 this.truffleCompiler = DefaultTruffleCompiler.create(); 047 048 DebugEnvironment.initialize(System.out); 049 } 050 051 protected OptimizedCallTarget assertPartialEvalEquals(String methodName, RootNode root) { 052 return assertPartialEvalEquals(methodName, root, new Object[0]); 053 } 054 055 protected OptimizedCallTarget compileHelper(String methodName, RootNode root, Object[] arguments) { 056 final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root); 057 StructuredGraph actual = partialEval(compilable, arguments, AllowAssumptions.YES); 058 truffleCompiler.compileMethodHelper(actual, methodName, null, compilable); 059 return compilable; 060 } 061 062 protected OptimizedCallTarget assertPartialEvalEquals(String methodName, RootNode root, Object[] arguments) { 063 final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root); 064 StructuredGraph actual = partialEval(compilable, arguments, AllowAssumptions.YES); 065 truffleCompiler.compileMethodHelper(actual, methodName, null, compilable); 066 removeFrameStates(actual); 067 StructuredGraph expected = parseForComparison(methodName); 068 Assert.assertEquals(getCanonicalGraphString(expected, true, true), getCanonicalGraphString(actual, true, true)); 069 return compilable; 070 } 071 072 protected void assertPartialEvalNoInvokes(RootNode root) { 073 assertPartialEvalNoInvokes(root, new Object[0]); 074 } 075 076 protected void assertPartialEvalNoInvokes(RootNode root, Object[] arguments) { 077 final OptimizedCallTarget compilable = (OptimizedCallTarget) Truffle.getRuntime().createCallTarget(root); 078 StructuredGraph actual = partialEval(compilable, arguments, AllowAssumptions.YES); 079 removeFrameStates(actual); 080 for (MethodCallTargetNode node : actual.getNodes(MethodCallTargetNode.TYPE)) { 081 Assert.fail("Found invalid method call target node: " + node); 082 } 083 } 084 085 protected StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arguments, AllowAssumptions allowAssumptions) { 086 // Executed AST so that all classes are loaded and initialized. 087 compilable.call(arguments); 088 compilable.call(arguments); 089 compilable.call(arguments); 090 091 try (Scope s = Debug.scope("TruffleCompilation", new TruffleDebugJavaMethod(compilable))) { 092 return truffleCompiler.getPartialEvaluator().createGraph(compilable, allowAssumptions); 093 } catch (Throwable e) { 094 throw Debug.handle(e); 095 } 096 } 097 098 protected void removeFrameStates(StructuredGraph graph) { 099 for (FrameState frameState : graph.getNodes(FrameState.TYPE)) { 100 frameState.replaceAtUsages(null); 101 frameState.safeDelete(); 102 } 103 new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders())); 104 new DeadCodeEliminationPhase().apply(graph); 105 } 106 107 protected StructuredGraph parseForComparison(final String methodName) { 108 try (Scope s = Debug.scope("Truffle", new DebugDumpScope("Comparison: " + methodName))) { 109 StructuredGraph graph = parseEager(methodName, AllowAssumptions.YES); 110 compile(graph.method(), graph); 111 return graph; 112 } catch (Throwable e) { 113 throw Debug.handle(e); 114 } 115 } 116}