C++: Fix awful joins on bochs:

```
Evaluated relational algebra for predicate DataFlowPrivate::storeStepImpl/4#b2c79f9a@13be12rc with tuple counts:
           9   ~0%    {3} r1 = JOIN `FlowSummaryImpl::Private::Steps::summaryStoreStep/3#5c2d4899` WITH DataFlowUtil::TFlowSummaryNode#40da8361 ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1
           9   ~0%    {4}    | JOIN WITH DataFlowUtil::TFlowSummaryNode#40da8361 ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1, _
           9  ~12%    {4}    | REWRITE WITH Out.3 := true

     1853420   ~0%    {3} r2 = SCAN `DataFlowPrivate::nodeHasInstruction/3#f469bb06` OUTPUT In.1, In.0, In.2
      100282   ~0%    {3}    | JOIN WITH `Instruction::StoreInstruction.getDestinationAddressOperand/0#dispred#596a4aba` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2
      127910   ~0%    {6}    | JOIN WITH `DataFlowPrivate::numberOfLoadsFromOperand/4#7e555666_1023#join_rhs` ON FIRST 1 OUTPUT _, Lhs.1, Rhs.1, Rhs.3, Lhs.2, Rhs.2
      127910   ~0%    {4}    | REWRITE WITH Tmp.0 := 1, Out.0 := (Tmp.0 + In.4 + In.5) KEEPING 4
  4178182721   ~1%    {4}    | JOIN WITH `DataFlowUtil::FieldContent.getIndirectionIndex/0#dispred#cc69866f_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3
  4290552803   ~0%    {5}    | JOIN WITH `DataFlowUtil::FieldContent.getAField/0#dispred#ba1c91e5` ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.3, Lhs.0, Rhs.1
  3033745816   ~5%    {7}    | JOIN WITH DataFlowUtil::PostFieldUpdateNode#b86f3a84_1023#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.2, Rhs.3
  3033745816   ~3%    {9}    | JOIN WITH DataFlowUtil::TPostUpdateNodeImpl#f5e76b7a_21#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4, Lhs.0, Lhs.5, Lhs.6, Rhs.1, _
                      {8}    | REWRITE WITH Tmp.8 := 1, TEST InOut.7 = Tmp.8 KEEPING 8
  1516872908   ~0%    {7}    | SCAN OUTPUT In.4, In.5, In.6, In.0, In.1, In.2, In.3
  2409090286   ~1%    {6}    | JOIN WITH DataFlowUtil::PostFieldUpdateNode#b86f3a84_0231#join_rhs ON FIRST 3 OUTPUT Rhs.3, Lhs.6, Lhs.3, Lhs.4, Lhs.5, Lhs.0
       66016  ~45%    {4}    | JOIN WITH `DataFlowUtil::FieldAddress.getField/0#dispred#bdd01c1a` ON FIRST 2 OUTPUT Lhs.2, Lhs.4, Lhs.5, Lhs.3

       66025  ~45%    {4} r3 = r1 UNION r2
                      return r3
```
This commit is contained in:
Mathias Vorreiter Pedersen
2025-11-19 10:08:09 +00:00
parent 7f0fcb0c46
commit 9bfe847fda
2 changed files with 11 additions and 15 deletions

View File

@@ -861,6 +861,10 @@ predicate jumpStep(Node n1, Node n2) {
n2.(FlowSummaryNode).getSummaryNode())
}
bindingset[c]
pragma[inline_late]
private int getIndirectionIndexLate(Content c) { result = c.getIndirectionIndex() }
/**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`.
* Thus, `node2` references an object with a field `f` that contains the
@@ -877,12 +881,13 @@ predicate storeStepImpl(Node node1, Content c, Node node2, boolean certain) {
|
postFieldUpdate = node2 and
fc = c and
nodeHasInstruction(node1, store, pragma[only_bind_into](indirectionIndex1)) and
nodeHasInstruction(node1, pragma[only_bind_into](store),
pragma[only_bind_into](indirectionIndex1)) and
postFieldUpdate.getIndirectionIndex() = 1 and
numberOfLoadsFromOperand(postFieldUpdate.getFieldAddress(),
store.getDestinationAddressOperand(), numberOfLoads, certain) and
fc.getAField() = postFieldUpdate.getUpdatedField() and
fc.getIndirectionIndex() = 1 + indirectionIndex1 + numberOfLoads
getIndirectionIndexLate(fc) = 1 + indirectionIndex1 + numberOfLoads
)
or
// models-as-data summarized flow
@@ -968,7 +973,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
nodeHasOperand(node1, fa1.getObjectAddressOperand(), 1) and
numberOfLoadsFromOperand(fa1, operand, numberOfLoads, _) and
fc.getAField() = fa1.getField() and
fc.getIndirectionIndex() = indirectionIndex2 + numberOfLoads
getIndirectionIndexLate(fc) = indirectionIndex2 + numberOfLoads
)
or
// models-as-data summarized flow

View File

@@ -2197,10 +2197,7 @@ class NonUnionFieldContent extends FieldContent, TNonUnionContent {
override Field getAField() { result = f }
/** Gets the indirection index of this `FieldContent`. */
pragma[inline]
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override int getIndirectionIndex() { result = indirectionIndex }
override predicate impliesClearOf(Content c) {
exists(FieldContent fc |
@@ -2230,10 +2227,7 @@ class UnionContent extends FieldContent, TUnionContent {
Union getUnion() { result = u }
/** Gets the indirection index of this `UnionContent`. */
pragma[inline]
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override int getIndirectionIndex() { result = indirectionIndex }
override predicate impliesClearOf(Content c) {
exists(UnionContent uc |
@@ -2257,10 +2251,7 @@ class ElementContent extends Content, TElementContent {
ElementContent() { this = TElementContent(indirectionIndex) }
pragma[inline]
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override int getIndirectionIndex() { result = indirectionIndex }
override predicate impliesClearOf(Content c) { none() }