Skip to content

Commit d010114

Browse files
committed
Type inference: Performance tweaks
1 parent 7a367c9 commit d010114

1 file changed

Lines changed: 84 additions & 21 deletions

File tree

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,30 +1261,58 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12611261
module MatchingWithEnvironment<MatchingWithEnvironmentInputSig Input> {
12621262
private import Input
12631263

1264+
private Type getTypeArgumentNonPseudo(Access a, int pos, TypePath path) {
1265+
result = a.getTypeArgument(pos, path) and
1266+
not result instanceof PseudoType
1267+
}
1268+
12641269
/**
12651270
* Gets the type of the type argument at `path` in `a` that corresponds to
12661271
* the type parameter `tp` in `target`, if any.
12671272
*
12681273
* Note that this predicate crucially does not depend on type inference,
1269-
* and hence can appear in negated position, e.g., as in
1270-
* `directTypeMatch`.
1274+
* and hence can appear in negated position, e.g., as in `directTypeMatch`.
12711275
*/
12721276
bindingset[a, target]
12731277
pragma[inline_late]
12741278
Type getTypeArgument(Access a, Declaration target, TypeParameter tp, TypePath path) {
12751279
exists(int pos |
1276-
result = a.getTypeArgument(pos, path) and
1277-
tp = target.getTypeParameter(pos) and
1278-
not result instanceof PseudoType
1280+
result = getTypeArgumentNonPseudo(a, pos, path) and
1281+
tp = target.getTypeParameter(pos)
1282+
)
1283+
}
1284+
1285+
bindingset[a, target]
1286+
pragma[inline_late]
1287+
private predicate hasNotTypeArgument0(Access a, Declaration target, TypeParameter tp) {
1288+
exists(int pos |
1289+
tp = target.getTypeParameter(pragma[only_bind_into](pos)) and
1290+
not exists(getTypeArgumentNonPseudo(a, pos, _))
12791291
)
12801292
}
12811293

1294+
bindingset[target, tp]
1295+
pragma[inline_late]
1296+
private predicate hasNotTypeArgument1(Declaration target, TypeParameter tp) {
1297+
not tp = target.getTypeParameter(_)
1298+
}
1299+
1300+
/**
1301+
* A join-order optimized version of `not exists(getTypeArgument(a, target, tp, _)`.
1302+
*/
1303+
pragma[inline]
1304+
private predicate hasNotTypeArgument(Access a, Declaration target, TypeParameter tp) {
1305+
hasNotTypeArgument0(a, target, tp)
1306+
or
1307+
hasNotTypeArgument1(target, tp)
1308+
}
1309+
12821310
pragma[nomagic]
12831311
private predicate directTypeMatch0(
12841312
Access a, DeclarationPosition dpos, AccessEnvironment e, Declaration target,
12851313
TypePath pathToTypeParam, TypeParameter tp
12861314
) {
1287-
not exists(getTypeArgument(a, target, tp, _)) and
1315+
hasNotTypeArgument(a, target, tp) and
12881316
tp = target.getDeclaredType(dpos, pathToTypeParam) and
12891317
target = a.getTarget(e)
12901318
}
@@ -1359,12 +1387,18 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13591387
t = a.getInferredType(e, apos, TypePath::nil())
13601388
}
13611389

1390+
private predicate relevantAccessTarget(
1391+
Access a, AccessPosition apos, AccessEnvironment e, Declaration target
1392+
) {
1393+
exists(Type t |
1394+
accessTargetsWithArgRootType(a, e, target, apos, t) and
1395+
argRootTypeSatisfiesTargetTypeCand(t, target, apos, _, _)
1396+
)
1397+
}
1398+
13621399
private newtype TRelevantAccess =
13631400
MkRelevantAccess(Access a, AccessPosition apos, AccessEnvironment e) {
1364-
exists(Declaration target, Type t |
1365-
accessTargetsWithArgRootType(a, e, target, apos, t) and
1366-
argRootTypeSatisfiesTargetTypeCand(t, target, apos, _, _)
1367-
)
1401+
relevantAccessTarget(a, apos, e, _)
13681402
}
13691403

13701404
private class RelevantAccess extends MkRelevantAccess {
@@ -1374,7 +1408,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13741408

13751409
RelevantAccess() { this = MkRelevantAccess(a, apos, e) }
13761410

1377-
RelevantTarget getTarget() { result = MkRelevantTarget(a.getTarget(e), apos) }
1411+
RelevantTarget getTarget() {
1412+
exists(Declaration target |
1413+
relevantAccessTarget(a, apos, e, target) and
1414+
result = MkRelevantTarget(target, apos)
1415+
)
1416+
}
13781417

13791418
pragma[nomagic]
13801419
Type getTypeAt(TypePath path) { result = a.getInferredType(e, apos, path) }
@@ -1431,13 +1470,23 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
14311470
predicate baseTypeMatch(
14321471
Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp
14331472
) {
1434-
exists(AccessPosition apos, TypePath pathToTp |
1435-
argRootTypeSatisfiesTargetTypeCand(_, target, pragma[only_bind_into](apos), tp, pathToTp) and
1473+
exists(AccessPosition apos, TypePath pathToTp, TypePath pathFull, string regexp |
14361474
SatisfiesParameterConstraint::satisfiesConstraint(MkRelevantAccess(a,
14371475
pragma[only_bind_into](apos), e),
1438-
MkRelevantTarget(target, pragma[only_bind_into](apos)), pathToTp.appendInverse(path),
1439-
t) and
1440-
not exists(getTypeArgument(a, target, tp, _))
1476+
MkRelevantTarget(target, pragma[only_bind_into](apos)), pathFull, t) and
1477+
// In order to prevent fan-out in the subsequent inverse append below, first
1478+
// pin down `pathToTp` using a single regex match
1479+
regexp =
1480+
"(" +
1481+
strictconcat(TypePath pathToTp0 |
1482+
argRootTypeSatisfiesTargetTypeCand(_, target, apos, _, pathToTp0)
1483+
|
1484+
pathToTp0.replaceAll(".", "\\."), "|"
1485+
) + ").*" and
1486+
pathToTp = pathFull.regexpCapture(regexp, 1) and
1487+
pathFull = pathToTp.appendInverse(path) and
1488+
argRootTypeSatisfiesTargetTypeCand(_, target, pragma[only_bind_into](apos), tp, pathToTp) and
1489+
hasNotTypeArgument(a, target, tp)
14411490
)
14421491
}
14431492
}
@@ -1595,11 +1644,25 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15951644
private predicate typeConstraintBaseTypeMatch(
15961645
Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp
15971646
) {
1598-
not exists(getTypeArgument(a, target, tp, _)) and
1599-
exists(TypeMention constraint, TypeParameter constrainedTp, TypePath pathToTp |
1600-
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, tp) and
1601-
AccessConstraint::satisfiesConstraint(a, e, target, constrainedTp, constraint,
1602-
pathToTp.appendInverse(path), t)
1647+
hasNotTypeArgument(a, target, tp) and
1648+
exists(
1649+
TypeParameter constrainedTp, TypeMention constraint, TypePath pathToTp, TypePath pathFull,
1650+
string regexp
1651+
|
1652+
AccessConstraint::satisfiesConstraint(a, e, target, constrainedTp, constraint, pathFull, t) and
1653+
// In order to prevent fan-out in the subsequent inverse append below, first
1654+
// pin down `pathToTp` using a single regex match
1655+
regexp =
1656+
"(" +
1657+
strictconcat(TypePath pathToTp0 |
1658+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint,
1659+
pathToTp0, _)
1660+
|
1661+
pathToTp0.replaceAll(".", "\\."), "|"
1662+
) + ").*" and
1663+
pathToTp = pathFull.regexpCapture(regexp, 1) and
1664+
pathFull = pathToTp.appendInverse(path) and
1665+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, tp)
16031666
)
16041667
}
16051668

0 commit comments

Comments
 (0)