use of org.graalvm.compiler.phases.common.inlining.info.InlineInfo in project graal by oracle.
the class AOTInliningPolicy method isWorthInlining.
@Override
public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
final InlineInfo info = invocation.callee();
for (int i = 0; i < info.numberOfMethods(); ++i) {
HotSpotResolvedObjectType t = (HotSpotResolvedObjectType) info.methodAt(i).getDeclaringClass();
if (t.getFingerprint() == 0) {
return false;
}
}
final double probability = invocation.probability();
final double relevance = invocation.relevance();
OptionValues options = info.graph().getOptions();
if (InlineEverything.getValue(options)) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
return true;
}
if (isIntrinsic(replacements, info)) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
return true;
}
if (info.shouldInline()) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
return true;
}
double inliningBonus = getInliningBonus(info);
int nodes = info.determineNodeCount();
if (nodes < TrivialInliningSize.getValue(options) * inliningBonus) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
return true;
}
double maximumNodes = computeMaximumSize(relevance, (int) (maxInliningSize(inliningDepth, options) * inliningBonus));
if (nodes <= maximumNodes) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
return true;
}
InliningUtil.traceNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
return false;
}
use of org.graalvm.compiler.phases.common.inlining.info.InlineInfo in project graal by oracle.
the class GreedyInliningPolicy method isWorthInlining.
@Override
public boolean isWorthInlining(Replacements replacements, MethodInvocation invocation, int inliningDepth, boolean fullyProcessed) {
final InlineInfo info = invocation.callee();
OptionValues options = info.graph().getOptions();
final double probability = invocation.probability();
final double relevance = invocation.relevance();
if (InlineEverything.getValue(options)) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything");
return true;
}
if (isIntrinsic(replacements, info)) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic");
return true;
}
if (info.shouldInline()) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "forced inlining");
return true;
}
double inliningBonus = getInliningBonus(info);
int nodes = info.determineNodeCount();
int lowLevelGraphSize = previousLowLevelGraphSize(info);
if (SmallCompiledLowLevelGraphSize.getValue(options) > 0 && lowLevelGraphSize > SmallCompiledLowLevelGraphSize.getValue(options) * inliningBonus) {
InliningUtil.traceNotInlinedMethod(info, inliningDepth, "too large previous low-level graph (low-level-nodes: %d, relevance=%f, probability=%f, bonus=%f, nodes=%d)", lowLevelGraphSize, relevance, probability, inliningBonus, nodes);
return false;
}
if (nodes < TrivialInliningSize.getValue(options) * inliningBonus) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "trivial (relevance=%f, probability=%f, bonus=%f, nodes=%d)", relevance, probability, inliningBonus, nodes);
return true;
}
/*
* TODO (chaeubl): invoked methods that are on important paths but not yet compiled -> will
* be compiled anyways and it is likely that we are the only caller... might be useful to
* inline those methods but increases bootstrap time (maybe those methods are also getting
* queued in the compilation queue concurrently)
*/
double invokes = determineInvokeProbability(info);
if (LimitInlinedInvokes.getValue(options) > 0 && fullyProcessed && invokes > LimitInlinedInvokes.getValue(options) * inliningBonus) {
InliningUtil.traceNotInlinedMethod(info, inliningDepth, "callee invoke probability is too high (invokeP=%f, relevance=%f, probability=%f, bonus=%f, nodes=%d)", invokes, relevance, probability, inliningBonus, nodes);
return false;
}
double maximumNodes = computeMaximumSize(relevance, (int) (MaximumInliningSize.getValue(options) * inliningBonus));
if (nodes <= maximumNodes) {
InliningUtil.traceInlinedMethod(info, inliningDepth, fullyProcessed, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d <= %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
return true;
}
InliningUtil.traceNotInlinedMethod(info, inliningDepth, "relevance-based (relevance=%f, probability=%f, bonus=%f, nodes=%d > %f)", relevance, probability, inliningBonus, nodes, maximumNodes);
return false;
}
use of org.graalvm.compiler.phases.common.inlining.info.InlineInfo in project graal by oracle.
the class InliningData method doInline.
@SuppressWarnings("try")
private void doInline(CallsiteHolderExplorable callerCallsiteHolder, MethodInvocation calleeInvocation) {
StructuredGraph callerGraph = callerCallsiteHolder.graph();
InlineInfo calleeInfo = calleeInvocation.callee();
try {
try (DebugContext.Scope scope = debug.scope("doInline", callerGraph)) {
EconomicSet<Node> canonicalizedNodes = EconomicSet.create(Equivalence.IDENTITY);
canonicalizedNodes.addAll(calleeInfo.invoke().asNode().usages());
EconomicSet<Node> parameterUsages = calleeInfo.inline(new Providers(context));
canonicalizedNodes.addAll(parameterUsages);
counterInliningRuns.increment(debug);
debug.dump(DebugContext.DETAILED_LEVEL, callerGraph, "after %s", calleeInfo);
Graph.Mark markBeforeCanonicalization = callerGraph.getMark();
canonicalizer.applyIncremental(callerGraph, context, canonicalizedNodes);
// process invokes that are possibly created during canonicalization
for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {
if (newNode instanceof Invoke) {
callerCallsiteHolder.pushInvoke((Invoke) newNode);
}
}
callerCallsiteHolder.computeProbabilities();
counterInliningPerformed.increment(debug);
}
} catch (BailoutException bailout) {
throw bailout;
} catch (AssertionError | RuntimeException e) {
throw new GraalError(e).addContext(calleeInfo.toString());
} catch (GraalError e) {
throw e.addContext(calleeInfo.toString());
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.phases.common.inlining.info.InlineInfo in project graal by oracle.
the class InliningData method tryToInline.
/**
* This method attempts:
* <ol>
* <li>to inline at the callsite given by <code>calleeInvocation</code>, where that callsite
* belongs to the {@link CallsiteHolderExplorable} at the top of the {@link #graphQueue}
* maintained in this class.</li>
* <li>otherwise, to devirtualize the callsite in question.</li>
* </ol>
*
* @return true iff inlining was actually performed
*/
private boolean tryToInline(MethodInvocation calleeInvocation, int inliningDepth) {
CallsiteHolderExplorable callerCallsiteHolder = (CallsiteHolderExplorable) currentGraph();
InlineInfo calleeInfo = calleeInvocation.callee();
assert callerCallsiteHolder.containsInvoke(calleeInfo.invoke());
counterInliningConsidered.increment(debug);
if (inliningPolicy.isWorthInlining(context.getReplacements(), calleeInvocation, inliningDepth, true)) {
doInline(callerCallsiteHolder, calleeInvocation);
return true;
}
if (context.getOptimisticOptimizations().devirtualizeInvokes(calleeInfo.graph().getOptions())) {
calleeInfo.tryToDevirtualizeInvoke(new Providers(context));
}
return false;
}
use of org.graalvm.compiler.phases.common.inlining.info.InlineInfo in project graal by oracle.
the class InliningData method processNextInvoke.
/**
* This method picks one of the callsites belonging to the current
* {@link CallsiteHolderExplorable}. Provided the callsite qualifies to be analyzed for
* inlining, this method prepares a new stack top in {@link InliningData} for such callsite,
* which comprises:
* <ul>
* <li>preparing a summary of feasible targets, ie preparing an {@link InlineInfo}</li>
* <li>based on it, preparing the stack top proper which consists of:</li>
* <ul>
* <li>one {@link MethodInvocation}</li>
* <li>a {@link CallsiteHolder} for each feasible target</li>
* </ul>
* </ul>
*
* <p>
* The thus prepared "stack top" is needed by {@link #moveForward()} to explore the space of
* inlining decisions (each decision one of: backtracking, delving, inlining).
* </p>
*
* <p>
* The {@link InlineInfo} used to get things rolling is kept around in the
* {@link MethodInvocation}, it will be needed in case of inlining, see
* {@link InlineInfo#inline(Providers)}
* </p>
*/
private void processNextInvoke() {
CallsiteHolderExplorable callsiteHolder = (CallsiteHolderExplorable) currentGraph();
Invoke invoke = callsiteHolder.popInvoke();
InlineInfo info = getInlineInfo(invoke);
if (info != null) {
info.populateInlinableElements(context, currentGraph().graph(), canonicalizer, rootGraph.getOptions());
double invokeProbability = callsiteHolder.invokeProbability(invoke);
double invokeRelevance = callsiteHolder.invokeRelevance(invoke);
MethodInvocation methodInvocation = new MethodInvocation(info, invokeProbability, invokeRelevance, freshlyInstantiatedArguments(invoke, callsiteHolder.getFixedParams()));
pushInvocationAndGraphs(methodInvocation);
}
}
Aggregations