< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/cfg/Loop.java

Print this page

        

*** 23,45 **** package org.graalvm.compiler.core.common.cfg; import java.util.ArrayList; import java.util.List; public abstract class Loop<T extends AbstractBlockBase<T>> { private final Loop<T> parent; ! private final List<Loop<T>> children; private final int depth; private final int index; private final T header; ! private final List<T> blocks; ! private final List<T> exits; protected Loop(Loop<T> parent, int index, T header) { this.parent = parent; if (parent != null) { this.depth = parent.getDepth() + 1; --- 23,54 ---- package org.graalvm.compiler.core.common.cfg; + import static org.graalvm.compiler.core.common.cfg.AbstractBlockBase.BLOCK_ID_COMPARATOR; + import java.util.ArrayList; + import java.util.Collections; import java.util.List; public abstract class Loop<T extends AbstractBlockBase<T>> { private final Loop<T> parent; ! private final ArrayList<Loop<T>> children; private final int depth; private final int index; private final T header; ! private final ArrayList<T> blocks; ! private final ArrayList<T> exits; ! /** ! * Natural exits, ignoring LoopExitNodes. ! * ! * @see #getNaturalExits() ! */ ! private final ArrayList<T> naturalExits; protected Loop(Loop<T> parent, int index, T header) { this.parent = parent; if (parent != null) { this.depth = parent.getDepth() + 1;
*** 49,58 **** --- 58,68 ---- this.index = index; this.header = header; this.blocks = new ArrayList<>(); this.children = new ArrayList<>(); this.exits = new ArrayList<>(); + this.naturalExits = new ArrayList<>(); } public abstract long numBackedges(); @Override
*** 82,97 **** public List<T> getBlocks() { return blocks; } ! public List<T> getExits() { return exits; } ! public void addExit(T t) { ! exits.add(t); } /** * Determines if one loop is a transitive parent of another loop. * --- 92,182 ---- public List<T> getBlocks() { return blocks; } ! /** ! * Returns the loop exits. ! * ! * This might be a conservative set: before framestate assignment it matches the LoopExitNodes ! * even if earlier blocks could be considered as exits. After framestate assignments, this is ! * the same as {@link #getNaturalExits()}. ! * ! * <p> ! * LoopExitNodes are inserted in the control-flow during parsing and are natural exits: they are ! * the earliest block at which we are guaranteed to have exited the loop. However, after some ! * transformations of the graph, the natural exit might go up but the LoopExitNodes are not ! * updated. ! * </p> ! * ! * <p> ! * For example in: ! * ! * <pre> ! * for (int i = 0; i < N; i++) { ! * if (c) { ! * // Block 1 ! * if (dummy) { ! * // ... ! * } else { ! * // ... ! * } ! * if (b) { ! * continue; ! * } else { ! * // Block 2 ! * // LoopExitNode ! * break; ! * } ! * } ! * } ! * </pre> ! * ! * After parsing, the natural exits match the LoopExitNode: Block 2 is a natural exit and has a ! * LoopExitNode. If the {@code b} condition gets canonicalized to {@code false}, the natural ! * exit moves to Block 1 while the LoopExitNode remains in Block 2. In such a scenario, ! * {@code getLoopExits()} will contain block 2 while {@link #getNaturalExits()} will contain ! * block 1. ! * ! * ! * @see #getNaturalExits() ! */ ! public List<T> getLoopExits() { return exits; } ! public boolean isLoopExit(T block) { ! assert isSorted(exits); ! return Collections.binarySearch(exits, block, BLOCK_ID_COMPARATOR) >= 0; ! } ! ! /** ! * Returns the natural exit points: these are the earliest block that are guaranteed to never ! * reach a back-edge. ! * ! * This can not be used in the context of preserving or using loop-closed form. ! * ! * @see #getLoopExits() ! */ ! public ArrayList<T> getNaturalExits() { ! return naturalExits; ! } ! ! public boolean isNaturalExit(T block) { ! assert isSorted(naturalExits); ! return Collections.binarySearch(naturalExits, block, BLOCK_ID_COMPARATOR) >= 0; ! } ! ! private static <T extends AbstractBlockBase<T>> boolean isSorted(List<T> list) { ! int lastId = Integer.MIN_VALUE; ! for (AbstractBlockBase<?> block : list) { ! if (block.getId() < lastId) { ! return false; ! } ! lastId = block.getId(); ! } ! return true; } /** * Determines if one loop is a transitive parent of another loop. *
*** 113,118 **** --- 198,208 ---- @Override public int hashCode() { return index + depth * 31; } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } }
< prev index next >