blob: 8a40db42e8a5e279f349b3753fa6f06da16e9153 [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.conversion;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Consumer;
/**
* An abstraction of {@link IRCode}-level optimization, which may retrieve info from
* {@link AppView}; update {@link OptimizationFeedback}; or utilize {@link MethodProcessor}.
*/
public interface CodeOptimization {
// TODO(b/140766440): if some other code optimizations require more info to pass, i.e., requires
// a signature change, we may need to turn this interface into an abstract base, instead of
// rewriting every affected optimization.
// Note that a code optimization can be a collection of other code optimizations.
// In that way, IRConverter will serve as the default full processing of all optimizations.
void optimize(IRCode code, OptimizationFeedback feedback, MethodProcessor methodProcessor);
static CodeOptimization from(Consumer<IRCode> consumer) {
return (code, feedback, methodProcessor) -> {
consumer.accept(code);
};
}
static CodeOptimization sequence(CodeOptimization... codeOptimizations) {
return sequence(Arrays.asList(codeOptimizations));
}
static CodeOptimization sequence(Collection<CodeOptimization> codeOptimizations) {
return (code, feedback, methodProcessor) -> {
for (CodeOptimization codeOptimization : codeOptimizations) {
codeOptimization.optimize(code, feedback, methodProcessor);
}
};
}
/**
* Builder for {@link CodeOptimization}.
*
* Users can append either {@link CodeOptimization}, or simply {@link IRCode} consumer.
*
* Note that the order of everything that is appended through the builder matters.
*/
public static class Builder {
private ImmutableList.Builder<CodeOptimization> processingQueue;
private Builder() {
processingQueue = ImmutableList.builder();
}
public static Builder builder() {
return new Builder();
}
public Builder addIRCodeConsumer(Consumer<IRCode> consumer) {
processingQueue.add(from(consumer));
return this;
}
public Builder addCodeOptimization(CodeOptimization optimization) {
processingQueue.add(optimization);
return this;
}
public CodeOptimization build() {
return (code, feedback, methodProcessor) -> {
processingQueue
.build()
.forEach(codeOptimization ->
codeOptimization.optimize(code, feedback, methodProcessor));
};
}
}
}