compiler/docs/CompilationPlanFuzzing.md
This page covers the creation and usage of fuzzed compilation plans instead of the usual phase orderings specified by the different CompilerConfigurations.
The following design can be found in the package jdk.graal.compiler.core.phases.fuzzing.
Suites > FuzzedSuites
|
AbstractCompilationPlan > MinimalFuzzedCompilationPlan > FullFuzzedCompilationPlan
/ | \ 3x| 3x|
AbstractTierPlan AbstractTierPlan AbstractTierPlan > MinimalFuzzedTierPlan > FullFuzzedTierPlan
A > B means A is the superclass of B.
Vertical lines (/, | and \) means the lower end of the line is a field of the higher end of the line.
AbstractCompilationPlanAn AbstractCompilationPlan represents a specific ordering of phases.
It is composed of three AbstractTierPlans which represent the phase orderings for high tier, mid tier and low tier.
AbstractTierPlanAn AbstractTierPlan represents the phase ordering for a tier (high, mid or low tier).
It contains a PhaseSuite which specifies the specific phase ordering of the plan.
MinimalFuzzedCompilationPlanA MinimalFuzzedCompilationPlan is a fuzzed compilation plan that is composed only of phases that apply a mandatory stage or that fulfills a future stage requirement. It is a phase ordering with the least number of phases possible.
A mandatory stage (see GraphState.MandatoryStages) is a stage that necessarily needs to be applied to the graph to produce a valid compilation. For example, StageFlag.HIGH_TIER_LOWERING is required in high tier to transition to mid tier.
A future stage requirement means the graph requires a stage to be applied. For example, if vector nodes are created, the graph requires a stage that lowers this kind of nodes.
A MinimalFuzzedCompilationPlan is composed of three MinimalFuzzedTierPlans which represent the phase orderings for high tier, mid tier and low tier.
FullFuzzedCompilationPlanA FullFuzzedCompilationPlan represents a compilation plan created by fuzzing.
It is created by inserting optional phases in a MinimalFuzzedCompilationPlan.
It is composed of three FullFuzzedTierPlans which represent the phase orderings for high tier, mid tier and low tier.
FuzzedSuitesFuzzedSuites is a subclass of Suites and represents suites created using a FullFuzzedCompilationPlan.
Since it is a subclass of Suites, it can be used instead of Suites to provide fuzzed phase orderings.
To create a fuzzed compilation plan, three fuzzed tier plans are constructed: one for high, mid and low tier. They are assembled in this order to ensure the graph state resulting from a previous tier is carried to the next tier. This way, future stage requirements can be resolved by phases in later tiers.
The MinimalFuzzedCompilationPlan is created by constructing three MinimalFuzzedTierPlans. These tier plans are assembled in three steps:
BasePhase.mustApply(GraphState) returns true.
This resolves graph or stage requirements that were introduced by earlier tiers.BasePhase.mustApply(GraphState) after applying the tier plan resulting from step 2.
This leaves only future stage requirements remaining that cannot be fulfilled by the tier itself.To fulfill future stage requirements, phases for which BasePhase.mustApply(GraphState) returns true are inserted in the suite. The procedure is as follow:
queue = queueContainingAllThePhases();
while(queue.contains(phaseThatMustApply)){
// Try to insert the phase in the plan, starting from the end.
for(position=endPosition; position >= startPosition; position--){
if(!phaseMustApply(position)){
break;
}
if(canInsertPhaseAtPosition(phaseThatMustApply, position)){
insertPhaseAtPosition(phaseThatMustApply, position);
break;
}
}
// If the phase cannot be inserted, it means it must happen after another phase. Try again later.
queue.putAtTheEnd(phaseThatMustApply);
}
The FullFuzzedCompilationPlan is created by constructing three FullFuzzedTierPlans. These tier plans are assembled with the following steps:
MinimalFuzzedTierPlan.BasePhase.mustApply(GraphState) returns true.
This resolves graph or stage requirements that were introduced by earlier tiers.phase = pickRandomPhase()
for randomPosition in positionsInThePlan {
if(skipped){
continue;
}
newPlan = currPlan.insertPhaseAtPosition(randomPosition, phase);
if(newPlan.respectsOrderingConstraints()){
currPlan = newPlan;
break;
}
}
The probability of skipping a phase is determined by a parameter of FullFuzzedTierPlan.
phase = pickRandomPhase()
for position in positionsInThePlan {
if(skipped){
continue;
}
newPlan = currPlan.insertPhaseAtPosition(position, phase);
if(newPlan.respectsOrderingConstraints()){
currPlan = newPlan;
}
}
The probability of skipping a phase is determined by a parameter of FullFuzzedTierPlan.
Compared to step 3, we keep on trying to insert the phase in the plan even if the phase was already inserted successfully. Furthermore, we do not insert at a random position but follow the natural positions order.
BasePhase.mustApply(GraphState) after applying the tier plan resulting from the previous step.
This leaves only future stage requirements remaining that cannot be fulfilled by the tier itself.You can create fuzzed compilation plans for JTT tests. For this, use one of the following equivalent commands:
mx phaseplan-fuzz-jtt-testsmx gate --tags phaseplan-fuzz-jtt-testsIt is possible to fix some parameters of the creation of fuzzed compilation plans:
mx phaseplan-fuzz-jtt-tests --minimalmx gate --extra-unittest-argument='--minimal' --tags phaseplan-fuzz-jtt-testsmx phaseplan-fuzz-jtt-tests -Dtest.graal.compilationplan.fuzzing.minimal=truemx gate --extra-unittest-argument='-Dtest.graal.compilationplan.fuzzing.minimal=true' --tags phaseplan-fuzz-jtt-testsmx gate --extra-vm-argument='-Dtest.graal.compilationplan.fuzzing.minimal=true' --tags phaseplan-fuzz-jtt-testsRandom instances. The option is -Dtest.graal.compilationplan.fuzzing.seed=<seed> and the short version is --seed=<seed>. It can be used like the option for the minimal fuzzed compilation plan.-Dtest.graal.skip.phase.insertion.odds=<number> or --skip-phase-odds=<number>.1/<number> at each position in the current suite but only if the ordering constraints are respected.-Dtest.graal.skip.phase.insertion.odds.high.tier=<number> or --high-tier-skip-phase=<number>
FullFuzzedCompilationPlan are used instead.-Dtest.graal.skip.phase.insertion.odds.mid.tier=<number> or --mid-tier-skip-phase=<number>
-Dtest.graal.skip.phase.insertion.odds.low.tier=<number> or --low-tier-skip-phase=<number>
mx phaseplan-fuzz-jtt-tests HP_lifemx gate --extra-unittest-argument='HP_life' --tags phaseplan-fuzz-jtt-tests-Djdk.graal.CompilerConfiguration=<config>You can load a phase plan (one created by a fuzzed compilation plan or any other phase plan serialized using the PhasePlanSerializer) using the command:
mx unittest -Dtest.graal.phaseplan.file="/path/to/phaseplan"
You can use fuzzed plans for CompileTheWorld's compilations by using the following commands:
mx gate --tags ctwphaseplanfuzzing
or
mx gate --extra-vm-argument='-DCompileTheWorld.FuzzPhasePlan=true' --tags ctw
These commands will make each thread create a new fuzzed compilation plan for each compilation they have to perform.
It is possible to load a phase plan (one created by a fuzzed compilation plan or any other phase plan serialized using the PhasePlanSerializer) and use it for the compilation of a method by using the command:
mx gate --extra-vm-argument='-DCompileTheWorld.LoadPhasePlan=/path/to/phaseplan' --extra-vm-argument='-DCompileTheWorld.MethodFilter=<methodName>' --extra-vm-argument='-Djdk.graal.CompilerConfiguration=<config>' --tags ctw