implements PR-O2.3
This commit is contained in:
parent
804fc27959
commit
7679c5eeeb
@ -1,14 +1,25 @@
|
||||
package p.studio.compiler.backend.irvm;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class OptimizeIRVMService {
|
||||
private final IRVMValidator validator;
|
||||
private final List<IRVMPass> passes;
|
||||
|
||||
public OptimizeIRVMService() {
|
||||
this(new IRVMValidator());
|
||||
this(new IRVMValidator(), List.of(new NoOpPass()));
|
||||
}
|
||||
|
||||
OptimizeIRVMService(final IRVMValidator validator) {
|
||||
this(validator, List.of(new NoOpPass()));
|
||||
}
|
||||
|
||||
OptimizeIRVMService(
|
||||
final IRVMValidator validator,
|
||||
final List<IRVMPass> passes) {
|
||||
this.validator = validator;
|
||||
this.passes = passes == null ? List.of(new NoOpPass()) : List.copyOf(passes);
|
||||
}
|
||||
|
||||
public IRVMProgram optimize(final IRVMProgram input) {
|
||||
@ -16,11 +27,41 @@ public class OptimizeIRVMService {
|
||||
if (!"core-v1".equals(program.module().vmProfile())) {
|
||||
throw new IllegalArgumentException("unsupported vm profile: " + program.module().vmProfile());
|
||||
}
|
||||
validator.validate(program.module(), false);
|
||||
// Baseline pass manager: no-op pass preserving semantic shape.
|
||||
final var optimized = program;
|
||||
validator.validate(optimized.module(), false);
|
||||
return optimized;
|
||||
var current = program;
|
||||
validator.validate(current.module(), false);
|
||||
for (final var pass : passes) {
|
||||
if (pass == null || !pass.enabled()) {
|
||||
continue;
|
||||
}
|
||||
final var beforeProfile = current.module().vmProfile();
|
||||
current = Objects.requireNonNull(pass.apply(current), "pass output");
|
||||
if (!beforeProfile.equals(current.module().vmProfile())) {
|
||||
throw new IllegalArgumentException("pass changed vm profile: " + pass.name());
|
||||
}
|
||||
validator.validate(current.module(), false);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
public interface IRVMPass {
|
||||
String name();
|
||||
|
||||
default boolean enabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
IRVMProgram apply(IRVMProgram input);
|
||||
}
|
||||
|
||||
private static final class NoOpPass implements IRVMPass {
|
||||
@Override
|
||||
public String name() {
|
||||
return "NoOpPass";
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRVMProgram apply(final IRVMProgram input) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,94 @@
|
||||
package p.studio.compiler.backend.irvm;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import p.studio.utilities.structures.ReadOnlyList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class OptimizeIRVMServiceTest {
|
||||
|
||||
@Test
|
||||
void optimizeMustExecuteEnabledPassesInDeclaredOrder() {
|
||||
final var order = new ArrayList<String>();
|
||||
final var service = new OptimizeIRVMService(new IRVMValidator(), List.of(
|
||||
namedPass("A", order, true),
|
||||
namedPass("B", order, true)));
|
||||
|
||||
final var output = service.optimize(validProgram());
|
||||
|
||||
assertEquals(validProgram(), output);
|
||||
assertEquals(List.of("A", "B"), order);
|
||||
}
|
||||
|
||||
@Test
|
||||
void optimizeMustSkipDisabledPasses() {
|
||||
final var order = new ArrayList<String>();
|
||||
final var service = new OptimizeIRVMService(new IRVMValidator(), List.of(
|
||||
namedPass("A", order, false),
|
||||
namedPass("B", order, true)));
|
||||
|
||||
service.optimize(validProgram());
|
||||
|
||||
assertEquals(List.of("B"), order);
|
||||
}
|
||||
|
||||
@Test
|
||||
void optimizeMustRejectPassThatMutatesVmProfile() {
|
||||
final var service = new OptimizeIRVMService(new IRVMValidator(), List.of(new OptimizeIRVMService.IRVMPass() {
|
||||
@Override
|
||||
public String name() {
|
||||
return "MutateProfile";
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRVMProgram apply(final IRVMProgram input) {
|
||||
return new IRVMProgram(new IRVMModule(
|
||||
"experimental",
|
||||
input.module().functions()));
|
||||
}
|
||||
}));
|
||||
|
||||
final var thrown = assertThrows(IllegalArgumentException.class, () -> service.optimize(validProgram()));
|
||||
assertTrue(thrown.getMessage().contains("vm profile"));
|
||||
}
|
||||
|
||||
private OptimizeIRVMService.IRVMPass namedPass(
|
||||
final String name,
|
||||
final List<String> order,
|
||||
final boolean enabled) {
|
||||
return new OptimizeIRVMService.IRVMPass() {
|
||||
@Override
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRVMProgram apply(final IRVMProgram input) {
|
||||
order.add(name);
|
||||
return input;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IRVMProgram validProgram() {
|
||||
return new IRVMProgram(new IRVMModule(
|
||||
"core-v1",
|
||||
ReadOnlyList.from(new IRVMFunction(
|
||||
"main",
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
ReadOnlyList.from(new IRVMInstruction(IRVMOp.HALT, null))))));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user