77
77
import jdk .graal .compiler .nodes .debug .NeverStripMineNode ;
78
78
import jdk .graal .compiler .nodes .debug .NeverWriteSinkNode ;
79
79
import jdk .graal .compiler .nodes .extended .ValueAnchorNode ;
80
+ import jdk .graal .compiler .nodes .loop .InductionVariable .Direction ;
80
81
import jdk .graal .compiler .nodes .util .GraphUtil ;
81
82
import jdk .graal .compiler .phases .common .CanonicalizerPhase ;
82
83
@@ -316,17 +317,17 @@ public boolean detectCounted() {
316
317
}
317
318
CompareNode compare = (CompareNode ) ifTest ;
318
319
Condition condition = null ;
319
- InductionVariable iv = null ;
320
+ InductionVariable limitCheckedIV = null ;
320
321
ValueNode limit = null ;
321
322
if (isOutsideLoop (compare .getX ())) {
322
- iv = getInductionVariables ().get (compare .getY ());
323
- if (iv != null ) {
323
+ limitCheckedIV = getInductionVariables ().get (compare .getY ());
324
+ if (limitCheckedIV != null ) {
324
325
condition = compare .condition ().asCondition ().mirror ();
325
326
limit = compare .getX ();
326
327
}
327
328
} else if (isOutsideLoop (compare .getY ())) {
328
- iv = getInductionVariables ().get (compare .getX ());
329
- if (iv != null ) {
329
+ limitCheckedIV = getInductionVariables ().get (compare .getX ());
330
+ if (limitCheckedIV != null ) {
330
331
condition = compare .condition ().asCondition ();
331
332
limit = compare .getY ();
332
333
}
@@ -337,35 +338,40 @@ public boolean detectCounted() {
337
338
if (negated ) {
338
339
condition = condition .negate ();
339
340
}
341
+ final Direction limitCheckedIVDirection = limitCheckedIV .direction ();
342
+ if (limitCheckedIVDirection == null ) {
343
+ // we do not know which direction the stride goes
344
+ return false ;
345
+ }
340
346
boolean isLimitIncluded = false ;
341
347
boolean unsigned = false ;
342
348
switch (condition ) {
343
349
case EQ :
344
- if (iv .initNode () == limit ) {
350
+ if (limitCheckedIV .initNode () == limit ) {
345
351
// allow "single iteration" case
346
352
isLimitIncluded = true ;
347
353
} else {
348
354
return false ;
349
355
}
350
356
break ;
351
357
case NE : {
352
- IntegerStamp initStamp = (IntegerStamp ) iv .initNode ().stamp (NodeView .DEFAULT );
358
+ IntegerStamp initStamp = (IntegerStamp ) limitCheckedIV .initNode ().stamp (NodeView .DEFAULT );
353
359
IntegerStamp limitStamp = (IntegerStamp ) limit .stamp (NodeView .DEFAULT );
354
- IntegerStamp counterStamp = (IntegerStamp ) iv .valueNode ().stamp (NodeView .DEFAULT );
355
- if (iv . direction () == InductionVariable .Direction .Up ) {
360
+ IntegerStamp counterStamp = (IntegerStamp ) limitCheckedIV .valueNode ().stamp (NodeView .DEFAULT );
361
+ if (limitCheckedIVDirection == InductionVariable .Direction .Up ) {
356
362
if (limitStamp .asConstant () != null && limitStamp .asConstant ().asLong () == counterStamp .upperBound ()) {
357
363
// signed: i < MAX_INT
358
364
} else if (limitStamp .asConstant () != null && limitStamp .asConstant ().asLong () == counterStamp .unsignedUpperBound () && IntegerStamp .sameSign (initStamp , limitStamp )) {
359
365
unsigned = true ;
360
- } else if (!iv .isConstantStride () || !absStrideIsOne (iv ) || initStamp .upperBound () > limitStamp .lowerBound ()) {
366
+ } else if (!limitCheckedIV .isConstantStride () || !absStrideIsOne (limitCheckedIV ) || initStamp .upperBound () > limitStamp .lowerBound ()) {
361
367
return false ;
362
368
}
363
- } else if (iv . direction () == InductionVariable .Direction .Down ) {
369
+ } else if (limitCheckedIVDirection == InductionVariable .Direction .Down ) {
364
370
if (limitStamp .asConstant () != null && limitStamp .asConstant ().asLong () == counterStamp .lowerBound ()) {
365
371
// signed: MIN_INT > i
366
372
} else if (limitStamp .asConstant () != null && limitStamp .asConstant ().asLong () == counterStamp .unsignedLowerBound () && IntegerStamp .sameSign (initStamp , limitStamp )) {
367
373
unsigned = true ;
368
- } else if (!iv .isConstantStride () || !absStrideIsOne (iv ) || initStamp .lowerBound () < limitStamp .upperBound ()) {
374
+ } else if (!limitCheckedIV .isConstantStride () || !absStrideIsOne (limitCheckedIV ) || initStamp .lowerBound () < limitStamp .upperBound ()) {
369
375
return false ;
370
376
}
371
377
} else {
@@ -377,36 +383,36 @@ public boolean detectCounted() {
377
383
unsigned = true ; // fall through
378
384
case LE :
379
385
isLimitIncluded = true ;
380
- if (iv .direction () != InductionVariable .Direction .Up ) {
386
+ if (limitCheckedIV .direction () != InductionVariable .Direction .Up ) {
381
387
return false ;
382
388
}
383
389
break ;
384
390
case BT :
385
391
unsigned = true ; // fall through
386
392
case LT :
387
- if (iv .direction () != InductionVariable .Direction .Up ) {
393
+ if (limitCheckedIV .direction () != InductionVariable .Direction .Up ) {
388
394
return false ;
389
395
}
390
396
break ;
391
397
case AE :
392
398
unsigned = true ; // fall through
393
399
case GE :
394
400
isLimitIncluded = true ;
395
- if (iv .direction () != InductionVariable .Direction .Down ) {
401
+ if (limitCheckedIV .direction () != InductionVariable .Direction .Down ) {
396
402
return false ;
397
403
}
398
404
break ;
399
405
case AT :
400
406
unsigned = true ; // fall through
401
407
case GT :
402
- if (iv .direction () != InductionVariable .Direction .Down ) {
408
+ if (limitCheckedIV .direction () != InductionVariable .Direction .Down ) {
403
409
return false ;
404
410
}
405
411
break ;
406
412
default :
407
413
throw GraalError .shouldNotReachHere (condition .toString ()); // ExcludeFromJacocoGeneratedReport
408
414
}
409
- counted = new CountedLoopInfo (this , iv , ifNode , limit , isLimitIncluded , negated ? ifNode .falseSuccessor () : ifNode .trueSuccessor (), unsigned );
415
+ counted = new CountedLoopInfo (this , limitCheckedIV , ifNode , limit , isLimitIncluded , negated ? ifNode .falseSuccessor () : ifNode .trueSuccessor (), unsigned );
410
416
return true ;
411
417
}
412
418
return false ;
0 commit comments