Skip to content

Commit 594dfc9

Browse files
committed
Type inference: Performance tweaks
1 parent b6a9b20 commit 594dfc9

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
@@ -1262,30 +1262,58 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12621262
module MatchingWithEnvironment<MatchingWithEnvironmentInputSig Input> {
12631263
private import Input
12641264

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

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

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

13711405
private class RelevantAccess extends MkRelevantAccess {
@@ -1375,7 +1409,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13751409

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

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

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

0 commit comments

Comments
 (0)