blob: 6340db4e1d1b3470c5e1a48dfbba3d688f491e0f [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.optimize.inliner;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.ir.code.InstancePut;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InvokeDirect;
import java.io.PrintStream;
class WhyAreYouNotInliningReporterImpl extends WhyAreYouNotInliningReporter {
private final DexEncodedMethod callee;
private final DexEncodedMethod context;
private final PrintStream output;
private boolean reasonHasBeenReported = false;
WhyAreYouNotInliningReporterImpl(
DexEncodedMethod callee, DexEncodedMethod context, PrintStream output) {
this.callee = callee;
this.context = context;
this.output = output;
}
private void print(String reason) {
output.print("Method `");
output.print(callee.method.toSourceString());
output.print("` was not inlined into `");
output.print(context.method.toSourceString());
if (reason != null) {
output.print("`: ");
output.println(reason);
} else {
output.println("`.");
}
reasonHasBeenReported = true;
}
private void printWithExceededThreshold(
String reason, String description, int value, int threshold) {
print(reason + " (" + description + ": " + value + ", threshold: " + threshold + ").");
}
@Override
public void reportInstructionBudgetIsExceeded() {
print("caller's instruction budget is exceeded.");
}
@Override
public void reportPotentialExplosionInExceptionalControlFlowResolutionBlocks(
int estimatedNumberOfControlFlowResolutionBlocks, int threshold) {
printWithExceededThreshold(
"could lead to an explosion in the number of moves due to the exceptional control flow",
"estimated number of control flow resolution blocks",
estimatedNumberOfControlFlowResolutionBlocks,
threshold);
}
// TODO(b/142108662): Always report a meaningful reason.
@Override
public void reportUnknownReason() {
print(null);
}
@Override
public void reportUnknownTarget() {
print("could not find a single target.");
}
@Override
public void reportUnsafeConstructorInliningDueToFinalFieldAssignment(InstancePut instancePut) {
print(
"final field `"
+ instancePut.getField()
+ "` must be initialized in a constructor of `"
+ callee.method.holder.toSourceString()
+ "`.");
}
@Override
public void reportUnsafeConstructorInliningDueToIndirectConstructorCall(InvokeDirect invoke) {
print(
"must invoke a constructor from the class being instantiated (would invoke `"
+ invoke.getInvokedMethod().toSourceString()
+ "`).");
}
@Override
public void reportUnsafeConstructorInliningDueToUninitializedObjectUse(Instruction user) {
print("would lead to use of uninitialized object (user: `" + user.toString() + "`).");
}
@Override
public void reportWillExceedInstructionBudget(int numberOfInstructions, int threshold) {
printWithExceededThreshold(
"would exceed the caller's instruction budget",
"number of instructions in inlinee",
numberOfInstructions,
threshold);
}
@Override
public boolean verifyReasonHasBeenReported() {
assert reasonHasBeenReported;
return true;
}
}