1 /*
   2  * Copyright (c) 2009, 2012, 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 package com.oracle.graal.compiler.hsail.test.infra;
  25 
  26 /**
  27  * This class extends KernelTester and provides a base class
  28  * for which the HSAIL code comes from the Graal compiler.
  29  */
  30 import static com.oracle.graal.compiler.common.GraalOptions.*;
  31 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
  32 import static org.junit.Assume.*;
  33 
  34 import java.io.*;
  35 import java.lang.reflect.*;
  36 
  37 import org.junit.*;
  38 
  39 import com.oracle.graal.api.code.*;
  40 import com.oracle.graal.api.meta.*;
  41 import com.oracle.graal.compiler.common.*;
  42 import com.oracle.graal.compiler.target.*;
  43 import com.oracle.graal.debug.*;
  44 import com.oracle.graal.gpu.*;
  45 import com.oracle.graal.hotspot.hsail.*;
  46 import com.oracle.graal.hotspot.meta.*;
  47 import com.oracle.graal.hsail.*;
  48 import com.oracle.graal.options.*;
  49 import com.oracle.graal.options.OptionValue.OverrideScope;
  50 
  51 public abstract class GraalKernelTester extends KernelTester {
  52 
  53     private static boolean substitutionsInstalled;
  54 
  55     private static synchronized void installSubstitutions() {
  56         if (!substitutionsInstalled) {
  57             getHSAILBackend().getProviders().getReplacements().registerSubstitutions(GraalKernelTester.class, ForceDeoptSubstitutions.class);
  58             substitutionsInstalled = true;
  59         }
  60     }
  61 
  62     public GraalKernelTester() {
  63         super(getHSAILBackend().isDeviceInitialized());
  64         installSubstitutions();
  65     }
  66 
  67     protected static HSAILHotSpotBackend getHSAILBackend() {
  68         Backend backend = runtime().getBackend(HSAIL.class);
  69         Assume.assumeTrue(backend instanceof HSAILHotSpotBackend);
  70         return (HSAILHotSpotBackend) backend;
  71     }
  72 
  73     ExternalCompilationResult hsailCode;
  74     private boolean showHsailSource = false;
  75     private boolean saveInFile = false;
  76 
  77     @Override
  78     public String getCompiledHSAILSource(Method method) {
  79         if (hsailCode == null) {
  80             HSAILHotSpotBackend backend = getHSAILBackend();
  81             ResolvedJavaMethod javaMethod = backend.getProviders().getMetaAccess().lookupJavaMethod(method);
  82             hsailCode = backend.compileKernel(javaMethod, false);
  83         }
  84         String hsailSource = hsailCode.getCodeString();
  85         if (showHsailSource) {
  86             logger.severe(hsailSource);
  87         }
  88         if (saveInFile) {
  89             try {
  90                 File fout = File.createTempFile("tmp", ".hsail");
  91                 logger.fine("creating " + fout.getCanonicalPath());
  92                 FileWriter fw = new FileWriter(fout);
  93                 BufferedWriter bw = new BufferedWriter(fw);
  94                 bw.write(hsailSource);
  95                 bw.close();
  96             } catch (Exception e) {
  97                 e.printStackTrace();
  98             }
  99         }
 100         return hsailSource;
 101     }
 102 
 103     public boolean aggressiveInliningEnabled() {
 104         return (InlineEverything.getValue());
 105     }
 106 
 107     public boolean canHandleHSAILMethodCalls() {
 108         // needs 2 things, backend needs to be able to generate such calls, and target needs to be
 109         // able to run them
 110         boolean canGenerateCalls = false;   // not implemented yet
 111         boolean canExecuteCalls = runningOnSimulator();
 112         return (canGenerateCalls && canExecuteCalls);
 113     }
 114 
 115     private static boolean supportsObjectAllocation() {
 116         return true;
 117     }
 118 
 119     /**
 120      * Determines if the runtime supports object allocation in HSAIL code.
 121      */
 122     public boolean canHandleObjectAllocation() {
 123         return supportsObjectAllocation() && canDeoptimize();
 124     }
 125 
 126     /**
 127      * Determines if the runtime supports deoptimization in HSAIL code.
 128      */
 129     public boolean canDeoptimize() {
 130         return getHSAILBackend().getRuntime().getConfig().useHSAILDeoptimization;
 131     }
 132 
 133     /**
 134      * Determines if we are running CQE tests (via a -D flag)
 135      */
 136     public boolean runningCQETests() {
 137         return Boolean.getBoolean("com.amd.CQE");
 138     }
 139 
 140     /**
 141      * Determines if the JVM supports the required typeProfileWidth.
 142      */
 143     public boolean typeProfileWidthAtLeast(int val) {
 144         return (getHSAILBackend().getRuntime().getConfig().typeProfileWidth >= val);
 145     }
 146 
 147     /**
 148      * Determines if the runtime supports {@link VirtualObject}s in {@link DebugInfo} associated
 149      * with HSAIL code.
 150      */
 151     public boolean canHandleDeoptVirtualObjects() {
 152         return true;
 153     }
 154 
 155     /**
 156      * Determines if the runtime has the capabilities required by this test.
 157      */
 158     protected boolean supportsRequiredCapabilities() {
 159         return true;
 160     }
 161 
 162     HotSpotNmethod installedCode;
 163 
 164     @Override
 165     protected void dispatchKernelOkra(int range, Object... args) {
 166         HSAILHotSpotBackend backend = getHSAILBackend();
 167         if (backend.isDeviceInitialized()) {
 168             try {
 169                 if (installedCode == null) {
 170                     installedCode = backend.compileAndInstallKernel(testMethod);
 171                 }
 172                 backend.executeKernel(installedCode, range, args);
 173             } catch (InvalidInstalledCodeException e) {
 174                 Debug.log("WARNING:Invalid installed code: " + e);
 175                 e.printStackTrace();
 176             }
 177         } else {
 178             super.dispatchKernelOkra(range, args);
 179         }
 180     }
 181 
 182     public static OptionValue<?> getOptionFromField(Class<?> declaringClass, String fieldName) {
 183         try {
 184             Field f = declaringClass.getDeclaredField(fieldName);
 185             f.setAccessible(true);
 186             return (OptionValue<?>) f.get(null);
 187         } catch (Exception e) {
 188             throw new GraalInternalError(e);
 189         }
 190     }
 191 
 192     private OptionValue<?> accessibleRemoveNeverExecutedCode = getOptionFromField(GraalOptions.class, "RemoveNeverExecutedCode");
 193 
 194     // Special overrides for the testGeneratedxxx routines which set
 195     // required graal options that we need to run any junit test
 196 
 197     private OverrideScope getOverrideScope() {
 198         return OptionValue.override(GraalOptions.InlineEverything, true, accessibleRemoveNeverExecutedCode, false);
 199     }
 200 
 201     @Override
 202     public void testGeneratedHsail() {
 203         try (OverrideScope s = getOverrideScope()) {
 204             assumeTrue(supportsRequiredCapabilities() && okraEnvIsInitialized());
 205             super.testGeneratedHsail();
 206         }
 207     }
 208 
 209     @Override
 210     public void testGeneratedHsailUsingLambdaMethod() {
 211         try (OverrideScope s = getOverrideScope()) {
 212             assumeTrue(supportsRequiredCapabilities() && okraEnvIsInitialized());
 213             super.testGeneratedHsailUsingLambdaMethod();
 214         }
 215     }
 216 
 217     // used for forcing a deoptimization
 218     public static int forceDeopt(int x) {
 219         return x * x;
 220     }
 221 
 222     public static double forceDeopt(double x) {
 223         return x * x;
 224     }
 225 
 226 }