implements PR-O4.5

This commit is contained in:
bQUARKz 2026-03-07 19:44:33 +00:00
parent 0073469555
commit 5abadc62fa
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
7 changed files with 97 additions and 7 deletions

View File

@ -35,10 +35,18 @@ public final class IRVMProfileFeatureGate {
this.allowedByProfile = allowedByProfile == null ? Map.of() : Map.copyOf(allowedByProfile);
}
public String normalizeProfile(final String profile) {
return profile == null || profile.isBlank() ? "core-v1" : profile;
}
public boolean isSupportedProfile(final String profile) {
return allowedByProfile.containsKey(normalizeProfile(profile));
}
public boolean isAllowed(
final String profile,
final IRVMOp op) {
final var allowed = allowedByProfile.get(profile == null || profile.isBlank() ? "core-v1" : profile);
final var allowed = allowedByProfile.get(normalizeProfile(profile));
return allowed != null && allowed.contains(op);
}
}

View File

@ -29,6 +29,12 @@ public class LowerToIRVMService {
}
public IRVMProgram lower(final IRBackend backend) {
return lower(backend, "core-v1");
}
public IRVMProgram lower(
final IRBackend backend,
final String vmProfile) {
if (backend == null || backend.getExecutableFunctions().isEmpty()) {
throw new IRVMLoweringException(
IRVMLoweringErrorCode.LOWER_IRVM_EMPTY_EXECUTABLE_INPUT,
@ -194,7 +200,7 @@ public class LowerToIRVMService {
ReadOnlyList.wrap(operations)));
}
final var module = new IRVMModule("core-v1", ReadOnlyList.wrap(loweredFunctions));
final var module = new IRVMModule(vmProfile, ReadOnlyList.wrap(loweredFunctions));
validator.validate(module, false);
return new IRVMProgram(
module,

View File

@ -5,26 +5,35 @@ import java.util.Objects;
public class OptimizeIRVMService {
private final IRVMValidator validator;
private final IRVMProfileFeatureGate profileFeatureGate;
private final List<IRVMPass> passes;
public OptimizeIRVMService() {
this(new IRVMValidator(), List.of(new NoOpPass()));
this(new IRVMValidator(), new IRVMProfileFeatureGate(), List.of(new NoOpPass()));
}
OptimizeIRVMService(final IRVMValidator validator) {
this(validator, List.of(new NoOpPass()));
this(validator, new IRVMProfileFeatureGate(), List.of(new NoOpPass()));
}
OptimizeIRVMService(
final IRVMValidator validator,
final List<IRVMPass> passes) {
this(validator, new IRVMProfileFeatureGate(), passes);
}
OptimizeIRVMService(
final IRVMValidator validator,
final IRVMProfileFeatureGate profileFeatureGate,
final List<IRVMPass> passes) {
this.validator = validator;
this.profileFeatureGate = profileFeatureGate;
this.passes = passes == null ? List.of(new NoOpPass()) : List.copyOf(passes);
}
public IRVMProgram optimize(final IRVMProgram input) {
final var program = input == null ? IRVMProgram.empty() : input;
if (!"core-v1".equals(program.module().vmProfile())) {
if (!profileFeatureGate.isSupportedProfile(program.module().vmProfile())) {
throw new IllegalArgumentException("unsupported vm profile: " + program.module().vmProfile());
}
var current = program;

View File

@ -2,4 +2,16 @@ package p.studio.compiler.messages;
public record BuilderPipelineConfig(
boolean explain,
String rootProjectPath) {}
String rootProjectPath,
String vmProfile) {
public BuilderPipelineConfig(
final boolean explain,
final String rootProjectPath) {
this(explain, rootProjectPath, "core-v1");
}
public BuilderPipelineConfig {
vmProfile = vmProfile == null || vmProfile.isBlank() ? "core-v1" : vmProfile;
}
}

View File

@ -32,7 +32,7 @@ public class LowerToIRVMPipelineStage implements PipelineStage {
.message("[BUILD]: IRBackend is missing before LowerToIRVM stage"));
}
try {
ctx.irvm = lowerToIRVMService.lower(ctx.irBackend);
ctx.irvm = lowerToIRVMService.lower(ctx.irBackend, ctx.config.vmProfile());
} catch (IRVMLoweringException e) {
return BuildingIssueSink.empty()
.report(builder -> builder

View File

@ -11,6 +11,7 @@ import p.studio.utilities.logs.LogAggregator;
import p.studio.utilities.structures.ReadOnlyList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -62,4 +63,36 @@ class LowerToIRVMPipelineStageTest {
assertNotNull(ctx.irvm);
assertEquals(1, ctx.irvm.module().functions().size());
}
@Test
void runMustPropagateConfiguredVmProfileToLowering() {
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, ".", "experimental-v1"));
ctx.irBackend = IRBackend.builder()
.executableFunctions(ReadOnlyList.from(new IRBackendExecutableFunction(
new FileId(0),
"app",
"main",
1,
0,
10,
0,
0,
0,
1,
ReadOnlyList.from(new IRBackendExecutableFunction.Instruction(
IRBackendExecutableFunction.InstructionKind.RET,
"",
"",
null,
null,
Span.none())),
Span.none())))
.build();
final var issues = new LowerToIRVMPipelineStage().run(ctx, LogAggregator.empty());
assertFalse(issues.hasErrors());
assertNotNull(ctx.irvm);
assertEquals("experimental-v1", ctx.irvm.module().vmProfile());
}
}

View File

@ -74,4 +74,26 @@ class OptimizeIRVMPipelineStageTest {
assertTrue(issues.hasErrors());
assertEquals(1, issues.size());
}
@Test
void runMustAcceptSupportedNonDefaultVmProfile() {
final var ctx = BuilderPipelineContext.compilerContext(new BuilderPipelineConfig(false, ".", "experimental-v1"));
ctx.irvm = new IRVMProgram(new IRVMModule(
"experimental-v1",
ReadOnlyList.from(new IRVMFunction(
"main",
0,
0,
0,
1,
ReadOnlyList.from(
new IRVMInstruction(IRVMOp.HALT, null))))));
final var stage = new OptimizeIRVMPipelineStage();
final var issues = stage.run(ctx, LogAggregator.empty());
assertFalse(issues.hasErrors());
assertNotNull(ctx.optimizedIrvm);
assertEquals("experimental-v1", ctx.optimizedIrvm.module().vmProfile());
}
}