All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.graalvm.compiler.nodes.GraphState Maven / Gradle / Ivy

There is a newer version: 24.1.1
Show newest version
/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package org.graalvm.compiler.nodes;

import java.util.EnumSet;
import java.util.Formatter;
import java.util.Objects;

import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.graph.Graph;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.util.GraphUtil;

import jdk.vm.ci.meta.SpeculationLog;

/**
 * Describes {@link StructuredGraph} state with respect to compilation.
 *
 * This state is defined by fields which represent
 * 
    *
  • The progress made in the compilation (e.g. which stages have been reached (see * {@link StageFlag}), which verification is performed by {@link FrameState}s (see * {@link FrameStateVerification}))
  • *
  • The properties of the intermediate representation (e.g. if new {@link DeoptimizingNode}s can * be introduced (see {@link GuardsStage}), if the graph contains nodes that require a stage to be * applied on the graph (see {@link #getFutureRequiredStages()}))
  • *
*/ public final class GraphState { /** * These sets of {@link StageFlag}s represent the necessary stages that must be applied to a * {@link StructuredGraph} for a complete compilation. */ private static final EnumSet HIGH_TIER_MANDATORY_STAGES = EnumSet.of( StageFlag.HIGH_TIER_LOWERING); private static final EnumSet MID_TIER_MANDATORY_STAGES = EnumSet.of( StageFlag.VALUE_PROXY_REMOVAL, StageFlag.SAFEPOINTS_INSERTION, StageFlag.GUARD_LOWERING, StageFlag.MID_TIER_LOWERING, StageFlag.FSA, StageFlag.BARRIER_ADDITION); private static final EnumSet LOW_TIER_MANDATORY_STAGES = EnumSet.of( StageFlag.LOW_TIER_LOWERING, StageFlag.EXPAND_LOGIC, StageFlag.ADDRESS_LOWERING); private static final EnumSet ENTERPRISE_MID_TIER_MANDATORY_STAGES = EnumSet.of( StageFlag.VALUE_PROXY_REMOVAL, StageFlag.SAFEPOINTS_INSERTION, StageFlag.GUARD_LOWERING, StageFlag.MID_TIER_LOWERING, StageFlag.FSA, StageFlag.BARRIER_ADDITION, StageFlag.NODE_VECTORIZATION); /** * This set of {@link StageFlag}s represents the stages a {@link StructuredGraph} initially * requires to correctly pass all the other stages of the compilation. (See * {@link #getFutureRequiredStages()}) */ public static final EnumSet INITIAL_REQUIRED_STAGES = EnumSet.of(StageFlag.CANONICALIZATION); /** * Indicates a stage is in progress. */ private StageFlag currentStage; /** * Flag to indicate {@link #forceDisableFrameStateVerification()} was called. */ private boolean disabledFrameStateVerification; /** * Represents the status of {@linkplain FrameState} verification of * {@linkplain AbstractStateSplit} state after. */ private FrameStateVerification frameStateVerification; /** * Records the stages required by this graph. For example, if a stage introduces nodes that need * to be lowered in the graph, the graph will require a lowering stage to be in a correct state * after the compilation. After the lowering has been executed, the requirement will be * fulfilled. {@link GraphState#futureRequiredStages} should be empty after the compilation. */ private EnumSet futureRequiredStages; /** * Represents the state and properties of {@link DeoptimizingNode}s and {@link FrameState}s in * the graph. */ private GuardsStage guardsStage; /** * Records which stages have been applied to the graph. */ private EnumSet stageFlags; /** * Contains the {@link SpeculationLog} used to perform speculative operations on this graph. */ private final SpeculationLog speculationLog; /** * Creates a {@link GraphState} with the given fields. * * @param isSubstitution determines this {@linkplain #getFrameStateVerification() frame state * verification}. {@link FrameStateVerification#NONE} is used if it is {@code true}, * otherwise it is {@link FrameStateVerification#ALL}. If it is {@code true}, * {@link #isFrameStateVerificationDisabled()} will be {@code true}. */ public GraphState(StageFlag currentStage, boolean disabledFrameStateVerification, boolean isSubstitution, EnumSet futureRequiredStages, GuardsStage guardsStage, SpeculationLog speculationLog, EnumSet stageFlags) { this(currentStage, disabledFrameStateVerification || isSubstitution, isSubstitution ? FrameStateVerification.NONE : FrameStateVerification.ALL, futureRequiredStages, guardsStage, speculationLog, stageFlags); } /** * Creates a {@link GraphState} with the given fields. * * @param guardsStage the {@link GuardsStage} of this graph state, * {@link GuardsStage#FLOATING_GUARDS} if it is {@code null}. */ public GraphState(StageFlag currentStage, boolean disabledFrameStateVerification, FrameStateVerification frameStateVerification, EnumSet futureRequiredStages, GuardsStage guardsStage, SpeculationLog speculationLog, EnumSet stageFlags) { this.currentStage = currentStage; this.disabledFrameStateVerification = disabledFrameStateVerification; this.frameStateVerification = frameStateVerification; this.futureRequiredStages = futureRequiredStages == null ? EnumSet.noneOf(StageFlag.class) : futureRequiredStages; this.guardsStage = guardsStage == null ? GuardsStage.FLOATING_GUARDS : guardsStage; this.speculationLog = speculationLog; this.stageFlags = stageFlags == null ? EnumSet.noneOf(StageFlag.class) : stageFlags; } /** * Creates a {@link GraphState} with {@linkplain #getGuardsStage() guards stage} set to * {@link GuardsStage#FLOATING_GUARDS}, empty {@link EnumSet} for {@linkplain #getStageFlags() * stage flags} and {@linkplain #getFutureRequiredStages() future required stages}, * {@linkplain #getFrameStateVerification() frame state verification} set to * {@link FrameStateVerification#ALL} and {@code null} for the other fields. */ public static GraphState defaultGraphState() { return new GraphState(null, false, false, null, null, null, null); } /** * Creates a copy of this graph state. The copy's {@linkplain #getStageFlags() stage flags} and * {@linkplain #getFutureRequiredStages() future required stages} are deep copy of this graph * state's respective fields. */ public GraphState copy() { return new GraphState(this.currentStage, disabledFrameStateVerification, this.frameStateVerification, EnumSet.copyOf(this.futureRequiredStages), this.guardsStage, this.speculationLog, EnumSet.copyOf(this.stageFlags)); } /** * Creates a copy of this graph state with the given {@linkplain #getSpeculationLog() * speculation log}. The copy's {@linkplain #getStageFlags() stage flags} and * {@linkplain #getFutureRequiredStages() future required stages} are deep copy of this graph * state's respective fields. * * @param isSubstitution determines the copy's {@linkplain #getFrameStateVerification() frame * state verification}. (See * {@link #GraphState(StageFlag, boolean, boolean, EnumSet, GuardsStage, SpeculationLog, EnumSet)}) */ public GraphState copyWith(boolean isSubstitution, SpeculationLog speculationLogForCopy) { return new GraphState(this.currentStage, disabledFrameStateVerification, isSubstitution, EnumSet.copyOf(this.futureRequiredStages), this.guardsStage, speculationLogForCopy, EnumSet.copyOf(this.stageFlags)); } @Override public String toString() { return toString(""); } /** * Creates a {@link String} with this {@linkplain #getGuardsStage() guards stage}, * {@linkplain #getStageFlags() stage flags}, {@linkplain #getFrameStateVerification() frame * state verification} and {@linkplain #getFutureRequiredStages() future required stages}. * * @param prefix the string inserted at the beginning of each line of the resulting string. */ public String toString(String prefix) { Formatter formatter = new Formatter(); formatter.format("%sGraphState:%n", prefix); formatter.format("%s\tGuards stage: %s%n", prefix, guardsStage.toString()); formatter.format("%s\tStage flags:%n", prefix); for (StageFlag flag : stageFlags) { formatter.format("%s\t\t%s%n", prefix, flag.toString()); } formatter.format("%s\tFrame state verification: %s%n", prefix, frameStateVerification.toString()); formatter.format("%s\tFuture required stages: %s%n", prefix, futureRequiredStages.toString()); return formatter.toString(); } /** * Creates a {@link String} representing the differences between this * {@linkplain #getGuardsStage() guards stage}, {@linkplain #getStageFlags() stage flags}, * {@linkplain #getFrameStateVerification() frame state verification} and * {@linkplain #getFutureRequiredStages() future required stages} and {@code previous}'s * respective fields. If {@code this} {@link #equals} {@code previous}, an empty string is * returned. */ public String updateFromPreviousToString(GraphState previous) { if (this.equals(previous)) { return ""; } StringBuilder builder = new StringBuilder(); builder.append('{'); builder.append(valueStringAsDiff(previous.guardsStage, this.guardsStage, "Guards stage: ", ", ")); builder.append(newFlagsToString(previous.stageFlags, this.stageFlags, "+", "Stage flags: ")); builder.append(valueStringAsDiff(previous.frameStateVerification, this.frameStateVerification, "Frame state verification: ", ", ")); builder.append(newFlagsToString(previous.futureRequiredStages, this.futureRequiredStages, "+", "Future required stages: ")); builder.append(newFlagsToString(this.futureRequiredStages, previous.futureRequiredStages, "-", "")); builder.setLength(builder.length() - 2); builder.append('}'); return builder.toString(); } /** * @return the {@link String} representing the difference between {@code oldValue} and * {@code newValue}, surrounded by {@code prefix} and {@code suffix}. If both values are * equal, returns an empty string. */ private static String valueStringAsDiff(T oldValue, T newValue, String prefix, String suffix) { if (oldValue == newValue) { return ""; } return String.format("%s%s -> %s%s", prefix, oldValue, newValue, suffix); } /** * @return a {@link String} representing the {@link StageFlag}s that differ between * {@code oldSet} and {@code newSet}. If both sets are equal, returns an empty string. */ private static String newFlagsToString(EnumSet oldSet, EnumSet newSet, String flagPrefix, String prefix) { Formatter formatter = new Formatter(); EnumSet newFlags = newSet.clone(); newFlags.removeAll(oldSet); if (!newFlags.isEmpty()) { formatter.format(prefix); for (StageFlag flag : newFlags) { formatter.format("%s%s, ", flagPrefix, flag.toString()); } } return formatter.toString(); } @Override public int hashCode() { return Objects.hash(currentStage, disabledFrameStateVerification, frameStateVerification, futureRequiredStages, guardsStage, speculationLog, stageFlags); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof GraphState)) { return false; } GraphState graphState = (GraphState) obj; return this.currentStage == graphState.currentStage && this.disabledFrameStateVerification == graphState.disabledFrameStateVerification && this.frameStateVerification == graphState.frameStateVerification && this.futureRequiredStages.equals(graphState.futureRequiredStages) && this.guardsStage == graphState.guardsStage && Objects.equals(this.speculationLog, graphState.speculationLog) && this.stageFlags.equals(graphState.stageFlags); } /** * @return the {@link SpeculationLog} used to perform speculative operations on this graph. */ public SpeculationLog getSpeculationLog() { return speculationLog; } /** * Determines if {@linkplain #getFrameStateVerification() frame state verification} has been * forcefully disabled. * * @return {@code true} if {@link #forceDisableFrameStateVerification()} or * {@link StructuredGraph#clearAllStateAfterForTestingOnly()} has been called or if this * graph was build as a substitution (see * {@link #GraphState(StageFlag, boolean, boolean, EnumSet, GuardsStage, SpeculationLog, EnumSet)}). */ public boolean isFrameStateVerificationDisabled() { return disabledFrameStateVerification; } /** * Different node types verified during {@linkplain GraphState.FrameStateVerification}. See * {@linkplain GraphState.FrameStateVerification} for details. */ public enum FrameStateVerificationFeature { STATE_SPLITS, MERGES, LOOP_BEGINS, LOOP_EXITS } /** * The different stages of the compilation of a {@link Graph} regarding the status of * {@linkplain FrameState} verification of {@linkplain AbstractStateSplit} state after. * Verification starts with the mode {@linkplain FrameStateVerification#ALL}, i.e., all state * splits with side-effects, merges and loop exits need a proper state after. The verification * mode progresses monotonously until the {@linkplain FrameStateVerification#NONE} mode is * reached. From there on, no further {@linkplain AbstractStateSplit#stateAfter} verification * happens. */ public enum FrameStateVerification { /** * Verify all {@linkplain AbstractStateSplit} nodes that return {@code true} for * {@linkplain AbstractStateSplit#hasSideEffect()} have a * {@linkplain AbstractStateSplit#stateAfter} assigned. Additionally, verify * {@linkplain LoopExitNode} and {@linkplain AbstractMergeNode} have a valid * {@linkplain AbstractStateSplit#stateAfter}. This is necessary to avoid missing * {@linkplain FrameState} after optimizations. See {@link GraphUtil#mayRemoveSplit} for * more details. * * This stage is the initial verification stage for every graph. */ ALL(EnumSet.allOf(FrameStateVerificationFeature.class)), /** * Same as {@linkplain #ALL} except that {@linkplain LoopExitNode} nodes are no longer * verified. */ ALL_EXCEPT_LOOP_EXIT(EnumSet.complementOf(EnumSet.of(FrameStateVerificationFeature.LOOP_EXITS))), /** * Same as {@linkplain #ALL_EXCEPT_LOOP_EXIT} except that {@linkplain LoopBeginNode} are no * longer verified. */ ALL_EXCEPT_LOOPS(EnumSet.complementOf(EnumSet.of(FrameStateVerificationFeature.LOOP_BEGINS, FrameStateVerificationFeature.LOOP_EXITS))), /** * Verification is disabled. Typically used after assigning {@linkplain FrameState} to * {@linkplain DeoptimizeNode} or for {@linkplain Snippet} compilations. */ NONE(EnumSet.noneOf(FrameStateVerificationFeature.class)); private EnumSet features; FrameStateVerification(EnumSet features) { this.features = features; } /** * Determines if the current verification mode implies this feature. * * @param feature the other verification feature to check * @return {@code true} if this verification mode implies the feature, {@code false} * otherwise */ boolean implies(FrameStateVerificationFeature feature) { return this.features.contains(feature); } } /** * @return the status of the {@link FrameState} verification of {@link AbstractStateSplit} state * after. */ public FrameStateVerification getFrameStateVerification() { return frameStateVerification; } /** * Checks if this {@linkplain #getFrameStateVerification() frame state verification} can be * weakened to the given {@link FrameStateVerification}. Verification can only be relaxed over * the course of compilation. */ public boolean canWeakenFrameStateVerification(FrameStateVerification stage) { if (isFrameStateVerificationDisabled()) { assert frameStateVerification == FrameStateVerification.NONE : "Frame state verification is disabled, should be NONE but is " + frameStateVerification; return true; } return frameStateVerification.ordinal() <= stage.ordinal(); } /** * Sets the given {@link FrameStateVerification} as this * {@linkplain #getFrameStateVerification() frame state verification}. */ public void weakenFrameStateVerification(FrameStateVerification newFrameStateVerification) { if (isFrameStateVerificationDisabled()) { assert frameStateVerification == FrameStateVerification.NONE : "Frame state verification is disabled, should be NONE but is " + frameStateVerification; return; } assert canWeakenFrameStateVerification(newFrameStateVerification) : "Old verification " + frameStateVerification + " must imply new verification " + newFrameStateVerification + ", i.e., verification can only be relaxed over the course of compilation"; frameStateVerification = newFrameStateVerification; } /** * Forcefully disable {@linkplain #getFrameStateVerification() frame state verification} for the * rest of this compilation. This must only be used for stubs, snippets, and test code that * builds custom compilation pipelines. * * Normal compilations must use {@link #weakenFrameStateVerification(FrameStateVerification)} to * progress through the standard stages of frame state verification. Calling this method is * not equivalent to calling {@code weakenFrameStateVerification(NONE)}. */ public void forceDisableFrameStateVerification() { weakenFrameStateVerification(FrameStateVerification.NONE); this.disabledFrameStateVerification = true; } /** * The different stages of the compilation of a {@link Graph} regarding the status of * {@link GuardNode}s, {@link DeoptimizingNode}s and {@link FrameState}s. The stage of a graph * progresses monotonously. */ public enum GuardsStage { /** * During this stage, there can be {@link FloatingNode floating} {@link DeoptimizingNode}s * such as {@link GuardNode}s. New {@link DeoptimizingNode}s can be introduced without * constraints. {@link FrameState}s are associated with {@link StateSplit} nodes. */ FLOATING_GUARDS, /** * During this stage, all {@link DeoptimizingNode}s must be {@link FixedNode fixed} but new * {@link DeoptimizingNode}s can still be introduced. {@link FrameState}s are still * associated with {@link StateSplit} nodes. */ FIXED_DEOPTS, /** * During this stage, all {@link DeoptimizingNode}s must be {@link FixedNode fixed}. New * {@link DeoptimizingNode}s cannot be introduced. {@link FrameState}s are now associated * with {@link DeoptimizingNode}s. */ AFTER_FSA; /** * Checks if this guards stage indicates that the graph may contain {@link FloatingNode * floating} {@link DeoptimizingNode}s such as {@link GuardNode}s. */ public boolean allowsFloatingGuards() { return this == FLOATING_GUARDS; } /** * Checks if this guards stage indicates new {@link DeoptimizingNode}s can be introduced in * the graph. */ public boolean allowsGuardInsertion() { return this.ordinal() <= FIXED_DEOPTS.ordinal(); } /** * Checks if this guards stage indicates all {@link FrameState}s are associated with * {@link DeoptimizingNode}s. */ public boolean areFrameStatesAtDeopts() { return this == AFTER_FSA; } /** * Checks if this guards stage indicates all {@link FrameState}s are associated with * {@link StateSplit} nodes. */ public boolean areFrameStatesAtSideEffects() { return !this.areFrameStatesAtDeopts(); } /** * Checks if this guards stage indicates all the {@link DeoptimizingNode}s are * {@link FixedNode fixed}. */ public boolean areDeoptsFixed() { return this.ordinal() >= FIXED_DEOPTS.ordinal(); } /** * Checks if this guards stage indicates it is necessary to have value proxies in the graph. */ public boolean requiresValueProxies() { return this != AFTER_FSA; } /** * Checks if this guards stage indicates a later or equivalent stage of the compilation than * the given stage. */ public boolean reachedGuardsStage(GuardsStage stage) { return this.ordinal() >= stage.ordinal(); } } /** * @return the current {@link GuardsStage} for this graph state. */ public GuardsStage getGuardsStage() { return guardsStage; } /** * Sets the {@linkplain #getGuardsStage() guards stage} of this graph state. The new * {@link GuardsStage} needs to indicate a progression in the compilation, not a regression. */ public void setGuardsStage(GuardsStage guardsStage) { assert guardsStage.ordinal() >= this.guardsStage.ordinal(); this.guardsStage = guardsStage; } /** * Determines if this graph state is configured in a way it only allows explicit exception edges * and no floating guards which would be lowered to deoptimize nodes. */ public boolean isExplicitExceptionsNoDeopt() { return guardsStage == GuardsStage.FIXED_DEOPTS && isAfterStage(StageFlag.GUARD_LOWERING); } /** * Configure the graph to only allow explicit exception edges without floating guard nodes. That * is the graph: * *
    *
  • has explicit exception edges on {@link WithExceptionNode#exceptionEdge} successors
  • *
  • the graph does not support floating {@link GuardNode} as they lower to * {@link DeoptimizeNode}
  • *
  • {@link GuardNode} nodes are never lowered since they are not part of the graph. The graph * is always {@link #isAfterStage(StageFlag)} {@link StageFlag#GUARD_LOWERING}
  • *
* * Note that this operation is only possible on empty graphs, i.e., it must be called at the * beginning of a compilation when a graph is created since it influences how the parser and * other components build the graph and meta data. */ public void configureExplicitExceptionsNoDeopt() { assert !isExplicitExceptionsNoDeopt(); assert stageFlags.isEmpty() : "Must not have set a stage flag before"; assert guardsStage == GuardsStage.FLOATING_GUARDS : "Default guards stage is floating guards"; setGuardsStage(GraphState.GuardsStage.FIXED_DEOPTS); setAfterStage(StageFlag.GUARD_LOWERING); } public void configureExplicitExceptionsNoDeoptIfNecessary() { if (!isExplicitExceptionsNoDeopt()) { configureExplicitExceptionsNoDeopt(); } } /** * Indicates FSA has been applied to this graph. (See {@link #setGuardsStage(GuardsStage)} and * {@link #setAfterStage(StageFlag)}) */ public void setAfterFSA() { setGuardsStage(GuardsStage.AFTER_FSA); setAfterStage(StageFlag.FSA); } /** * Different stages of the compilation regarding the status of various graph properties. The * order used to defined theses stages corresponds to their order in a standard compilation. */ public enum StageFlag { CANONICALIZATION, /* Stages applied by high tier. */ FINAL_PARTIAL_ESCAPE, HIGH_TIER_LOWERING, /* Stages applied by mid tier. */ FLOATING_READS, GUARD_MOVEMENT, GUARD_LOWERING, VALUE_PROXY_REMOVAL, SAFEPOINTS_INSERTION, MID_TIER_LOWERING, OPTIMISTIC_ALIASING, FSA, NODE_VECTORIZATION, VECTOR_MATERIALIZATION, OPTIMISTIC_GUARDS, BARRIER_ADDITION, BARRIER_ELIMINATION, /* Stages applied by low tier. */ LOW_TIER_LOWERING, VECTOR_LOWERING, EXPAND_LOGIC, FIXED_READS, ADDRESS_LOWERING, FINAL_CANONICALIZATION, TARGET_VECTOR_LOWERING, } /** * Checks if this graph state is before a stage. This stage must not be in progress (see * {@link #isDuringStage(StageFlag)}) nor have been applied yet (see * {@link #isAfterStage(StageFlag)}). */ public boolean isBeforeStage(StageFlag stage) { return !isDuringStage(stage) && !isAfterStage(stage); } /** * Phases may set this flag to indicate that a stage is in progress. This is optional: * {@link #isAfterStage(StageFlag)} may become true for a stage even if * {@link #isDuringStage(StageFlag)} was never set for that stage. */ public boolean isDuringStage(StageFlag stage) { return currentStage == stage; } /** * Checks if a stage has already been applied to this graph. */ public boolean isAfterStage(StageFlag stage) { return stageFlags.contains(stage); } /** * Checks if multiple stages have been already applied to this graph. */ public boolean isAfterStages(EnumSet stages) { return stageFlags.containsAll(stages); } /** * Sets this {@link #currentStage} to indicate that a stage is in progress. This stage must not * have been applied yet. */ public void setDuringStage(StageFlag stage) { assert isBeforeStage(stage) : "Cannot set during stage " + stage + " since the graph is not before that stage"; currentStage = stage; } /** * Adds the given stage to this {@linkplain #getStageFlags() stage flags} to indicate this stage * has been applied. This stage must not have been applied yet. */ public void setAfterStage(StageFlag stage) { assert !isAfterStage(stage) : "Cannot set after stage " + stage + " since the graph is already in that state"; stageFlags.add(stage); currentStage = null; } /** * @return the stages (see {@link StageFlag}) that were applied to this graph. */ public EnumSet getStageFlags() { return stageFlags; } /** * Checks if all the stages represented by the given {@link MandatoryStages} have been applied * to this graph. */ public boolean hasAllMandatoryStages(MandatoryStages mandatoryStages) { return stageFlags.containsAll(mandatoryStages.highTier) && stageFlags.containsAll(mandatoryStages.midTier) && stageFlags.containsAll(mandatoryStages.lowTier); } /** * @return the number of stages that are in {@code targetStages} but not in the * {@linkplain #getStageFlags() stage flags} of this graph state. */ public int countMissingStages(EnumSet targetStages) { EnumSet target = EnumSet.copyOf(targetStages); target.removeAll(stageFlags); return target.size(); } /** * Adds the given {@link StageFlag} to the {@linkplain #getFutureRequiredStages() future * required stages} of this graph state. */ public void addFutureStageRequirement(StageFlag stage) { futureRequiredStages.add(stage); } /** * Removes the {@linkplain #getFutureRequiredStages() requirement} to the given * {@link StageFlag} from this graph state. */ public void removeRequirementToStage(StageFlag stage) { futureRequiredStages.remove(stage); } /** * Checks if the given {@link StageFlag} is contained in this graph state's * {@linkplain #getFutureRequiredStages() future required stages}. */ public boolean requiresFutureStage(StageFlag stage) { return futureRequiredStages.contains(stage); } /** * Checks if this graph state has remaining {@link StageFlag}s requirements in * {@linkplain #getFutureRequiredStages() future required stages}. */ public boolean requiresFutureStages() { return !futureRequiredStages.isEmpty(); } /** * @return which stages this graph state requires. These {@linkplain #getFutureRequiredStages() * future required stages} might includes lowering phases for nodes that were introduced * in the graph by previous stages for example. */ public EnumSet getFutureRequiredStages() { return futureRequiredStages; } /** * Represents the necessary stages that must be applied to a {@link StructuredGraph} for a * complete compilation depending on the compiler configuration chosen. There is a different * {@link EnumSet} of {@link StageFlag}s for each tier of the compilation. */ public enum MandatoryStages { ECONOMY(HIGH_TIER_MANDATORY_STAGES, MID_TIER_MANDATORY_STAGES, LOW_TIER_MANDATORY_STAGES), COMMUNITY(HIGH_TIER_MANDATORY_STAGES, MID_TIER_MANDATORY_STAGES, LOW_TIER_MANDATORY_STAGES), ENTERPRISE(HIGH_TIER_MANDATORY_STAGES, ENTERPRISE_MID_TIER_MANDATORY_STAGES, LOW_TIER_MANDATORY_STAGES); private final EnumSet highTier; private final EnumSet midTier; private final EnumSet lowTier; MandatoryStages(EnumSet highTier, EnumSet midTier, EnumSet lowTier) { this.highTier = highTier; this.midTier = midTier; this.lowTier = lowTier; } /** * @return the {@link MandatoryStages} corresponding to the given string. If no such value * is found, returns {@link #COMMUNITY}. */ public static MandatoryStages getFromName(String name) { switch (name.toLowerCase()) { case "economy": return ECONOMY; case "community": return COMMUNITY; case "enterprise": return ENTERPRISE; default: return COMMUNITY; } } /** * @return the {@link EnumSet} of {@link StageFlag}s that are mandatory for high tier. */ public EnumSet getHighTier() { return highTier; } /** * @return the {@link EnumSet} of {@link StageFlag}s that are mandatory for mid tier. */ public EnumSet getMidTier() { return midTier; } /** * @return the {@link EnumSet} of {@link StageFlag}s that are mandatory for low tier. */ public EnumSet getLowTier() { return lowTier; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy