blob: 35bb668684577651f884c93675eb84529d891a67 [file] [log] [blame]
/*
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.api.directives;
import java.nio.charset.Charset;
// JaCoCo Exclude
/**
* Directives that influence the compilation of methods by Graal. They don't influence the semantics
* of the code, but they are useful for unit testing and benchmarking.
*/
public final class GraalDirectives {
public static final double LIKELY_PROBABILITY = 0.75;
public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY;
public static final double SLOWPATH_PROBABILITY = 0.0001;
public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY;
/**
* Directive for the compiler to fall back to the bytecode interpreter at this point.
*/
public static void deoptimize() {
}
/**
* Directive for the compiler to fall back to the bytecode interpreter at this point, invalidate
* the compiled code and reprofile the method.
*/
public static void deoptimizeAndInvalidate() {
}
/**
* Returns a boolean value indicating whether the method is executed in Graal-compiled code.
*/
public static boolean inCompiledCode() {
return false;
}
/**
* A call to this method will never be duplicated by control flow optimizations in the compiler.
*/
public static void controlFlowAnchor() {
}
/**
* Injects a probability for the given condition into the profiling information of a branch
* instruction. The probability must be a value between 0.0 and 1.0 (inclusive).
*
* Example usage (it specifies that the likelihood for a to be greater than b is 90%):
*
* <code>
* if (injectBranchProbability(0.9, a &gt; b)) {
* // ...
* }
* </code>
*
* There are predefined constants for commonly used probabilities (see
* {@link #LIKELY_PROBABILITY} , {@link #UNLIKELY_PROBABILITY}, {@link #SLOWPATH_PROBABILITY},
* {@link #FASTPATH_PROBABILITY} ).
*
* @param probability the probability value between 0.0 and 1.0 that should be injected
*/
public static boolean injectBranchProbability(double probability, boolean condition) {
assert probability >= 0.0 && probability <= 1.0;
return condition;
}
/**
* Injects an average iteration count of a loop into the probability information of a loop exit
* condition. The iteration count specifies how often the condition is checked, i.e. in for and
* while loops it is one more than the body iteration count, and in do-while loops it is equal
* to the body iteration count. The iteration count must be >= 1.0.
*
* Example usage (it specifies that the expected iteration count of the loop condition is 500,
* so the iteration count of the loop body is 499):
*
* <code>
* for (int i = 0; injectIterationCount(500, i < array.length); i++) {
* // ...
* }
* </code>
*
* @param iterations the expected number of iterations that should be injected
*/
public static boolean injectIterationCount(double iterations, boolean condition) {
return injectBranchProbability(1. - 1. / iterations, condition);
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(boolean value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(byte value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(short value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(char value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(int value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(long value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(float value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(double value) {
}
/**
* Consume a value, making sure the compiler doesn't optimize away the computation of this
* value, even if it is otherwise unused.
*/
@SuppressWarnings("unused")
public static void blackhole(Object value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(boolean value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(byte value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(short value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(char value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(int value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(long value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(float value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(double value) {
}
/**
* Forces a value to be kept in a register.
*/
@SuppressWarnings("unused")
public static void bindToRegister(Object value) {
}
/**
* Spills all caller saved registers.
*/
public static void spillRegisters() {
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static boolean opaque(boolean value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static byte opaque(byte value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static short opaque(short value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static char opaque(char value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static int opaque(int value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static long opaque(long value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static float opaque(float value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static double opaque(double value) {
return value;
}
/**
* Do nothing, but also make sure the compiler doesn't do any optimizations across this call.
*
* For example, the compiler will constant fold the expression 5 * 3, but the expression 5 *
* opaque(3) will result in a real multiplication, because the compiler will not see that
* opaque(3) is a constant.
*/
public static <T> T opaque(T value) {
return value;
}
public static <T> T guardingNonNull(T value) {
if (value == null) {
deoptimize();
}
return value;
}
/**
* Ensures that the given object will be virtual (escape analyzed) at all points that are
* dominated by the current position.
*/
public static void ensureVirtualized(@SuppressWarnings("unused") Object object) {
}
/**
* Ensures that the given object will be virtual at the current position.
*/
public static void ensureVirtualizedHere(@SuppressWarnings("unused") Object object) {
}
/**
* Marks the beginning of an instrumentation boundary. The instrumentation code will be folded
* during compilation and will not affect inlining heuristics regarding graph size except one on
* compiled low-level graph size (e.g., {@code GraalOptions.SmallCompiledLowLevelGraphSize}).
*/
public static void instrumentationBegin() {
}
/**
* Marks the beginning of an instrumentation boundary and associates the instrumentation with
* the preceding bytecode. If the instrumented instruction is {@code new}, then instrumentation
* will adapt to optimizations concerning allocation, and only be executed if allocation really
* happens.
*
* Example (the instrumentation is associated with {@code new}):
*
* <blockquote>
*
* <pre>
* 0 new java.lang.Object
* 3 invokestatic org.graalvm.compiler.api.directives.GraalDirectives.instrumentationBeginForPredecessor() : void
* 6 invokestatic AllocationProfiler.countActualAllocation() : void
* 9 invokestatic org.graalvm.compiler.api.directives.GraalDirectives.instrumentationEnd() : void
* 12 invokespecial java.lang.Object()
* </pre>
*
* </blockquote>
*
* @see #instrumentationBegin()
*/
public static void instrumentationBeginForPredecessor() {
}
/**
* Marks the end of the instrumentation boundary.
*
* @see #instrumentationBegin()
*/
public static void instrumentationEnd() {
}
/**
* @return true if the enclosing method is inlined.
*/
public static boolean isMethodInlined() {
return false;
}
private static final Charset UTF8 = Charset.forName("UTF-8");
/**
* @return the name of the root method for the current compilation task. If the enclosing method
* is inlined, it returns the name of the method into which it is inlined.
*/
public static String rootName() {
return new String(rawRootName(), UTF8);
}
public static byte[] rawRootName() {
return new byte[0];
}
}