mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Avoids an expensive anti-join:
```
[2023-08-29 15:25:48] Evaluated non-recursive predicate _FileSystem#df18ed9a::Make#File#1a556f64::Input#::Container::toString#0#dispred#bf_Method#621e9e2e::__#antijoin_rhs@96d08bc8 in 272332ms (size: 1841891).
Evaluated relational algebra for predicate _FileSystem#df18ed9a::Make#File#1a556f64::Input#::Container::toString#0#dispred#bf_Method#621e9e2e::__#antijoin_rhs@96d08bc8 with tuple counts:
4632443 ~2% {3} r1 = JOIN _cil_instruction_3#antijoin_rhs_cil_method_implementation#shared WITH cil_method_implementation ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1
71945701 ~3% {3} r2 = JOIN r1 WITH cil_method_implementation_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2
71945701 ~1329% {3} r3 = JOIN r2 WITH Method#621e9e2e::MethodImplementation::getNumberOfInstructions#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1
5016836 ~4% {4} r4 = JOIN r3 WITH Method#621e9e2e::MethodImplementation::getNumberOfInstructions#0#dispred#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Rhs.1
{4} r5 = SELECT r4 ON In.3 < In.2
65637 ~3% {2} r6 = SCAN r5 OUTPUT In.0, In.1
71945701 ~0% {3} r7 = JOIN r1 WITH cil_method_implementation_10#join_rhs ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
71945701 ~1% {4} r8 = JOIN r7 WITH assemblies ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0, Rhs.1
71945701 ~0% {5} r9 = JOIN r8 WITH cil_method_implementation ON FIRST 1 OUTPUT Rhs.2, Lhs.1, Lhs.2, Lhs.0, Lhs.3
71945701 ~0% {5} r10 = JOIN r9 WITH assemblies ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Lhs.4
71945701 ~0% {5} r11 = JOIN r10 WITH FileSystem#df18ed9a::Make#File#1a556f64::Input#::Container::toString#0#dispred#bf ON FIRST 1 OUTPUT Lhs.4, Lhs.1, Lhs.2, Lhs.3, Rhs.1
71945701 ~2% {5} r12 = JOIN r11 WITH FileSystem#df18ed9a::Make#File#1a556f64::Input#::Container::toString#0#dispred#bf ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.1
{5} r13 = SELECT r12 ON In.4 > In.3
33509342 ~0% {3} r14 = SCAN r13 OUTPUT In.0, In.1, In.2
33509342 ~0% {4} r15 = JOIN r14 WITH Method#621e9e2e::MethodImplementation::getNumberOfInstructions#0#dispred#ff ON FIRST 1 OUTPUT Lhs.2, Rhs.1, Lhs.0, Lhs.1
33051362 ~1670% {2} r16 = JOIN r15 WITH Method#621e9e2e::MethodImplementation::getNumberOfInstructions#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.3
33116999 ~1646% {2} r17 = r6 UNION r16
return r17
```
58 lines
1.8 KiB
Plaintext
58 lines
1.8 KiB
Plaintext
/**
|
|
* Provides classes and predicates for identifying stub code.
|
|
*/
|
|
|
|
import CIL
|
|
|
|
/**
|
|
* The average number of instructions per method,
|
|
* below which an assembly is probably a stub.
|
|
*/
|
|
private float stubInstructionThreshold() { result = 5.1 }
|
|
|
|
cached
|
|
private module Cached {
|
|
/**
|
|
* A simple heuristic for determining whether an assembly is a
|
|
* reference assembly where the method bodies have dummy implementations.
|
|
* Look at the average number of instructions per method.
|
|
*/
|
|
cached
|
|
predicate assemblyIsStubImpl(Assembly asm) {
|
|
exists(int totalInstructions, int totalImplementations |
|
|
totalInstructions = count(Instruction i | i.getImplementation().getLocation() = asm) and
|
|
totalImplementations =
|
|
count(MethodImplementation i | i.getImplementation().getLocation() = asm) and
|
|
totalInstructions.(float) / totalImplementations.(float) < stubInstructionThreshold()
|
|
)
|
|
}
|
|
|
|
cached
|
|
predicate bestImplementation(MethodImplementation mi) {
|
|
exists(Assembly asm |
|
|
asm = mi.getLocation() and
|
|
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
|
|
mi =
|
|
max(MethodImplementation impl |
|
|
mi.getMethod() = impl.getMethod()
|
|
|
|
|
impl order by impl.getNumberOfInstructions(), impl.getLocation().getFile().toString() desc
|
|
) and
|
|
exists(mi.getAnInstruction())
|
|
)
|
|
}
|
|
}
|
|
|
|
private import Cached
|
|
|
|
predicate assemblyIsStub = assemblyIsStubImpl/1;
|
|
|
|
/**
|
|
* A method implementation that is the "best" one for a particular method,
|
|
* if there are several potential implementations to choose between, and
|
|
* excludes implementations that are probably from stub/reference assemblies.
|
|
*/
|
|
class BestImplementation extends MethodImplementation {
|
|
BestImplementation() { bestImplementation(this) }
|
|
}
|