implements PR-O2.3

This commit is contained in:
bQUARKz 2026-03-07 18:17:36 +00:00
parent 804fc27959
commit 7679c5eeeb
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
2 changed files with 142 additions and 7 deletions

View File

@ -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;
}
}
}

View File

@ -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))))));
}
}