44 import org.graalvm.compiler.nodes.calc.ConditionalNode;
45 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
46 import org.graalvm.compiler.nodes.calc.NegateNode;
47 import org.graalvm.compiler.nodes.extended.GuardingNode;
48
49 import jdk.vm.ci.code.CodeUtil;
50 import jdk.vm.ci.meta.DeoptimizationAction;
51 import jdk.vm.ci.meta.DeoptimizationReason;
52 import jdk.vm.ci.meta.SpeculationLog;
53
54 public class CountedLoopInfo {
55
56 private final LoopEx loop;
57 private InductionVariable iv;
58 private ValueNode end;
59 private boolean oneOff;
60 private AbstractBeginNode body;
61 private IfNode ifNode;
62
63 CountedLoopInfo(LoopEx loop, InductionVariable iv, IfNode ifNode, ValueNode end, boolean oneOff, AbstractBeginNode body) {
64 this.loop = loop;
65 this.iv = iv;
66 this.end = end;
67 this.oneOff = oneOff;
68 this.body = body;
69 this.ifNode = ifNode;
70 }
71
72 /**
73 * Returns a node that computes the maximum trip count of this loop. That is the trip count of
74 * this loop assuming it is not exited by an other exit than the {@linkplain #getLimitTest()
75 * count check}.
76 *
77 * This count is exact if {@link #isExactTripCount()} returns true.
78 *
79 * THIS VALUE SHOULD BE TREATED AS UNSIGNED.
80 */
81 public ValueNode maxTripCountNode() {
82 return maxTripCountNode(false);
83 }
140 assert isConstantMaxTripCount();
141 return new UnsignedLong(rawConstantMaxTripCount());
142 }
143
144 /**
145 * Compute the raw value of the trip count for this loop. THIS IS AN UNSIGNED VALUE;
146 */
147 private long rawConstantMaxTripCount() {
148 assert iv.direction() != null;
149 long endValue = end.asJavaConstant().asLong();
150 long initValue = iv.constantInit();
151 long range;
152 long absStride;
153 if (iv.direction() == Direction.Up) {
154 if (endValue < initValue) {
155 return 0;
156 }
157 range = endValue - iv.constantInit();
158 absStride = iv.constantStride();
159 } else {
160 if (initValue < endValue) {
161 return 0;
162 }
163 range = iv.constantInit() - endValue;
164 absStride = -iv.constantStride();
165 }
166 if (oneOff) {
167 range += 1;
168 }
169 long denominator = range + absStride - 1;
170 return Long.divideUnsigned(denominator, absStride);
171 }
172
173 public boolean isExactTripCount() {
174 return loop.loopBegin().loopExits().count() == 1;
175 }
176
177 public ValueNode exactTripCountNode() {
178 assert isExactTripCount();
179 return maxTripCountNode();
|
44 import org.graalvm.compiler.nodes.calc.ConditionalNode;
45 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
46 import org.graalvm.compiler.nodes.calc.NegateNode;
47 import org.graalvm.compiler.nodes.extended.GuardingNode;
48
49 import jdk.vm.ci.code.CodeUtil;
50 import jdk.vm.ci.meta.DeoptimizationAction;
51 import jdk.vm.ci.meta.DeoptimizationReason;
52 import jdk.vm.ci.meta.SpeculationLog;
53
54 public class CountedLoopInfo {
55
56 private final LoopEx loop;
57 private InductionVariable iv;
58 private ValueNode end;
59 private boolean oneOff;
60 private AbstractBeginNode body;
61 private IfNode ifNode;
62
63 CountedLoopInfo(LoopEx loop, InductionVariable iv, IfNode ifNode, ValueNode end, boolean oneOff, AbstractBeginNode body) {
64 assert iv.direction() != null;
65 this.loop = loop;
66 this.iv = iv;
67 this.end = end;
68 this.oneOff = oneOff;
69 this.body = body;
70 this.ifNode = ifNode;
71 }
72
73 /**
74 * Returns a node that computes the maximum trip count of this loop. That is the trip count of
75 * this loop assuming it is not exited by an other exit than the {@linkplain #getLimitTest()
76 * count check}.
77 *
78 * This count is exact if {@link #isExactTripCount()} returns true.
79 *
80 * THIS VALUE SHOULD BE TREATED AS UNSIGNED.
81 */
82 public ValueNode maxTripCountNode() {
83 return maxTripCountNode(false);
84 }
141 assert isConstantMaxTripCount();
142 return new UnsignedLong(rawConstantMaxTripCount());
143 }
144
145 /**
146 * Compute the raw value of the trip count for this loop. THIS IS AN UNSIGNED VALUE;
147 */
148 private long rawConstantMaxTripCount() {
149 assert iv.direction() != null;
150 long endValue = end.asJavaConstant().asLong();
151 long initValue = iv.constantInit();
152 long range;
153 long absStride;
154 if (iv.direction() == Direction.Up) {
155 if (endValue < initValue) {
156 return 0;
157 }
158 range = endValue - iv.constantInit();
159 absStride = iv.constantStride();
160 } else {
161 assert iv.direction() == Direction.Down;
162 if (initValue < endValue) {
163 return 0;
164 }
165 range = iv.constantInit() - endValue;
166 absStride = -iv.constantStride();
167 }
168 if (oneOff) {
169 range += 1;
170 }
171 long denominator = range + absStride - 1;
172 return Long.divideUnsigned(denominator, absStride);
173 }
174
175 public boolean isExactTripCount() {
176 return loop.loopBegin().loopExits().count() == 1;
177 }
178
179 public ValueNode exactTripCountNode() {
180 assert isExactTripCount();
181 return maxTripCountNode();
|