use of org.graalvm.compiler.phases.OptimisticOptimizations in project graal by oracle.
the class HotSpotGraalCompiler method compileHelper.
public CompilationResult compileHelper(CompilationResultBuilderFactory crbf, CompilationResult result, StructuredGraph graph, ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo, OptionValues options) {
HotSpotBackend backend = graalRuntime.getHostBackend();
HotSpotProviders providers = backend.getProviders();
final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
Suites suites = getSuites(providers, options);
LIRSuites lirSuites = getLIRSuites(providers, options);
ProfilingInfo profilingInfo = useProfilingInfo ? method.getProfilingInfo(!isOSR, isOSR) : DefaultProfilingInfo.get(TriState.FALSE);
OptimisticOptimizations optimisticOpts = getOptimisticOpts(profilingInfo, options);
/*
* Cut off never executed code profiles if there is code, e.g. after the osr loop, that is
* never executed.
*/
if (isOSR && !OnStackReplacementPhase.Options.DeoptAfterOSR.getValue(options)) {
optimisticOpts.remove(Optimization.RemoveNeverExecutedCode);
}
result.setEntryBCI(entryBCI);
boolean shouldDebugNonSafepoints = providers.getCodeCache().shouldDebugNonSafepoints();
PhaseSuite<HighTierContext> graphBuilderSuite = configGraphBuilderSuite(providers.getSuites().getDefaultGraphBuilderSuite(), shouldDebugNonSafepoints, isOSR);
GraalCompiler.compileGraph(graph, method, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, result, crbf);
if (!isOSR && useProfilingInfo) {
ProfilingInfo profile = profilingInfo;
profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount());
}
return result;
}
use of org.graalvm.compiler.phases.OptimisticOptimizations in project graal by oracle.
the class SubstrateGraalUtils method compileGraph.
@SuppressWarnings("try")
public static CompilationResult compileGraph(RuntimeConfiguration runtimeConfig, Suites suites, LIRSuites lirSuites, final SharedMethod method, final StructuredGraph graph) {
assert runtimeConfig != null : "no runtime";
if (Options.ForceDumpGraphsBeforeCompilation.getValue()) {
/*
* forceDump is often used during debugging, and we want to make sure that it keeps
* working, i.e., does not lead to image generation problems when adding a call to it.
* This code ensures that forceDump is seen as reachable for all images that include
* Graal, because it is conditional on a runtime option.
*/
graph.getDebug().forceDump(graph, "Force dump before compilation");
}
String methodName = method.format("%h.%n");
try (DebugContext debug = graph.getDebug();
Indent indent = debug.logAndIndent("compile graph %s for method %s", graph, methodName)) {
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL.remove(OptimisticOptimizations.Optimization.UseLoopLimitChecks);
final Backend backend = runtimeConfig.lookupBackend(method);
try (Indent indent2 = debug.logAndIndent("do compilation")) {
SubstrateCompilationResult result = new SubstrateCompilationResult(graph.compilationId(), method.format("%H.%n(%p)"));
GraalCompiler.compileGraph(graph, method, backend.getProviders(), backend, null, optimisticOpts, null, suites, lirSuites, result, CompilationResultBuilderFactory.Default);
return result;
}
}
}
use of org.graalvm.compiler.phases.OptimisticOptimizations in project graal by oracle.
the class UnbalancedMonitorsTest method checkForBailout.
private void checkForBailout(String name) throws ClassNotFoundException {
ResolvedJavaMethod method = getResolvedJavaMethod(LOADER.findClass(INNER_CLASS_NAME), name);
try {
OptionValues options = getInitialOptions();
StructuredGraph graph = new StructuredGraph.Builder(options, getDebugContext(options, null, method)).method(method).build();
Plugins plugins = new Plugins(new InvocationPlugins());
GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getDefault(plugins).withEagerResolving(true).withUnresolvedIsError(true);
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.NONE;
GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(getMetaAccess(), getProviders().getStampProvider(), null, null, graphBuilderConfig, optimisticOpts, null);
graphBuilder.apply(graph);
} catch (BailoutException e) {
if (e.getMessage().contains("unbalanced monitors")) {
return;
}
throw e;
}
assertTrue("should have bailed out", false);
}
use of org.graalvm.compiler.phases.OptimisticOptimizations in project graal by oracle.
the class InvokeGraal method compileAndInstallMethod.
/**
* The simplest way to compile a method, using the default behavior for everything.
*/
@SuppressWarnings("try")
protected InstalledCode compileAndInstallMethod(ResolvedJavaMethod method) {
/* Create a unique compilation identifier, visible in IGV. */
CompilationIdentifier compilationId = backend.getCompilationIdentifier(method);
OptionValues options = getInitialOptions();
DebugContext debug = DebugContext.create(options, DebugHandlersFactory.LOADER);
try (DebugContext.Scope s = debug.scope("compileAndInstallMethod", new DebugDumpScope(String.valueOf(compilationId), true))) {
/*
* The graph that is compiled. We leave it empty (no nodes added yet). This means that
* it will be filled according to the graphBuilderSuite defined below. We also specify
* that we want the compilation to make optimistic assumptions about runtime state such
* as the loaded class hierarchy.
*/
StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).method(method).compilationId(compilationId).build();
/*
* The phases used to build the graph. Usually this is just the GraphBuilderPhase. If
* the graph already contains nodes, it is ignored.
*/
PhaseSuite<HighTierContext> graphBuilderSuite = backend.getSuites().getDefaultGraphBuilderSuite();
/*
* The optimization phases that are applied to the graph. This is the main configuration
* point for Graal. Add or remove phases to customize your compilation.
*/
Suites suites = backend.getSuites().getDefaultSuites(options);
/*
* The low-level phases that are applied to the low-level representation.
*/
LIRSuites lirSuites = backend.getSuites().getDefaultLIRSuites(options);
/*
* We want Graal to perform all speculative optimistic optimizations, using the
* profiling information that comes with the method (collected by the interpreter) for
* speculation.
*/
OptimisticOptimizations optimisticOpts = OptimisticOptimizations.ALL;
ProfilingInfo profilingInfo = graph.getProfilingInfo(method);
/* The default class and configuration for compilation results. */
CompilationResult compilationResult = new CompilationResult(graph.compilationId());
CompilationResultBuilderFactory factory = CompilationResultBuilderFactory.Default;
/* Invoke the whole Graal compilation pipeline. */
GraalCompiler.compileGraph(graph, method, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, compilationResult, factory);
/*
* Install the compilation result into the VM, i.e., copy the byte[] array that contains
* the machine code into an actual executable memory location.
*/
return backend.addInstalledCode(debug, method, asCompilationRequest(compilationId), compilationResult);
} catch (Throwable ex) {
throw debug.handle(ex);
}
}
use of org.graalvm.compiler.phases.OptimisticOptimizations in project graal by oracle.
the class InliningData method getTypeCheckedInlineInfo.
private InlineInfo getTypeCheckedInlineInfo(Invoke invoke, ResolvedJavaMethod targetMethod) {
JavaTypeProfile typeProfile = ((MethodCallTargetNode) invoke.callTarget()).getProfile();
if (typeProfile == null) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no type profile exists");
return null;
}
JavaTypeProfile.ProfiledType[] ptypes = typeProfile.getTypes();
if (ptypes == null || ptypes.length <= 0) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types in profile");
return null;
}
ResolvedJavaType contextType = invoke.getContextType();
double notRecordedTypeProbability = typeProfile.getNotRecordedProbability();
final OptimisticOptimizations optimisticOpts = context.getOptimisticOptimizations();
OptionValues options = invoke.asNode().getOptions();
if (ptypes.length == 1 && notRecordedTypeProbability == 0) {
if (!optimisticOpts.inlineMonomorphicCalls(options)) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining monomorphic calls is disabled");
return null;
}
ResolvedJavaType type = ptypes[0].getType();
assert type.isArray() || type.isConcrete();
ResolvedJavaMethod concrete = type.resolveConcreteMethod(targetMethod, contextType);
if (!checkTargetConditions(invoke, concrete)) {
return null;
}
return new TypeGuardInlineInfo(invoke, concrete, type);
} else {
invoke.setPolymorphic(true);
if (!optimisticOpts.inlinePolymorphicCalls(options) && notRecordedTypeProbability == 0) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining polymorphic calls is disabled (%d types)", ptypes.length);
return null;
}
if (!optimisticOpts.inlineMegamorphicCalls(options) && notRecordedTypeProbability > 0) {
// due to filtering impossible types, notRecordedTypeProbability can be > 0 although
// the number of types is lower than what can be recorded in a type profile
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "inlining megamorphic calls is disabled (%d types, %f %% not recorded types)", ptypes.length, notRecordedTypeProbability * 100);
return null;
}
// Find unique methods and their probabilities.
ArrayList<ResolvedJavaMethod> concreteMethods = new ArrayList<>();
ArrayList<Double> concreteMethodsProbabilities = new ArrayList<>();
for (int i = 0; i < ptypes.length; i++) {
ResolvedJavaMethod concrete = ptypes[i].getType().resolveConcreteMethod(targetMethod, contextType);
if (concrete == null) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "could not resolve method");
return null;
}
int index = concreteMethods.indexOf(concrete);
double curProbability = ptypes[i].getProbability();
if (index < 0) {
index = concreteMethods.size();
concreteMethods.add(concrete);
concreteMethodsProbabilities.add(curProbability);
} else {
concreteMethodsProbabilities.set(index, concreteMethodsProbabilities.get(index) + curProbability);
}
}
// Clear methods that fall below the threshold.
if (notRecordedTypeProbability > 0) {
ArrayList<ResolvedJavaMethod> newConcreteMethods = new ArrayList<>();
ArrayList<Double> newConcreteMethodsProbabilities = new ArrayList<>();
for (int i = 0; i < concreteMethods.size(); ++i) {
if (concreteMethodsProbabilities.get(i) >= MegamorphicInliningMinMethodProbability.getValue(options)) {
newConcreteMethods.add(concreteMethods.get(i));
newConcreteMethodsProbabilities.add(concreteMethodsProbabilities.get(i));
}
}
if (newConcreteMethods.isEmpty()) {
// No method left that is worth inlining.
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no methods remaining after filtering less frequent methods (%d methods previously)", concreteMethods.size());
return null;
}
concreteMethods = newConcreteMethods;
concreteMethodsProbabilities = newConcreteMethodsProbabilities;
}
if (concreteMethods.size() > maxMethodPerInlining) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "polymorphic call with more than %d target methods", maxMethodPerInlining);
return null;
}
// Clean out types whose methods are no longer available.
ArrayList<JavaTypeProfile.ProfiledType> usedTypes = new ArrayList<>();
ArrayList<Integer> typesToConcretes = new ArrayList<>();
for (JavaTypeProfile.ProfiledType type : ptypes) {
ResolvedJavaMethod concrete = type.getType().resolveConcreteMethod(targetMethod, contextType);
int index = concreteMethods.indexOf(concrete);
if (index == -1) {
notRecordedTypeProbability += type.getProbability();
} else {
assert type.getType().isArray() || !type.getType().isAbstract() : type + " " + concrete;
usedTypes.add(type);
typesToConcretes.add(index);
}
}
if (usedTypes.isEmpty()) {
// No type left that is worth checking for.
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "no types remaining after filtering less frequent types (%d types previously)", ptypes.length);
return null;
}
for (ResolvedJavaMethod concrete : concreteMethods) {
if (!checkTargetConditions(invoke, concrete)) {
InliningUtil.traceNotInlinedMethod(invoke, inliningDepth(), targetMethod, "it is a polymorphic method call and at least one invoked method cannot be inlined");
return null;
}
}
return new MultiTypeGuardInlineInfo(invoke, concreteMethods, usedTypes, typesToConcretes, notRecordedTypeProbability);
}
}
Aggregations