36 import org.graalvm.compiler.nodeinfo.InputType;
37 import org.graalvm.compiler.nodeinfo.NodeInfo;
38 import org.graalvm.compiler.nodes.calc.AddNode;
39 import org.graalvm.compiler.nodes.extended.GuardingNode;
40 import org.graalvm.compiler.nodes.spi.LIRLowerable;
41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
42 import org.graalvm.compiler.nodes.util.GraphUtil;
43
44 @NodeInfo
45 public final class LoopBeginNode extends AbstractMergeNode implements IterableNodeType, LIRLowerable {
46
47 public static final NodeClass<LoopBeginNode> TYPE = NodeClass.create(LoopBeginNode.class);
48 protected double loopFrequency;
49 protected double loopOrigFrequency;
50 protected int nextEndIndex;
51 protected int unswitches;
52 protected int splits;
53 protected int inversionCount;
54 protected LoopType loopType;
55 protected int unrollFactor;
56
57 public enum LoopType {
58 SIMPLE_LOOP,
59 PRE_LOOP,
60 MAIN_LOOP,
61 POST_LOOP
62 }
63
64 /** See {@link LoopEndNode#canSafepoint} for more information. */
65 boolean canEndsSafepoint;
66
67 @OptionalInput(InputType.Guard) GuardingNode overflowGuard;
68
69 public LoopBeginNode() {
70 super(TYPE);
71 loopFrequency = 1;
72 loopOrigFrequency = 1;
73 unswitches = 0;
74 splits = 0;
75 this.canEndsSafepoint = true;
286 unswitches++;
287 }
288
289 public int getInversionCount() {
290 return inversionCount;
291 }
292
293 public void setInversionCount(int count) {
294 inversionCount = count;
295 }
296
297 @Override
298 public void simplify(SimplifierTool tool) {
299 canonicalizePhis(tool);
300 }
301
302 public boolean isLoopExit(AbstractBeginNode begin) {
303 return begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == this;
304 }
305
306 public LoopExitNode getSingleLoopExit() {
307 assert loopExits().count() == 1;
308 return loopExits().first();
309 }
310
311 public LoopEndNode getSingleLoopEnd() {
312 assert loopEnds().count() == 1;
313 return loopEnds().first();
314 }
315
316 @SuppressWarnings("try")
317 public void removeExits() {
318 for (LoopExitNode loopexit : loopExits().snapshot()) {
319 try (DebugCloseable position = graph().withNodeSourcePosition(loopexit)) {
320 loopexit.removeProxies();
321 FrameState loopStateAfter = loopexit.stateAfter();
322 graph().replaceFixedWithFixed(loopexit, graph().add(new BeginNode()));
323 if (loopStateAfter != null) {
324 GraphUtil.tryKillUnused(loopStateAfter);
325 }
326 }
327 }
328 }
329
330 public GuardingNode getOverflowGuard() {
331 return overflowGuard;
332 }
333
334 public void setOverflowGuard(GuardingNode overflowGuard) {
335 updateUsagesInterface(this.overflowGuard, overflowGuard);
336 this.overflowGuard = overflowGuard;
337 }
338
339 private static final int NO_INCREMENT = Integer.MIN_VALUE;
340
341 /**
342 * Returns an array with one entry for each input of the phi, which is either
343 * {@link #NO_INCREMENT} or the increment, i.e., the value by which the phi is incremented in
344 * the corresponding branch.
345 */
397 for (int inputIndex = 0; inputIndex < phiInputCount; inputIndex++) {
398 if (phiIncrement[inputIndex] == NO_INCREMENT) {
399 if (phi.valueAt(inputIndex) != otherPhi.valueAt(inputIndex)) {
400 continue nextPhi;
401 }
402 }
403 if (phiIncrement[inputIndex] != otherPhiIncrement[inputIndex]) {
404 continue nextPhi;
405 }
406 }
407 if (tool != null) {
408 tool.addToWorkList(otherPhi.usages());
409 }
410 otherPhi.replaceAtUsages(phi);
411 GraphUtil.killWithUnusedFloatingInputs(otherPhi);
412 phis[otherPhiIndex] = null;
413 }
414 }
415 }
416 }
417 }
418 }
|
36 import org.graalvm.compiler.nodeinfo.InputType;
37 import org.graalvm.compiler.nodeinfo.NodeInfo;
38 import org.graalvm.compiler.nodes.calc.AddNode;
39 import org.graalvm.compiler.nodes.extended.GuardingNode;
40 import org.graalvm.compiler.nodes.spi.LIRLowerable;
41 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
42 import org.graalvm.compiler.nodes.util.GraphUtil;
43
44 @NodeInfo
45 public final class LoopBeginNode extends AbstractMergeNode implements IterableNodeType, LIRLowerable {
46
47 public static final NodeClass<LoopBeginNode> TYPE = NodeClass.create(LoopBeginNode.class);
48 protected double loopFrequency;
49 protected double loopOrigFrequency;
50 protected int nextEndIndex;
51 protected int unswitches;
52 protected int splits;
53 protected int inversionCount;
54 protected LoopType loopType;
55 protected int unrollFactor;
56 protected boolean osrLoop;
57
58 public enum LoopType {
59 SIMPLE_LOOP,
60 PRE_LOOP,
61 MAIN_LOOP,
62 POST_LOOP
63 }
64
65 /** See {@link LoopEndNode#canSafepoint} for more information. */
66 boolean canEndsSafepoint;
67
68 @OptionalInput(InputType.Guard) GuardingNode overflowGuard;
69
70 public LoopBeginNode() {
71 super(TYPE);
72 loopFrequency = 1;
73 loopOrigFrequency = 1;
74 unswitches = 0;
75 splits = 0;
76 this.canEndsSafepoint = true;
287 unswitches++;
288 }
289
290 public int getInversionCount() {
291 return inversionCount;
292 }
293
294 public void setInversionCount(int count) {
295 inversionCount = count;
296 }
297
298 @Override
299 public void simplify(SimplifierTool tool) {
300 canonicalizePhis(tool);
301 }
302
303 public boolean isLoopExit(AbstractBeginNode begin) {
304 return begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == this;
305 }
306
307 public LoopEndNode getSingleLoopEnd() {
308 assert loopEnds().count() == 1;
309 return loopEnds().first();
310 }
311
312 @SuppressWarnings("try")
313 public void removeExits() {
314 for (LoopExitNode loopexit : loopExits().snapshot()) {
315 try (DebugCloseable position = graph().withNodeSourcePosition(loopexit)) {
316 loopexit.removeExit();
317 }
318 }
319 }
320
321 public GuardingNode getOverflowGuard() {
322 return overflowGuard;
323 }
324
325 public void setOverflowGuard(GuardingNode overflowGuard) {
326 updateUsagesInterface(this.overflowGuard, overflowGuard);
327 this.overflowGuard = overflowGuard;
328 }
329
330 private static final int NO_INCREMENT = Integer.MIN_VALUE;
331
332 /**
333 * Returns an array with one entry for each input of the phi, which is either
334 * {@link #NO_INCREMENT} or the increment, i.e., the value by which the phi is incremented in
335 * the corresponding branch.
336 */
388 for (int inputIndex = 0; inputIndex < phiInputCount; inputIndex++) {
389 if (phiIncrement[inputIndex] == NO_INCREMENT) {
390 if (phi.valueAt(inputIndex) != otherPhi.valueAt(inputIndex)) {
391 continue nextPhi;
392 }
393 }
394 if (phiIncrement[inputIndex] != otherPhiIncrement[inputIndex]) {
395 continue nextPhi;
396 }
397 }
398 if (tool != null) {
399 tool.addToWorkList(otherPhi.usages());
400 }
401 otherPhi.replaceAtUsages(phi);
402 GraphUtil.killWithUnusedFloatingInputs(otherPhi);
403 phis[otherPhiIndex] = null;
404 }
405 }
406 }
407 }
408 }
409
410 public void markOsrLoop() {
411 osrLoop = true;
412 }
413
414 public boolean isOsrLoop() {
415 return osrLoop;
416 }
417 }
|