Skip to content

Commit cff63ad

Browse files
committed
Python: Fix small join-order problem for call-graph
problem is: ``` 14294 ~33% {1} r23 = r21 UNION r22 13626 ~0% {2} | JOIN WITH `DataFlowPublic::Node.getEnclosingCallable/0#dispred#be95825a` ON FIRST 1 OUTPUT Rhs.1, Lhs.0 11871493 ~2% {2} | JOIN WITH `DataFlowPublic::Node.getEnclosingCallable/0#dispred#be95825a_10#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 6810938 ~3% {2} | JOIN WITH num#DataFlowPublic::TCfgNode#2cd2fb22_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 0 ~0% {4} | JOIN WITH `DataFlowDispatch::resolveMethodCall/4#3067f1f1#reorder_0_3_1_2#prev` ON FIRST 2 OUTPUT Rhs.3, Lhs.1, Lhs.0, Rhs.2 0 ~0% {4} | JOIN WITH num#DataFlowDispatch::CallTypeClassMethod#3508c3e5 ON FIRST 1 OUTPUT Lhs.3, Lhs.2, Lhs.0, Lhs.1 0 ~0% {4} | JOIN WITH `DataFlowDispatch::resolveCall/3#454c02d8#reorder_1_0_2#prev` ON FIRST 3 OUTPUT Lhs.3, Lhs.1, Lhs.0, Lhs.2 0 ~0% {5} | JOIN WITH num#DataFlowDispatch::TSelfArgumentPosition#de6d64b8 CARTESIAN PRODUCT OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.0, Rhs.0 ``` that is, it does cartesian product of DataFlowPublic::Node.getEnclosingCallable After fix ``` 14294 ~33% {1} r23 = r21 UNION r22 0 ~0% {4} | JOIN WITH `DataFlowDispatch::resolveMethodCall/4#3067f1f1#reorder_3_0_1_2#prev` ON FIRST 1 OUTPUT Rhs.3, Lhs.0, Rhs.1, Rhs.2 0 ~0% {4} | JOIN WITH num#DataFlowDispatch::CallTypeClassMethod#3508c3e5 ON FIRST 1 OUTPUT Lhs.3, Lhs.2, Lhs.0, Lhs.1 0 ~0% {4} | JOIN WITH `DataFlowDispatch::resolveCall/3#454c02d8#reorder_1_0_2#prev` ON FIRST 3 OUTPUT Lhs.1, Lhs.3, Lhs.0, Lhs.2 0 ~0% {5} | JOIN WITH num#DataFlowPublic::TCfgNode#2cd2fb22 ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0, Lhs.2, Lhs.3 0 ~0% {5} | JOIN WITH `DataFlowPublic::Node.getEnclosingCallable/0#dispred#be95825a` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.2, Lhs.3, Lhs.4 0 ~0% {4} | JOIN WITH `DataFlowPublic::Node.getEnclosingCallable/0#dispred#be95825a` ON FIRST 2 OUTPUT Lhs.0, Lhs.2, Lhs.3, Lhs.4 0 ~0% {5} | JOIN WITH num#DataFlowDispatch::TSelfArgumentPosition#de6d64b8 CARTESIAN PRODUCT OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.0, Rhs.0 ``` Overall stats (old) Pipeline standard for DataFlowDispatch::getCallArg/5#21589076@b30c7vxg was evaluated in 51 iterations totaling 54ms (delta sizes total: 38247). ==> (new) Pipeline standard for DataFlowDispatch::getCallArg/5#21589076@c1559vxu was evaluated in 51 iterations totaling 28ms (delta sizes total: 38247).
1 parent 2aa5ae4 commit cff63ad

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,19 +1302,15 @@ predicate getCallArg(CallNode call, Function target, CallType type, Node arg, Ar
13021302
//
13031303
// call_func(my_obj.some_method)
13041304
// ```
1305-
exists(CfgNode cfgNode | cfgNode.getNode() = call |
1306-
cfgNode.getEnclosingCallable() = arg.getEnclosingCallable()
1307-
)
1305+
exists(CfgNode cfgNode | cfgNode.getNode() = call | sameEnclosingCallable(cfgNode, arg))
13081306
or
13091307
// cls argument for classmethod calls -- see note above about bound methods
13101308
type instanceof CallTypeClassMethod and
13111309
apos.isSelf() and
13121310
resolveMethodCall(call, target, type, arg) and
13131311
(arg = classTracker(_) or arg = clsArgumentTracker(_)) and
13141312
// dataflow lib has requirement that arguments and calls are in same enclosing callable.
1315-
exists(CfgNode cfgNode | cfgNode.getNode() = call |
1316-
cfgNode.getEnclosingCallable() = arg.getEnclosingCallable()
1317-
)
1313+
exists(CfgNode cfgNode | cfgNode.getNode() = call | sameEnclosingCallable(cfgNode, arg))
13181314
or
13191315
// normal arguments for method calls
13201316
(
@@ -1365,6 +1361,16 @@ predicate getCallArg(CallNode call, Function target, CallType type, Node arg, Ar
13651361
)
13661362
}
13671363

1364+
/**
1365+
* join-order helper for getCallArg, since otherwise we would do cartesian product of
1366+
* the enclosing callables
1367+
*/
1368+
bindingset[node1, node2]
1369+
pragma[inline_late]
1370+
private predicate sameEnclosingCallable(Node node1, Node node2) {
1371+
node1.getEnclosingCallable() = node2.getEnclosingCallable()
1372+
}
1373+
13681374
// =============================================================================
13691375
// DataFlowCall
13701376
// =============================================================================

0 commit comments

Comments
 (0)