C#: Fix bad join order

Before
```
Evaluated recursive predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@8254eapb in 6096ms on iteration 4 (delta size: 592145).
Evaluated relational algebra for predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@8254eapb on iteration 4 running pipeline standard with tuple counts:
          204507  ~0%    {2} r1 = SCAN Stmt#3baf294a::TryStmt::getATriedElement#ff#prev_delta OUTPUT In.1, In.0
          204507  ~0%    {3} r2 = JOIN r1 WITH _@callable#f_ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff_10#j__#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1
        17844283  ~0%    {3} r3 = JOIN r2 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2
          592145  ~0%    {2} r4 = JOIN r3 WITH Element#baf0c59e::Element::getAChild#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.1
          592145  ~0%    {2} r5 = r4 AND NOT Stmt#3baf294a::TryStmt::getATriedElement#ff#prev(Lhs.0, Lhs.1)
                         return r5
```

After
```
Evaluated recursive predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@4adecd47 in 310ms on iteration 4 (delta size: 592145).
Evaluated relational algebra for predicate Stmt#3baf294a::TryStmt::getATriedElement#ff@4adecd47 on iteration 4 running pipeline standard with tuple counts:
        204507  ~0%    {2} r1 = SCAN Stmt#3baf294a::TryStmt::getATriedElement#ff#prev_delta OUTPUT In.1, In.0
        204507  ~0%    {2} r2 = r1 AND NOT _statements_10#join_rhs#antijoin_rhs#13(Lhs.0)
        592145  ~2%    {3} r3 = JOIN r2 WITH Element#baf0c59e::Element::getAChild#0#dispred#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Rhs.1
        592145  ~0%    {3} r4 = JOIN r3 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff ON FIRST 1 OUTPUT Lhs.2, Rhs.1, Lhs.1
        592145  ~0%    {2} r5 = JOIN r4 WITH ControlFlowElement#9501aa28::ControlFlowElement::getEnclosingCallable#0#dispred#ff ON FIRST 2 OUTPUT Lhs.2, Lhs.0
        592145  ~0%    {2} r6 = r5 AND NOT Stmt#3baf294a::TryStmt::getATriedElement#ff#prev(Lhs.0, Lhs.1)
                       return r6
```
This commit is contained in:
Tom Hvitved
2023-08-09 11:26:38 +02:00
parent 560b876c01
commit 7dac819730

View File

@@ -861,6 +861,12 @@ class YieldReturnStmt extends YieldStmt {
override string getAPrimaryQlClass() { result = "YieldReturnStmt" }
}
bindingset[cfe1, cfe2]
pragma[inline_late]
private predicate sameCallable(ControlFlowElement cfe1, ControlFlowElement cfe2) {
cfe1.getEnclosingCallable() = cfe2.getEnclosingCallable()
}
/**
* A `try` statement, for example
*
@@ -947,8 +953,7 @@ class TryStmt extends Stmt, @try_stmt {
mid = this.getATriedElement() and
not mid instanceof TryStmt and
result = mid.getAChild() and
pragma[only_bind_into](mid.getEnclosingCallable()) =
pragma[only_bind_into](result.getEnclosingCallable())
sameCallable(mid, result)
)
}
}