Skip to content

Commit c32c4bb

Browse files
authored
Merge pull request github#14086 from hvitved/csharp/perf-fixes
C#: Various performance fixes
2 parents 39b45fa + 7611bfb commit c32c4bb

File tree

5 files changed

+53
-29
lines changed

5 files changed

+53
-29
lines changed

csharp/ql/lib/semmle/code/csharp/Unification.qll

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -538,23 +538,26 @@ module Unification {
538538
*
539539
* Note: This predicate is inlined.
540540
*/
541-
bindingset[t]
541+
bindingset[this]
542+
pragma[inline_late]
542543
predicate unifiable(Type t) { none() }
543544

544545
/**
545546
* Holds if this type parameter subsumes type `t`
546547
*
547548
* Note: This predicate is inlined.
548549
*/
549-
bindingset[t]
550+
bindingset[this]
551+
pragma[inline_late]
550552
predicate subsumes(Type t) { none() }
551553
}
552554

553555
/** A type parameter that has a single constraint. */
554556
private class SingleConstraintTypeParameter extends ConstrainedTypeParameter {
555557
SingleConstraintTypeParameter() { constraintCount = 1 }
556558

557-
bindingset[t]
559+
bindingset[this]
560+
pragma[inline_late]
558561
override predicate unifiable(Type t) {
559562
exists(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) |
560563
ttc = TRefTypeConstraint() and
@@ -567,7 +570,8 @@ module Unification {
567570
)
568571
}
569572

570-
bindingset[t]
573+
bindingset[this]
574+
pragma[inline_late]
571575
override predicate subsumes(Type t) {
572576
exists(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) |
573577
ttc = TRefTypeConstraint() and
@@ -585,9 +589,13 @@ module Unification {
585589
private class MultiConstraintTypeParameter extends ConstrainedTypeParameter {
586590
MultiConstraintTypeParameter() { constraintCount > 1 }
587591

588-
bindingset[t]
592+
pragma[nomagic]
593+
TTypeParameterConstraint getATypeConstraint() { result = getATypeConstraint(this) }
594+
595+
bindingset[this]
596+
pragma[inline_late]
589597
override predicate unifiable(Type t) {
590-
forex(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) |
598+
forex(TTypeParameterConstraint ttc | ttc = this.getATypeConstraint() |
591599
ttc = TRefTypeConstraint() and
592600
t.isRefType()
593601
or
@@ -598,9 +606,10 @@ module Unification {
598606
)
599607
}
600608

601-
bindingset[t]
609+
bindingset[this]
610+
pragma[inline_late]
602611
override predicate subsumes(Type t) {
603-
forex(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) |
612+
forex(TTypeParameterConstraint ttc | ttc = this.getATypeConstraint() |
604613
ttc = TRefTypeConstraint() and
605614
t.isRefType()
606615
or

csharp/ql/lib/semmle/code/csharp/commons/Assertions.qll

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ class NUnitAssertNonNullMethod extends NullnessAssertMethod, NUnitAssertMethod {
299299
override int getAnAssertionIndex(boolean b) { result = this.getAnAssertionIndex() and b = false }
300300
}
301301

302+
pragma[nomagic]
303+
private predicate parameterAssertion(Assertion a, int index, Parameter p) {
304+
strictcount(AssignableDefinition def | def.getTarget() = p) = 1 and
305+
a.getExpr(index) = p.getAnAccess()
306+
}
307+
302308
/** A method that forwards to another assertion method. */
303309
class ForwarderAssertMethod extends AssertMethod {
304310
private Assertion a;
@@ -307,10 +313,9 @@ class ForwarderAssertMethod extends AssertMethod {
307313

308314
ForwarderAssertMethod() {
309315
p = this.getAParameter() and
310-
strictcount(AssignableDefinition def | def.getTarget() = p) = 1 and
311316
forex(ControlFlowElement body | body = this.getBody() |
312317
bodyAsserts(this, body, a) and
313-
a.getExpr(forwarderIndex) = p.getAnAccess()
318+
parameterAssertion(a, forwarderIndex, p)
314319
)
315320
}
316321

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,7 @@ private predicate adjacentDefReachesUncertainRead(
11591159
)
11601160
}
11611161

1162+
pragma[nomagic]
11621163
private predicate adjacentDefReachesUncertainReadExt(
11631164
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
11641165
) {

csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,7 @@ private module Internal {
862862
or
863863
Unification::subsumes(t, qualifierType)
864864
or
865-
t.(Unification::ConstrainedTypeParameter).unifiable(qualifierType)
866-
or
867-
qualifierType = t.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType()
865+
qualifierType = t.(TypeParameter).getAnUltimatelySuppliedType()
868866
)
869867
}
870868

shared/controlflow/codeql/controlflow/Cfg.qll

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -399,13 +399,20 @@ module Make<LocationSig Location, InputSig<Location> Input> {
399399
}
400400
}
401401

402+
private predicate isFullyConstructedSplits(Splits splits) { exists(TAstNode(_, _, splits)) }
403+
402404
/**
403405
* A set of control flow node splits. The set is represented by a list of splits,
404406
* ordered by ascending rank.
405407
*/
406408
class Splits extends TSplits {
407409
/** Gets a textual representation of this set of splits. */
408-
string toString() { result = splitsToString(this) }
410+
string toString() {
411+
result = splitsToString(this)
412+
or
413+
not isFullyConstructedSplits(this) and
414+
result = "<partial split set>"
415+
}
409416

410417
/** Gets a split belonging to this set of splits. */
411418
SplitImpl getASplit() {
@@ -857,23 +864,27 @@ module Make<LocationSig Location, InputSig<Location> Input> {
857864
succEntrySplitsCons(_, _, head, tail, _)
858865
}
859866

867+
private string getSplitStringAt(Splits split, int index) {
868+
exists(SplitImpl head, Splits tail | split = TSplitsCons(head, tail) |
869+
index = 0 and result = head.toString() and result != ""
870+
or
871+
index > 0 and result = getSplitStringAt(tail, index - 1)
872+
)
873+
}
874+
875+
private string getSplitsStringPart(Splits splits, int index) {
876+
isFullyConstructedSplits(splits) and
877+
result = getSplitStringAt(splits, index)
878+
}
879+
860880
cached
861881
string splitsToString(Splits splits) {
862-
splits = TSplitsNil() and
863-
result = ""
864-
or
865-
exists(SplitImpl head, Splits tail, string headString, string tailString |
866-
splits = TSplitsCons(head, tail)
867-
|
868-
headString = head.toString() and
869-
tailString = tail.toString() and
870-
if tailString = ""
871-
then result = headString
872-
else
873-
if headString = ""
874-
then result = tailString
875-
else result = headString + ", " + tailString
876-
)
882+
result =
883+
concat(string child, int index |
884+
child = getSplitsStringPart(splits, index)
885+
|
886+
child, ", " order by index
887+
)
877888
}
878889

879890
/**

0 commit comments

Comments
 (0)