Skip to content

Data flow: Performance improvements#14255

Merged
hvitved merged 2 commits intogithub:mainfrom
hvitved:dataflow/perf-improvements
Oct 2, 2023
Merged

Data flow: Performance improvements#14255
hvitved merged 2 commits intogithub:mainfrom
hvitved:dataflow/perf-improvements

Conversation

@hvitved
Copy link
Copy Markdown
Contributor

@hvitved hvitved commented Sep 19, 2023

  • Split up the existing fwdFlowIn predicate into two predicates (using a parameterized module); one which is used to calculate flow in and one which is used to calculate flow through (fwdFlowIsEntered). This allows us to get rid of a lot of columns in the first predicate, specifically we don't need to record the argument that flows into the parameter. The second predicate does need to record the argument, however, we can restrict this to arguments/parameters that may actually flow through.
  • Limit non-linear recursion by joining with manually magic'ed predicates: fwdFlowIntoArg, fwdFlowIntoRet, dataFlowTakenCallEdgeIn0, fwdFlow1Param, dataFlowTakenCallEdgeOut0, and fwdFlow1Out.
  • Speedup pathIntoCallable0 by joining with a pruned dispatch relation.

Timings before

Most expensive predicates for stage 17 of completed query StoredXSS.ql:
        time  | evals |   max @ iter | predicate
        ------|-------|--------------|----------
        7m45s |   406 | 37.3s @ 127  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowInCand#11#fffffffffff@36a57wpe
        2m21s |   406 |  7.3s @ 89   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow0#9#fffffffff@36a570we
        1m47s |   649 | 18.6s @ 151  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathIntoCallable0#8#ffffffff@482b2wi1
        53.6s |   405 |    9s @ 88   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowIn#13#fffffffffffff@36a572we
        52.5s |   331 | 13.7s @ 87   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage4#::Stage#Stage5Param#::fwdFlowInCand#11#fffffffffff@2a525wvu
        50.2s |       |              | project#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowIn#13#fffffffffffff@85b9b7cq
        22.6s |   404 |  2.7s @ 90   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow1#10#ffffffffff@36a57ype
        22.1s |       |              | project#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::readStepFwd#5#fffff#3@93e2b53b
        21.6s |       |              | project#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::readStepFwd#5#fffff#2_2301#join_rhs@05d2edql
        16.9s |   626 | 482ms @ 118  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowInCand#11#fffffffffff@a31aawmv
        14.3s |   731 |  1.3s @ 129  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowInCand#11#fffffffffff@99ea4wo2
          14s |    14 | 11.8s @ 3    | ActiveRecord#b77aa5fc::ActiveRecordAssociationMethodCall#ff@fcf4fwgb
        13.2s |   971 |  1.1s @ 164  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowInCand#11#fffffffffff@de8dewr8
        11.6s |   975 | 163ms @ 202  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowRead#10#ffffffffff@de8de6w8
        11.6s |   731 | 231ms @ 125  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowRead#10#ffffffffff@99ea46w2
         9.9s |       |              | TreeSitter#03eaabdd::Ruby::AstNode::getParent#0#dispred#bf@a72f6642
         9.5s |       |              | locations_default_10#join_rhs@6e0257cd
         8.9s |   411 |  2.4s @ 33   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathOutOfCallable1#6#ffffff@482b26w1
         8.1s |       |              | _AST#a6718388::AstNode::getLocation#0#dispred#ff_10#join_rhs_FileSystem#df18ed9a::Make#FileSystem#e9__#shared@1a42d5p4
           7s |       |              | num#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::TNodeNormal#ff@6779f32e
         6.4s |       |              | ruby_ast_node_info_10#join_rhs@49f2b1nd
         6.2s |   406 | 342ms @ 127  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowOutCand#10#ffffffffff@36a57zpe
         6.2s |       |              | Constant#54e8b051::ConstantValue::serialize#0#dispred#ff@a8c1d9aj
           6s |       |              | DataFlowPrivate#462ff392::approxKnownElementIndex#1#ff@5b1b0e8i
         4.8s |   649 | 220ms @ 139  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathStep#7#fffffff@482b21w1
         4.7s |       |              | num#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::TNodeNormal#ff@5a7c462o
         4.7s |       |              | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::flowIntoCallAp#5#fffff_24013#join_rhs@023fe8bo
         4.4s |       |              | BasicBlocks#d5fe3e99::BasicBlock::length#0#dispred#ff@d45f99l7
         4.3s |       |              | TreeSitter#03eaabdd::Ruby::AstNode#b@9f4eb5so
         4.2s |       |              | DataFlowPublic#e1781e31::Node::hasLocationInfo#5#dispred#ffffff@0452f379
         4.2s |       |              | ruby_tokeninfo_10#join_rhs@24caf2k7
         4.1s |    15 |  3.6s @ 3    | _ActiveRecord#b77aa5fc::ActiveRecordAssociation#ff_10#join_rhs_ActiveRecord#b77aa5fc::ActiveRecordAs__#antijoin_rhs@L0#fcf4f
         3.9s |       |              | _Constant#54e8b051::ConstantValue::serialize#0#dispred#ff__DataFlowPrivate#462ff392::Cached::TKnownE__#antijoin_rhs@83591bu2
         3.9s |   649 | 210ms @ 139  | _DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac38__#antijoin_rhs#7@L0#482b2
         3.9s |       |              | Module#2a43f566::getEnclosingModuleInSameCfgScope#1#ff@2ea426k2
         3.8s |   626 |  64ms @ 120  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow0#9#fffffffff@a31aa0wv
         3.8s |   424 | 202ms @ 120  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage3#::Stage#Stage4Param#::fwdFlowInCand#11#fffffffffff@0cc2dwkh
         3.5s |       |              | Scope#029dac98::Cached::scopeOf#1#ff_10#join_rhs@9d161bju
         3.3s |       |              | DataFlowPublic#e1781e31::ModuleNode::getAnInstanceSelf#0#dispred#ff@14473aad
         3.2s |       |              | IOOrFile#0f27e888::pathArgSpawnsSubprocess#1#f@bf5b66fp
         3.1s |       |              | FileSystem#df18ed9a::Make#FileSystem#e91ad87f::Input#::Container::getStem#0#dispred#ff@a06d35ke
         3.1s |       |              | DataFlowPrivate#462ff392::Cached::getLocation#1#ff_10#join_rhs@ce69c3t5
         3.1s |       |              | AST#a6718388::AstNode::getEnclosingModule#0#dispred#ff@34b20av7
           3s |    33 | 777ms @ 4    | Synthesis#d9ff06b1::Desugared::getADescendant#ff@054b045p
           3s |   624 |  95ms @ 291  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow1#10#ffffffffff@a31aaymv
           3s |       |              | AST#a6718388::AstNode::getLocation#0#dispred#ff@e8f09b72
           3s |   519 | 298ms @ 20   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::Stage1::revFlow0#2#ff@ae1f4wk3
         2.9s |       |              | boundedFastTC:ControlFlowGraph#46cebcbd::CfgNode::getASuccessor#0#dispred#ff:_CfgNodes#ace8e412::ExprCfgNode::getExpr#0#dispred#ff_CfgNodes#ace8e412::ExprNodes::InstanceVariable__#higher_order_body@d47903tr
         2.9s |       |              | ActiveRecord#b77aa5fc::ActiveRecordModelFinderCall#ff@3e8ba5qk
         2.9s |   731 | 141ms @ 96   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlow0#9#fffffffff@99ea40w2

Timings after

Most expensive predicates for stage 17 of completed query StoredXSS.ql:
        time  | evals |   max @ iter | predicate
        ------|-------|--------------|----------
        2m23s |   428 | 15.8s @ 168  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow0#9#fffffffff@11c87w9v
          33s |   429 |  7.5s @ 100  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlowIn#6#ffffff@11c87dwv
        19.4s |       |              | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::FwdTypeFlowInput::dataFlowTakenCallEdgeIn0#8#ffffffff@2a75ac2m
          18s |   428 |  2.8s @ 102  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow1#10#ffffffffff@11c876wv
        17.2s |   741 |  1.4s @ 151  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlow0#9#fffffffff@5e71cwq2
          16s |  1060 |  1.5s @ 250  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlow0#9#fffffffff@704bfw11
        13.4s |   658 | 379ms @ 365  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow0#9#fffffffff@f42f1w64
          13s |    14 | 10.9s @ 3    | ActiveRecord#b77aa5fc::ActiveRecordAssociationMethodCall#ff@fcf4fwgb
        11.6s |   741 | 165ms @ 39   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowRead#10#ffffffffff@5e71c8w2
        11.5s |  1063 | 110ms @ 151  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage1#::Stage#Stage2Param#::fwdFlowRead#10#ffffffffff@704bf8w1
         9.8s |       |              | TreeSitter#03eaabdd::Ruby::AstNode::getParent#0#dispred#bf@a72f6642
         9.3s |       |              | locations_default_10#join_rhs@6e0257cd
         9.2s |       |              | num#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::TNodeNormal#ff@6779f32e
         9.1s |       |              | _AST#a6718388::AstNode::getLocation#0#dispred#ff_10#join_rhs_FileSystem#df18ed9a::Make#FileSystem#e9__#shared@1a42d5p4
         8.8s |   411 |  2.4s @ 33   | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathOutOfCallable1#6#ffffff@2d8cd6we
         6.5s |       |              | DataFlowPrivate#462ff392::approxKnownElementIndex#1#ff@5b1b0e8i
         6.5s |       |              | ruby_ast_node_info_10#join_rhs@49f2b1nd
         6.3s |   649 | 674ms @ 151  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathIntoCallable0#8#ffffffff@2d8cdwve
         5.9s |       |              | num#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::TNodeNormal#ff@5a7c462o
         5.5s |       |              | Constant#54e8b051::ConstantValue::serialize#0#dispred#ff@a8c1d9aj
         4.9s |   649 | 250ms @ 145  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::pathStep#7#fffffff@2d8cd1we
         4.7s |       |              | Module#2a43f566::getEnclosingModuleInSameCfgScope#1#ff@2ea426k2
         4.7s |       |              | FileSystem#df18ed9a::Make#FileSystem#e91ad87f::Input#::Container::getBaseName#0#dispred#ff@8a027f4b
         4.6s |       |              | DataFlowPublic#e1781e31::Node::hasLocationInfo#5#dispred#ffffff@0452f379
         4.4s |       |              | _Constant#54e8b051::ConstantValue::serialize#0#dispred#ff__DataFlowPrivate#462ff392::Cached::TKnownE__#antijoin_rhs@83591bu2
         4.4s |       |              | Variable#1965ffe5::VariableWriteAccess#f@51a17872
         4.3s |       |              | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::flowIntoCallAp#5#fffff_24013#join_rhs@aecd765p
         4.1s |   649 | 234ms @ 139  | _DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac38__#antijoin_rhs#7@L0#2d8cd
           4s |       |              | AST#a6718388::AstNode::getLocation#0#dispred#ff@e8f09b72
         3.9s |       |              | Scope#029dac98::Cached::scopeOf#1#ff_10#join_rhs@9d161bju
         3.9s |   458 | 205ms @ 137  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage3#::Stage#Stage4Param#::fwdFlow0#9#fffffffff@f8cbewso
         3.8s |       |              | BasicBlocks#d5fe3e99::BasicBlock::length#0#dispred#ff@d45f99l7
         3.7s |    15 |  3.2s @ 3    | _ActiveRecord#b77aa5fc::ActiveRecordAssociation#ff_10#join_rhs_ActiveRecord#b77aa5fc::ActiveRecordAs__#antijoin_rhs@L0#fcf4f
         3.6s |       |              | TreeSitter#03eaabdd::Ruby::AstNode#b@9f4eb5so
         3.5s |       |              | DataFlowPublic#e1781e31::ModuleNode::getAnInstanceSelf#0#dispred#ff@14473aad
         3.4s |       |              | IOOrFile#0f27e888::pathArgSpawnsSubprocess#1#f@bf5b66fp
         3.4s |       |              | FileSystem#df18ed9a::Make#FileSystem#e91ad87f::Input#::Container::getStem#0#dispred#ff@a06d35ke
         3.3s |   519 | 333ms @ 7    | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::Stage1::revFlow0#2#ff@ae1f4wk3
         3.3s |       |              | boundedFastTC:ControlFlowGraph#46cebcbd::CfgNode::getASuccessor#0#dispred#ff:_CfgNodes#ace8e412::ExprCfgNode::getExpr#0#dispred#ff_CfgNodes#ace8e412::ExprNodes::InstanceVariable__#higher_order_body@d47903tr
         3.2s |       |              | DataFlowPrivate#462ff392::Cached::getLocation#1#ff_10#join_rhs@ce69c3t5
         3.2s |       |              | _num#DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTrackin__#shared@86bad5m9
         3.2s |       |              | AST#a6718388::AstNode::getEnclosingModule#0#dispred#ff@34b20av7
         2.9s |    33 | 827ms @ 4    | Synthesis#d9ff06b1::Desugared::getADescendant#ff@054b045p
         2.9s |       |              | DataFlowPublic#e1781e31::ModuleNode::getInstanceMethod#1#dispred#fff@e2f386qt
         2.9s |       |              | Method#8b49e67f::isDeclaredIn#3#fff@37ff952v
         2.8s |       |              | Module#fe82a56b::Cached::lookupMethod#2#fff_201#join_rhs@836922m0
         2.8s |   656 |  47ms @ 313  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#TaintTracking#f6f2598d::TaintFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#TaintTrackingImplSpecific#b79e579d::RubyTaintTracking#::Global#StoredXSSQuery#5ea303cf::StoredXssConfig#::C#::MkStage#Stage2#::Stage#Stage3Param#::fwdFlow1#10#ffffffffff@f42f16w4
         2.8s |       |              | CfgNodes#ace8e412::ExprNodes::VariableAccessCfgNode#ff@3756ec9a
         2.8s |       |              | ActiveRecord#b77aa5fc::ActiveRecordModelFinderCall#ff@3e8ba5qk
         2.7s |       |              | DataFlowPublic#e1781e31::Content::toString#0#dispred#ff@4519edhf

@hvitved hvitved force-pushed the dataflow/perf-improvements branch 2 times, most recently from 0c6b2eb to 3499f59 Compare September 19, 2023 18:12
@hvitved hvitved added the no-change-note-required This PR does not need a change note label Sep 19, 2023
@hvitved hvitved marked this pull request as ready for review September 19, 2023 18:17
@hvitved hvitved added the Ruby label Sep 20, 2023
@hvitved hvitved marked this pull request as draft September 25, 2023 18:24
@hvitved hvitved force-pushed the dataflow/perf-improvements branch from 3499f59 to ab182bc Compare September 26, 2023 11:15
@hvitved hvitved force-pushed the dataflow/perf-improvements branch from ab182bc to 975243f Compare September 26, 2023 11:16
Comment thread shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll Fixed
@hvitved hvitved force-pushed the dataflow/perf-improvements branch 2 times, most recently from 12073f7 to bce66d8 Compare September 26, 2023 18:23
@hvitved hvitved marked this pull request as ready for review September 27, 2023 07:34
@hvitved hvitved requested review from a team as code owners September 27, 2023 07:34
Comment thread go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll Outdated
@yoff
Copy link
Copy Markdown
Contributor

yoff commented Sep 27, 2023

Python evaluation looks quite acceptable (no real change). 👍


pragma[nomagic]
private predicate dataFlowTakenCallEdgeIn0(
DataFlowCall call, DataFlowCallable c, ParamNodeEx p, FlowState state, Cc innercc,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well be CcCall innercc for clarity, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

}

pragma[nomagic]
private predicate fwdFlowOut(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The introduction of this projection seems superfluous. It's only used once in fwdFlow0 and there its occurrence is as a trivial disjunct, so doing the projection there instead as we did before will be exactly the same work, except avoiding the additional materialisation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, wait, the wider version is now inlined. Hmm, but that still shouldn't matter, right? Dropping this predicate will just postpone the projection and dedup to fwdFlow0 where the cost will be the same, but will save this materialisation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be OK to inline; only reason I nomagiced it is because it is sometimes convenient to be able to spot in the timing logs whether it is, say, flow out that is expensive. But I'll inline it.

Comment on lines +1619 to +1620
fwdFlowOutCand(call, ret, innercc, inner, out, apa, allowsFieldFlow) and
FwdTypeFlow::typeFlowValidEdgeOut(call, inner) and
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so just double-checking: You're choosing to make this non-linear join smaller by re-joining with fwdFlowIntoRet in a subsequent and additional non-linear join? It's a bit counter-intuitive at first, but presumably that's worth it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed.

}
/**
* Exposes the inlined predicate `fwdFlowIn`, which is used to calculate both
* flow in and flow through.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this means that the contents of this module is calculated in both contexts where one is essentially is a subset of the other. Hmm. All for the purpose of being able to project slightly earlier. This trade-off sounds dubious.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the change that matters most to DB that I used to construct the performance numbers mentioned in the PR description. I reverified this by nomagicing the inlined fwdFlowIn, which results in

4m56s |   426 | 13.7s @ 223  | DataFlowImpl#248dabc3::MakeImpl#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Impl#DataFlow#167ac380::DataFlowMake#DataFlowImplSpecific#21008cd7::RubyDataFlow#::Global#XSS#e59174e9::OrmTracking::Config#::C#::MkStage#Stage2#::Stage#Stage3Param#::FwdFlowIn#FwdFlowInNoRestriction#::fwdFlowIn#13#fffffffffffff@ae640x39

aschackmull
aschackmull previously approved these changes Sep 29, 2023
Copy link
Copy Markdown
Contributor

@aschackmull aschackmull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are som obvious improvements here. Primarily I see the pruning of the call-context-dependent dispatch relation with the call edges from the prior stage as a likely important improvement. But there's also some changes that are harder to judge whether they are improvements or not. The overall picture appears to be a clear speedup, and the semantics appear to be correct, so I'm happy to merge as-is and then we can always iterate on the more dubious details in follow-up work.

*/
private module FwdFlowIn<FwdFlowInInputSig I> {
pragma[nomagic]
private predicate callEdgeArgParamRestricted(

Check warning

Code scanning / CodeQL

Candidate predicate not marked as `nomagic`

Candidate predicate to [readStepCand](1) is not marked as nomagic. Candidate predicate to [readStepCand](2) is not marked as nomagic.
@hvitved hvitved added the Ruby label Oct 2, 2023
@hvitved hvitved merged commit 2684a22 into github:main Oct 2, 2023
@hvitved hvitved deleted the dataflow/perf-improvements branch October 2, 2023 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DataFlow Library no-change-note-required This PR does not need a change note Ruby

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants