blob: fd3c580bdee2bcbcb7e2b95687495943d10d0824 [file] [log] [blame]
// Copyright (c) 2021, 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.conversion;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.optimize.DeadCodeRemover;
public abstract class MethodConversionOptions {
public static MutableMethodConversionOptions forPreLirPhase(AppView<?> appView) {
if (!appView.enableWholeProgramOptimizations()) {
return forD8(appView);
}
assert appView.testing().isPreLirPhase();
return new MutableMethodConversionOptions(Target.CF);
}
public static MutableMethodConversionOptions forPostLirPhase(AppView<?> appView) {
if (!appView.enableWholeProgramOptimizations()) {
return forD8(appView);
}
assert appView.testing().isPostLirPhase();
Target target = appView.options().isGeneratingClassFiles() ? Target.CF : Target.DEX;
return new MutableMethodConversionOptions(target);
}
public static MutableMethodConversionOptions forLirPhase(AppView<?> appView) {
if (!appView.enableWholeProgramOptimizations()) {
return forD8(appView);
}
assert appView.testing().isSupportedLirPhase();
return new MutableMethodConversionOptions(determineTarget(appView));
}
public static MutableMethodConversionOptions forD8(AppView<?> appView) {
assert !appView.enableWholeProgramOptimizations();
return new MutableMethodConversionOptions(determineTarget(appView));
}
public static MutableMethodConversionOptions nonConverting() {
return new ThrowingMethodConversionOptions();
}
public IRFinalizer<?> getFinalizer(DeadCodeRemover deadCodeRemover, AppView<?> appView) {
if (isGeneratingLir()) {
return new IRToLirFinalizer(appView);
}
if (isGeneratingClassFiles()) {
return new IRToCfFinalizer(appView, deadCodeRemover);
}
assert isGeneratingDex();
return new IRToDexFinalizer(appView, deadCodeRemover);
}
private enum Target {
CF,
DEX,
LIR
}
private static Target determineTarget(AppView<?> appView) {
if (appView.testing().canUseLir(appView)) {
return Target.LIR;
}
if (appView.options().isGeneratingClassFiles()) {
return Target.CF;
}
assert appView.options().isGeneratingDex();
return Target.DEX;
}
public abstract boolean isGeneratingLir();
public abstract boolean isGeneratingClassFiles();
public abstract boolean isGeneratingDex();
public abstract boolean isPeepholeOptimizationsEnabled();
public abstract boolean shouldFinalizeAfterLensCodeRewriter();
public static class MutableMethodConversionOptions extends MethodConversionOptions {
private final Target target;
private boolean enablePeepholeOptimizations = true;
private boolean finalizeAfterLensCodeRewriter;
private MutableMethodConversionOptions(Target target) {
this.target = target;
}
public void disablePeepholeOptimizations(MethodProcessor methodProcessor) {
assert methodProcessor.isPrimaryMethodProcessor();
enablePeepholeOptimizations = false;
}
public MutableMethodConversionOptions setFinalizeAfterLensCodeRewriter() {
finalizeAfterLensCodeRewriter = true;
return this;
}
@Override
public boolean isGeneratingLir() {
return target == Target.LIR;
}
@Override
public boolean isGeneratingClassFiles() {
return target == Target.CF;
}
@Override
public boolean isGeneratingDex() {
return target == Target.DEX;
}
@Override
public boolean isPeepholeOptimizationsEnabled() {
return enablePeepholeOptimizations;
}
@Override
public boolean shouldFinalizeAfterLensCodeRewriter() {
return finalizeAfterLensCodeRewriter;
}
}
public static class ThrowingMethodConversionOptions extends MutableMethodConversionOptions {
private ThrowingMethodConversionOptions() {
super(null);
}
@Override
public boolean isGeneratingLir() {
throw new Unreachable();
}
@Override
public boolean isGeneratingClassFiles() {
throw new Unreachable();
}
@Override
public boolean isGeneratingDex() {
throw new Unreachable();
}
@Override
public boolean isPeepholeOptimizationsEnabled() {
throw new Unreachable();
}
}
}