Skip to content

Commit 2dfa029

Browse files
committed
Misc. poc updates to address performance issues with wireshark.
1 parent 418b113 commit 2dfa029

File tree

1 file changed

+48
-8
lines changed

1 file changed

+48
-8
lines changed

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,48 @@ private import semmle.code.cpp.ir.ValueNumbering
99
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
1010
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
1111

12+
/**
13+
* Variant of valueNumber that accounts for conversions.
14+
* Note: this predicate is defined in IRGuards to take advantage of
15+
* IRGuards definition of int_value.
16+
*/
17+
ValueNumber valueNumberWithConversions(Instruction instr) {
18+
exists(ValueNumber vn | vn = valueNumber(instr) |
19+
// GVN using valueNumber directly
20+
result = vn
21+
or
22+
// GVN for the ConvertInstruction conversion
23+
result = valueNumberWithConversions(vn.getAnInstruction().(ConvertInstruction).getUnary())
24+
or
25+
// GVN for the CompareNEInstruction conversion for a comparison with 0 (conversion of value to boolean in c)
26+
exists(CompareNEInstruction cmp | cmp = vn.getAnInstruction() |
27+
result = valueNumberWithConversions(cmp.getLeft()) and
28+
int_value(cmp.getRight()) = 0
29+
)
30+
)
31+
}
32+
1233
/**
1334
* Returns `instr` or any instruction used to define `instr`.
1435
*/
36+
pragma[inline]
1537
private Instruction getDerivedInstruction(Instruction instr) {
16-
// The instruction itself
1738
result = instr
1839
or
19-
// or the GVN definition for the current instruction
2040
result = valueNumber(instr).getAnInstruction().(StoreInstruction).getSourceValue()
2141
or
22-
// Special handling for conversions
23-
result =
24-
getDerivedInstruction(valueNumber(instr).getAnInstruction().(CompareNEInstruction).getLeft())
42+
result = derivedThroughConversion(valueNumber(instr))
43+
}
44+
45+
private Instruction derivedThroughConversion(ValueNumber vn) {
46+
// GVN for the ConvertInstruction conversion
47+
result = getDerivedInstruction(vn.getAnInstruction().(ConvertInstruction).getUnary())
2548
or
26-
result =
27-
getDerivedInstruction(valueNumber(instr).getAnInstruction().(ConvertInstruction).getUnary())
49+
// GVN for the CompareNEInstruction conversion for a comparison with 0 (conversion of value to boolean in c)
50+
exists(CompareNEInstruction comp | comp = vn.getAnInstruction() |
51+
result = getDerivedInstruction(comp.getLeft()) and
52+
int_value(comp.getRight()) = 0
53+
)
2854
}
2955

3056
/**
@@ -832,7 +858,7 @@ private predicate unary_compares_eq(
832858
exists(Instruction derived | derived = getDerivedInstruction(test) |
833859
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
834860
exists(AbstractValue v |
835-
unary_simple_comparison_eq(derived, k, inNonZeroCase, v) and op.getDef() = test
861+
unary_simple_comparison_eq(derived, k, inNonZeroCase, v) and op.getDef() = derived
836862
|
837863
areEqual = true and value = v
838864
or
@@ -897,6 +923,18 @@ private predicate unary_simple_comparison_eq(
897923
inNonZeroCase = false
898924
)
899925
or
926+
(
927+
exists(BinaryLogicalOperation e | e.getAnOperand() = test.getUnconvertedResultExpression())
928+
or
929+
exists(UnaryLogicalOperation e | e.getAnOperand() = test.getUnconvertedResultExpression())
930+
or
931+
exists(IfStmt i | i.getCondition() = test.getUnconvertedResultExpression())
932+
or
933+
exists(Loop i | i.getCondition() = test.getUnconvertedResultExpression())
934+
or
935+
exists(ConditionalExpr c | c.getCondition() = test.getUnconvertedResultExpression())
936+
// Todo recursive conditionalExpr in guard
937+
) and
900938
// Any instruction with an integral type could potentially be part of a
901939
// check for nullness when used in a guard. So we include all integral
902940
// typed instructions here. However, since some of these instructions are
@@ -941,6 +979,8 @@ private predicate unary_simple_comparison_eq(
941979
value.(BooleanValue).getValue() = false and
942980
inNonZeroCase = false
943981
)
982+
// Has to be in a boolean operator (operanad of OR or AND)
983+
// has to be a 'guard' (loop, if, switch, ternary)
944984
}
945985

946986
/** A call to the builtin operation `__builtin_expect`. */

0 commit comments

Comments
 (0)