Skip to content

Commit a341912

Browse files
committed
C++: Performance tweak for 1-field struct loads
On kamailio/kamailio the `DataFlowUtil::simpleInstructionLocalFlowStep` predicate was slow because of the case for single-field structs, where there was a large tuple-count bulge when joining with `getFieldSizeOfClass`: 3552902 ~2% {2} r1 = SCAN Instruction::CopyInstruction::getSourceValueOperand_dispred#3#ff AS I OUTPUT I.<1>, I.<0> 2065347 ~2% {2} r35 = JOIN r1 WITH Operand::NonPhiMemoryOperand::getAnyDef_dispred#3#ff AS R ON FIRST 1 OUTPUT r1.<1>, R.<1> 2065827 ~2% {3} r36 = JOIN r35 WITH Instruction::Instruction::getResultType_dispred#3#ff AS R ON FIRST 1 OUTPUT R.<1>, r35.<1>, r35.<0> 2065825 ~3% {3} r37 = JOIN r36 WITH Type::Type::getSize_dispred#ff AS R ON FIRST 1 OUTPUT r36.<1>, r36.<2>, R.<1> 2068334 ~2% {4} r38 = JOIN r37 WITH Instruction::Instruction::getResultType_dispred#3#ff AS R ON FIRST 1 OUTPUT R.<1>, r37.<2>, r37.<0>, r37.<1> 314603817 ~0% {3} r39 = JOIN r38 WITH DataFlowUtil::getFieldSizeOfClass#fff_120#join_rhs AS R ON FIRST 2 OUTPUT r38.<3>, R.<2>, r38.<2> 8 ~0% {2} r40 = JOIN r39 WITH Instruction::Instruction::getResultType_dispred#3#ff AS R ON FIRST 2 OUTPUT r39.<2>, r39.<0> That's 314M tuples. Strangely, there is no such bulge on more well-behaved snapshots like mysql/mysql-server. With this commit the explosion is gone: ... 2065825 ~0% {4} r37 = JOIN r36 WITH Type::Type::getSize_dispred#ff AS R ON FIRST 1 OUTPUT r36.<0>, R.<1>, r36.<1>, r36.<2> 1521 ~1% {3} r38 = JOIN r37 WITH DataFlowUtil::getFieldSizeOfClass#fff_021#join_rhs AS R ON FIRST 2 OUTPUT r37.<2>, R.<2>, r37.<3> 8 ~0% {2} r39 = JOIN r38 WITH Instruction::Instruction::getResultType_dispred#3#ff AS R ON FIRST 2 OUTPUT r38.<0>, r38.<2>
1 parent 398678a commit a341912

File tree

1 file changed

+4
-3
lines changed

1 file changed

+4
-3
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,10 +564,11 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
564564
or
565565
// Flow from stores to structs with a single field to a load of that field.
566566
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = iFrom and
567-
exists(int size, Type type |
567+
exists(int size, Type type, Class cTo |
568568
type = iFrom.getResultType() and
569-
iTo.getResultType().getSize() = size and
570-
getFieldSizeOfClass(iTo.getResultType(), type, size)
569+
cTo = iTo.getResultType() and
570+
cTo.getSize() = size and
571+
getFieldSizeOfClass(cTo, type, size)
571572
)
572573
or
573574
// Flow through modeled functions

0 commit comments

Comments
 (0)