Add timing information to class inliner analysis
Change-Id: I9c68aae8d6814b76cc1c1577f8a666dd48d092b7
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/framework/intraprocedural/IntraproceduralDataflowAnalysis.java b/src/main/java/com/android/tools/r8/ir/analysis/framework/intraprocedural/IntraproceduralDataflowAnalysis.java
index 60136ce..dccf7e5 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/framework/intraprocedural/IntraproceduralDataflowAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/framework/intraprocedural/IntraproceduralDataflowAnalysis.java
@@ -8,6 +8,7 @@
import com.android.tools.r8.ir.analysis.framework.intraprocedural.DataflowAnalysisResult.SuccessfulDataflowAnalysisResult;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.WorkList;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -40,20 +41,29 @@
}
public DataflowAnalysisResult run(BasicBlock root) {
- return run(WorkList.newIdentityWorkList(root));
+ return run(root, Timing.empty());
}
- private DataflowAnalysisResult run(WorkList<BasicBlock> worklist) {
+ public DataflowAnalysisResult run(BasicBlock root, Timing timing) {
+ return run(WorkList.newIdentityWorkList(root), timing);
+ }
+
+ private DataflowAnalysisResult run(WorkList<BasicBlock> worklist, Timing timing) {
while (worklist.hasNext()) {
- BasicBlock block = worklist.next();
+ BasicBlock initialBlock = worklist.next();
+ BasicBlock block = initialBlock;
BasicBlock end = null;
// Compute the abstract state upon entry to the basic block, by joining all the predecessor
// exit states.
- StateType state = computeBlockEntryState(block);
+ StateType state =
+ timing.time("Compute block entry state", () -> computeBlockEntryState(initialBlock));
+
+ timing.begin("Compute transfers");
do {
for (Instruction instruction : block.getInstructions()) {
TransferFunctionResult<StateType> transferResult = transfer.apply(instruction, state);
if (transferResult.isFailedTransferResult()) {
+ timing.end();
return new FailedDataflowAnalysisResult();
}
assert transferResult.isAbstractState();
@@ -66,6 +76,8 @@
block = null;
}
} while (block != null);
+ timing.end();
+
// Update the block exit state, and re-enqueue all successor blocks if the abstract state
// changed.
if (setBlockExitState(end, state)) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
index b8f406a..854188e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/analysis/ClassInlinerMethodConstraintAnalysis.java
@@ -12,11 +12,12 @@
import com.android.tools.r8.ir.optimize.classinliner.constraint.ClassInlinerMethodConstraint;
import com.android.tools.r8.ir.optimize.classinliner.constraint.ConditionalClassInlinerMethodConstraint;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
+import com.android.tools.r8.utils.Timing;
public class ClassInlinerMethodConstraintAnalysis {
public static ClassInlinerMethodConstraint analyze(
- AppView<AppInfoWithLiveness> appView, ProgramMethod method, IRCode code) {
+ AppView<AppInfoWithLiveness> appView, ProgramMethod method, IRCode code, Timing timing) {
if (method.getDefinition().isClassInitializer()
|| method.getDefinition().getNumberOfArguments() == 0) {
return ClassInlinerMethodConstraint.alwaysFalse();
@@ -27,11 +28,13 @@
new IntraproceduralDataflowAnalysis<>(
ParameterUsages.bottom(), new TransferFunction(appView, method, code));
SuccessfulDataflowAnalysisResult<ParameterUsages> result =
- analysis.run(code.entryBlock()).asSuccessfulAnalysisResult();
+ timing.time(
+ "Data flow analysis",
+ () -> analysis.run(code.entryBlock(), timing).asSuccessfulAnalysisResult());
if (result == null) {
return ClassInlinerMethodConstraint.alwaysFalse();
}
- ParameterUsages usages = result.join().externalize();
+ ParameterUsages usages = timing.time("Externalize", () -> result.join().externalize());
if (usages.isBottom()) {
return ClassInlinerMethodConstraint.alwaysTrue();
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
index 9836791..e28b6ad 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/info/MethodOptimizationInfoCollector.java
@@ -783,15 +783,10 @@
OptimizationFeedback feedback,
Timing timing) {
timing.begin("Compute class inlining constraint");
- computeClassInlinerMethodConstraint(method, code, feedback);
- timing.end();
- }
-
- private void computeClassInlinerMethodConstraint(
- ProgramMethod method, IRCode code, OptimizationFeedback feedback) {
ClassInlinerMethodConstraint classInlinerMethodConstraint =
- ClassInlinerMethodConstraintAnalysis.analyze(appView, method, code);
+ ClassInlinerMethodConstraintAnalysis.analyze(appView, method, code, timing);
feedback.setClassInlinerMethodConstraint(method, classInlinerMethodConstraint);
+ timing.end();
}
private void computeEnumUnboxerMethodClassification(
diff --git a/src/main/java/com/android/tools/r8/utils/Timing.java b/src/main/java/com/android/tools/r8/utils/Timing.java
index 5652476..c1046e9 100644
--- a/src/main/java/com/android/tools/r8/utils/Timing.java
+++ b/src/main/java/com/android/tools/r8/utils/Timing.java
@@ -21,6 +21,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Stack;
+import java.util.function.Supplier;
public class Timing {
@@ -370,6 +371,15 @@
stack.push(child);
}
+ public <T> T time(String title, Supplier<T> supplier) {
+ begin(title);
+ try {
+ return supplier.get();
+ } finally {
+ end();
+ }
+ }
+
public void end() {
stack.peek().end(); // record time.
stack.pop();