|
40 | 40 | */
|
41 | 41 | package com.oracle.truffle.regex.tregex.parser.ast.visitors;
|
42 | 42 |
|
| 43 | +import static com.oracle.truffle.regex.tregex.util.MathUtil.saturatingInc; |
| 44 | + |
43 | 45 | import java.util.Arrays;
|
44 | 46 | import java.util.Set;
|
45 | 47 |
|
@@ -1214,13 +1216,8 @@ private void pushTransitionGuard(long guard) {
|
1214 | 1216 | case countSet1, countSetMin -> {
|
1215 | 1217 | bqLastCounterReset[TransitionGuard.getQuantifierIndex(guard)] = transitionGuards.length();
|
1216 | 1218 | }
|
1217 |
| - case countLtMin, countGeMin -> { |
1218 |
| - if (canOmitCounterMinCheck(guard)) { |
1219 |
| - return; |
1220 |
| - } |
1221 |
| - } |
1222 |
| - case countLtMax -> { |
1223 |
| - if (canOmitCounterMaxCheck(guard)) { |
| 1219 | + case countLtMin, countGeMin, countLtMax -> { |
| 1220 | + if (canOmitCounterCheck(guard)) { |
1224 | 1221 | return;
|
1225 | 1222 | }
|
1226 | 1223 | }
|
@@ -1298,47 +1295,74 @@ private void pushTransitionGuard(long guard) {
|
1298 | 1295 | transitionGuards.add(guard);
|
1299 | 1296 | }
|
1300 | 1297 |
|
1301 |
| - private boolean canOmitCounterMinCheck(long guard) { |
1302 |
| - assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countGeMin); |
| 1298 | + private boolean canOmitCounterCheck(long guard) { |
| 1299 | + assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countGeMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countLtMax); |
1303 | 1300 | int quantifierIndex = TransitionGuard.getQuantifierIndex(guard);
|
| 1301 | + int min = ast.getQuantifier(quantifierIndex).getMin(); |
| 1302 | + int max = ast.getQuantifier(quantifierIndex).getMax(); |
| 1303 | + int minPlus1 = saturatingInc(min); |
| 1304 | + |
| 1305 | + long countLtMin = TransitionGuard.createCountLtMin(quantifierIndex); |
| 1306 | + long countGeMin = TransitionGuard.createCountGeMin(quantifierIndex); |
| 1307 | + long countLtMax = TransitionGuard.createCountLtMax(quantifierIndex); |
1304 | 1308 | long countInc = TransitionGuard.createCountInc(quantifierIndex);
|
1305 | 1309 | long countSetMin = TransitionGuard.createCountSetMin(quantifierIndex);
|
1306 |
| - boolean isLtMin = TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin); |
1307 |
| - long inverseGuard = isLtMin ? TransitionGuard.createCountGeMin(quantifierIndex) : TransitionGuard.createCountLtMin(quantifierIndex); |
1308 |
| - boolean omit = false; |
1309 |
| - boolean existingIsSetMin = false; |
| 1310 | + long countSet1 = TransitionGuard.createCountSet1(quantifierIndex); |
| 1311 | + |
| 1312 | + int counterLow = 0; |
| 1313 | + int counterHigh = Integer.MAX_VALUE; |
1310 | 1314 | for (long existingGuard : transitionGuards) {
|
1311 |
| - if (existingGuard == countSetMin) { |
1312 |
| - existingIsSetMin = true; |
1313 |
| - } |
1314 |
| - if (existingGuard == guard) { |
1315 |
| - omit = true; |
1316 |
| - } |
1317 |
| - if (existingGuard == countInc && !(!isLtMin && existingIsSetMin)) { |
1318 |
| - omit = false; |
1319 |
| - } |
1320 |
| - if (existingGuard == inverseGuard || isLtMin && existingIsSetMin) { |
1321 |
| - setShouldRetreat(); |
1322 |
| - return true; |
| 1315 | + if (existingGuard == countLtMin) { |
| 1316 | + counterHigh = Math.min(counterHigh, min - 1); |
| 1317 | + } else if (existingGuard == countGeMin) { |
| 1318 | + counterLow = Math.max(counterLow, min); |
| 1319 | + } else if (existingGuard == countLtMax) { |
| 1320 | + counterHigh = Math.min(counterHigh, max - 1); |
| 1321 | + } else if (existingGuard == countSetMin) { |
| 1322 | + counterLow = minPlus1; |
| 1323 | + counterHigh = minPlus1; |
| 1324 | + } else if (existingGuard == countSet1) { |
| 1325 | + counterLow = 1; |
| 1326 | + counterHigh = 1; |
| 1327 | + } else if (existingGuard == countInc) { |
| 1328 | + counterLow = saturatingInc(counterLow); |
| 1329 | + counterHigh = saturatingInc(counterHigh); |
1323 | 1330 | }
|
1324 | 1331 | }
|
1325 |
| - return omit; |
1326 |
| - } |
1327 | 1332 |
|
1328 |
| - private boolean canOmitCounterMaxCheck(long guard) { |
1329 |
| - assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMax); |
1330 |
| - int quantifierIndex = TransitionGuard.getQuantifierIndex(guard); |
1331 |
| - long countInc = TransitionGuard.createCountInc(quantifierIndex); |
1332 |
| - boolean omit = false; |
1333 |
| - for (long existingGuard : transitionGuards) { |
1334 |
| - if (existingGuard == guard) { |
1335 |
| - omit = true; |
| 1333 | + switch (TransitionGuard.getKind(guard)) { |
| 1334 | + case countLtMin -> { |
| 1335 | + if (counterHigh < min) { |
| 1336 | + return true; |
| 1337 | + } else if (counterLow >= min) { |
| 1338 | + setShouldRetreat(); |
| 1339 | + return true; |
| 1340 | + } else { |
| 1341 | + return false; |
| 1342 | + } |
| 1343 | + } |
| 1344 | + case countLtMax -> { |
| 1345 | + if (counterHigh < max) { |
| 1346 | + return true; |
| 1347 | + } else if (counterLow >= max) { |
| 1348 | + setShouldRetreat(); |
| 1349 | + return true; |
| 1350 | + } else { |
| 1351 | + return false; |
| 1352 | + } |
1336 | 1353 | }
|
1337 |
| - if (existingGuard == countInc) { |
1338 |
| - omit = false; |
| 1354 | + case countGeMin -> { |
| 1355 | + if (counterLow >= min) { |
| 1356 | + return true; |
| 1357 | + } else if (counterHigh < min) { |
| 1358 | + setShouldRetreat(); |
| 1359 | + return true; |
| 1360 | + } else { |
| 1361 | + return false; |
| 1362 | + } |
1339 | 1363 | }
|
| 1364 | + default -> throw CompilerDirectives.shouldNotReachHere(); |
1340 | 1365 | }
|
1341 |
| - return omit; |
1342 | 1366 | }
|
1343 | 1367 |
|
1344 | 1368 | /// Visited set management
|
|
0 commit comments