svf-tools 1.0.303 → 1.0.307
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SVF-doxygen/html/html/AbstractPointsToDS_8h_source.html +1 -1
- package/SVF-doxygen/html/html/AndersenLCD_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/AndersenSCD_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/AndersenSFR_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/AndersenSFR_8h_source.html +4 -4
- package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +11 -11
- package/SVF-doxygen/html/html/AndersenWaveDiffWithType_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/AndersenWaveDiff_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/Andersen_8cpp_source.html +21 -21
- package/SVF-doxygen/html/html/Andersen_8h_source.html +8 -8
- package/SVF-doxygen/html/html/BasicTypes_8h_source.html +8 -8
- package/SVF-doxygen/html/html/CHG_8cpp.html +7 -6
- package/SVF-doxygen/html/html/CHG_8cpp_source.html +42 -41
- package/SVF-doxygen/html/html/CHG_8h_source.html +2 -2
- package/SVF-doxygen/html/html/CSC_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/CSC_8h_source.html +3 -3
- package/SVF-doxygen/html/html/CommonCHG_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ConditionalPT_8h_source.html +2 -2
- package/SVF-doxygen/html/html/Conditions_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/Conditions_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ConsGNode_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ConsG_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/ConsG_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ContextDDA_8cpp_source.html +9 -9
- package/SVF-doxygen/html/html/ContextDDA_8h_source.html +3 -3
- package/SVF-doxygen/html/html/CoreBitVector_8h.html +2 -0
- package/SVF-doxygen/html/html/CoreBitVector_8h_source.html +3 -1
- package/SVF-doxygen/html/html/CxtStmt_8h_source.html +1 -1
- package/SVF-doxygen/html/html/DCHG_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/DCHG_8h_source.html +4 -4
- package/SVF-doxygen/html/html/DDAClient_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/DDAClient_8h_source.html +3 -3
- package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +11 -11
- package/SVF-doxygen/html/html/DDAPass_8h_source.html +1 -1
- package/SVF-doxygen/html/html/DDAStat_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/DDAStat_8h_source.html +2 -2
- package/SVF-doxygen/html/html/DDAVFSolver_8h_source.html +8 -8
- package/SVF-doxygen/html/html/DPItem_8h_source.html +1 -1
- package/SVF-doxygen/html/html/DataFlowUtil_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ExtAPI_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ExternalPAG_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/ExternalPAG_8h_source.html +3 -3
- package/SVF-doxygen/html/html/FSMPTA_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/FSMPTA_8h_source.html +3 -3
- package/SVF-doxygen/html/html/FlowDDA_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/FlowDDA_8h_source.html +2 -2
- package/SVF-doxygen/html/html/FlowSensitiveStat_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/FlowSensitiveTBHC_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/FlowSensitiveTBHC_8h_source.html +3 -3
- package/SVF-doxygen/html/html/FlowSensitive_8cpp_source.html +17 -17
- package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +3 -3
- package/SVF-doxygen/html/html/GenericGraph_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ICFGBuilder_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ICFGNode_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ICFGStat_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ICFG_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/ICFG_8h_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMModule_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/LLVMModule_8h_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMUtil_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/LLVMUtil_8h_source.html +1 -1
- package/SVF-doxygen/html/html/LeakChecker_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/LeakChecker_8h_source.html +2 -2
- package/SVF-doxygen/html/html/LocationSet_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/LocationSet_8h_source.html +2 -2
- package/SVF-doxygen/html/html/LockAnalysis_8cpp_source.html +8 -8
- package/SVF-doxygen/html/html/LockAnalysis_8h_source.html +6 -6
- package/SVF-doxygen/html/html/LockResultValidator_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/LockResultValidator_8h_source.html +3 -3
- package/SVF-doxygen/html/html/MHP_8cpp_source.html +12 -12
- package/SVF-doxygen/html/html/MHP_8h_source.html +4 -4
- package/SVF-doxygen/html/html/MSSAMuChi_8h_source.html +1 -1
- package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/MTAAnnotator_8h_source.html +1 -1
- package/SVF-doxygen/html/html/MTAResultValidator_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/MTAResultValidator_8h_source.html +3 -3
- package/SVF-doxygen/html/html/MTAStat_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/MTAStat_8h_source.html +1 -1
- package/SVF-doxygen/html/html/MTA_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/MTA_8h_source.html +2 -2
- package/SVF-doxygen/html/html/MemModel_8h_source.html +1 -1
- package/SVF-doxygen/html/html/MemPartition_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/MemPartition_8h_source.html +3 -3
- package/SVF-doxygen/html/html/MemRegion_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/MemRegion_8h_source.html +4 -4
- package/SVF-doxygen/html/html/MemSSA_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/MemSSA_8h_source.html +2 -2
- package/SVF-doxygen/html/html/MutablePointsToDS_8h_source.html +2 -2
- package/SVF-doxygen/html/html/NodeIDAllocator_8cpp_source.html +11 -11
- package/SVF-doxygen/html/html/NodeIDAllocator_8h_source.html +2 -2
- package/SVF-doxygen/html/html/OfflineConsG_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/OfflineConsG_8h_source.html +2 -2
- package/SVF-doxygen/html/html/Options_8cpp_source.html +112 -110
- package/SVF-doxygen/html/html/Options_8h.html +1 -0
- package/SVF-doxygen/html/html/Options_8h_source.html +114 -111
- package/SVF-doxygen/html/html/PAGBuilder_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/PAGEdge_8h_source.html +1 -1
- package/SVF-doxygen/html/html/PAG_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/PAG_8h_source.html +5 -5
- package/SVF-doxygen/html/html/PCG_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/PCG_8h_source.html +1 -1
- package/SVF-doxygen/html/html/PTACallGraph_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/PTACallGraph_8h_source.html +3 -3
- package/SVF-doxygen/html/html/PTAStat_8cpp_source.html +21 -18
- package/SVF-doxygen/html/html/PTAStat_8h_source.html +19 -17
- package/SVF-doxygen/html/html/PTAType_8h_source.html +4 -4
- package/SVF-doxygen/html/html/PathCondAllocator_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/PathCondAllocator_8h_source.html +3 -3
- package/SVF-doxygen/html/html/PersistentPointsToCache_8h_source.html +2 -2
- package/SVF-doxygen/html/html/PersistentPointsToDS_8h_source.html +2 -2
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/PointerAnalysisImpl_8h_source.html +4 -4
- package/SVF-doxygen/html/html/PointerAnalysis_8cpp_source.html +19 -19
- package/SVF-doxygen/html/html/PointerAnalysis_8h_source.html +5 -5
- package/SVF-doxygen/html/html/PointsTo_8cpp_source.html +4 -5
- package/SVF-doxygen/html/html/PointsTo_8h_source.html +2 -2
- package/SVF-doxygen/html/html/ProgSlice_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/ProgSlice_8h_source.html +2 -2
- package/SVF-doxygen/html/html/SCC_8h_source.html +3 -3
- package/SVF-doxygen/html/html/SVFBasicTypes_8h.html +33 -27
- package/SVF-doxygen/html/html/SVFBasicTypes_8h_source.html +52 -49
- package/SVF-doxygen/html/html/SVFGBuilder_8cpp_source.html +6 -6
- package/SVF-doxygen/html/html/SVFGEdge_8h_source.html +2 -2
- package/SVF-doxygen/html/html/SVFGNode_8h_source.html +3 -3
- package/SVF-doxygen/html/html/SVFGOPT_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/SVFGOPT_8h_source.html +3 -3
- package/SVF-doxygen/html/html/SVFGStat_8cpp_source.html +11 -11
- package/SVF-doxygen/html/html/SVFGStat_8h_source.html +5 -5
- package/SVF-doxygen/html/html/SVFG_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/SVFG_8h_source.html +2 -2
- package/SVF-doxygen/html/html/SVFModule_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/SVFModule_8h_source.html +1 -1
- package/SVF-doxygen/html/html/SVFUtil_8cpp_source.html +10 -9
- package/SVF-doxygen/html/html/SVFUtil_8h_source.html +7 -7
- package/SVF-doxygen/html/html/SaberCheckerAPI_8h_source.html +1 -1
- package/SVF-doxygen/html/html/SaberSVFGBuilder_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/SaberSVFGBuilder_8h_source.html +2 -2
- package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +7 -7
- package/SVF-doxygen/html/html/SrcSnkDDA_8h_source.html +3 -3
- package/SVF-doxygen/html/html/Steensgaard_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/Steensgaard_8h_source.html +2 -2
- package/SVF-doxygen/html/html/SymbolTableInfo_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/SymbolTableInfo_8h_source.html +2 -2
- package/SVF-doxygen/html/html/TCT_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/TCT_8h_source.html +4 -4
- package/SVF-doxygen/html/html/ThreadAPI_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/ThreadAPI_8h_source.html +1 -1
- package/SVF-doxygen/html/html/ThreadCallGraph_8cpp_source.html +3 -3
- package/SVF-doxygen/html/html/ThreadCallGraph_8h_source.html +2 -2
- package/SVF-doxygen/html/html/TypeAnalysis_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/TypeAnalysis_8h_source.html +1 -1
- package/SVF-doxygen/html/html/TypeBasedHeapCloning_8cpp_source.html +2 -2
- package/SVF-doxygen/html/html/TypeBasedHeapCloning_8h_source.html +2 -2
- package/SVF-doxygen/html/html/VFGNode_8h_source.html +2 -2
- package/SVF-doxygen/html/html/VFG_8cpp_source.html +4 -4
- package/SVF-doxygen/html/html/VFG_8h_source.html +3 -3
- package/SVF-doxygen/html/html/VersionedFlowSensitiveStat_8cpp_source.html +10 -8
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp.html +3 -0
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +78 -65
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8h.html +3 -2
- package/SVF-doxygen/html/html/VersionedFlowSensitive_8h_source.html +78 -69
- package/SVF-doxygen/html/html/WPAFSSolver_8h_source.html +2 -2
- package/SVF-doxygen/html/html/WPAPass_8cpp_source.html +5 -5
- package/SVF-doxygen/html/html/WPASolver_8h_source.html +2 -2
- package/SVF-doxygen/html/html/WPAStat_8h_source.html +1 -1
- package/SVF-doxygen/html/html/WorkList_8h_source.html +1 -1
- package/SVF-doxygen/html/html/annotated.html +189 -186
- package/SVF-doxygen/html/html/classSVF_1_1ActualINSVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ActualOUTSVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1AddrPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +24 -24
- package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +10 -10
- package/SVF-doxygen/html/html/classSVF_1_1AndersenLCD.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD.html +12 -12
- package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1AndersenStat-members.html +10 -7
- package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +18 -14
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiffWithType.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.html +7 -7
- package/SVF-doxygen/html/html/classSVF_1_1BinaryOPPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1BinaryOPVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1BranchCondManager.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1CHGraph.html +91 -91
- package/SVF-doxygen/html/html/classSVF_1_1CHNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CSC.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1CallBlockNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CallPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CmpPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CmpVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ContextDDA.html +17 -17
- package/SVF-doxygen/html/html/classSVF_1_1CopyPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1CxtProc.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1CxtThreadProc.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +7 -7
- package/SVF-doxygen/html/html/classSVF_1_1DDAClient.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +11 -11
- package/SVF-doxygen/html/html/classSVF_1_1DDAStat-members.html +5 -2
- package/SVF-doxygen/html/html/classSVF_1_1DDAStat.html +14 -10
- package/SVF-doxygen/html/html/classSVF_1_1DDAVFSolver.html +27 -27
- package/SVF-doxygen/html/html/classSVF_1_1DistinctMRG.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1ExternalPAG.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1FIObjPN.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1FlowDDA.html +14 -14
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +48 -48
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat-members.html +5 -2
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +16 -12
- package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveTBHC.html +23 -23
- package/SVF-doxygen/html/html/classSVF_1_1ForkJoinAnalysis.html +13 -13
- package/SVF-doxygen/html/html/classSVF_1_1FormalINSVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FormalOUTSVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FormalParmVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FormalRetVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FunEntryBlockNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FunExitBlockNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1FunptrDDAClient.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1GepObjPN.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1GepPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1GepValPN.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ICFG.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ICFGStat-members.html +5 -2
- package/SVF-doxygen/html/html/classSVF_1_1ICFGStat.html +7 -3
- package/SVF-doxygen/html/html/classSVF_1_1InterDisjointMRG.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1InterMSSAPHISVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1InterPHIVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1IntraBlockNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1IntraDisjointMRG.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1IntraMSSAPHISVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1IntraPHIVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1LLVMModuleSet.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1LeakChecker.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1LoadPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1LocationSet.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1LockAnalysis.html +36 -36
- package/SVF-doxygen/html/html/classSVF_1_1LockResultValidator.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1MHP.html +31 -31
- package/SVF-doxygen/html/html/classSVF_1_1MRGenerator.html +20 -20
- package/SVF-doxygen/html/html/classSVF_1_1MSSAPHISVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1MTA.html +9 -9
- package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +9 -9
- package/SVF-doxygen/html/html/classSVF_1_1MTAResultValidator.html +12 -12
- package/SVF-doxygen/html/html/classSVF_1_1MTASVFGBuilder.html +18 -18
- package/SVF-doxygen/html/html/classSVF_1_1MTAStat-members.html +6 -3
- package/SVF-doxygen/html/html/classSVF_1_1MTAStat.html +17 -13
- package/SVF-doxygen/html/html/classSVF_1_1MemObj.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1MemSSA.html +19 -19
- package/SVF-doxygen/html/html/classSVF_1_1MemSSAStat-members.html +5 -2
- package/SVF-doxygen/html/html/classSVF_1_1MemSSAStat.html +12 -8
- package/SVF-doxygen/html/html/classSVF_1_1MutableDFPTData.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1NodeIDAllocator.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1NodeIDAllocator_1_1Clusterer.html +17 -17
- package/SVF-doxygen/html/html/classSVF_1_1NormalGepPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ObjPN.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1OfflineConsG.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1Options-members.html +102 -100
- package/SVF-doxygen/html/html/classSVF_1_1Options.html +166 -111
- package/SVF-doxygen/html/html/classSVF_1_1PAG.html +6 -6
- package/SVF-doxygen/html/html/classSVF_1_1PAGBuilder.html +29 -29
- package/SVF-doxygen/html/html/classSVF_1_1PCG.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1PHIVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1PTACallGraph.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1PTACallGraphNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1PTAStat-members.html +6 -3
- package/SVF-doxygen/html/html/classSVF_1_1PTAStat.html +88 -56
- package/SVF-doxygen/html/html/classSVF_1_1PathCondAllocator.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1PersistentDFPTData.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1PersistentDiffPTData.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1PersistentPTData.html +6 -6
- package/SVF-doxygen/html/html/classSVF_1_1PersistentPointsToCache.html +6 -6
- package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.html +23 -23
- package/SVF-doxygen/html/html/classSVF_1_1PointsTo.html +9 -8
- package/SVF-doxygen/html/html/classSVF_1_1ProgSlice.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1RetBlockNode.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1RetPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFBasicBlock.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFFunction.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1SVFG.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1SVFGBuilder.html +8 -8
- package/SVF-doxygen/html/html/classSVF_1_1SVFGOPT.html +13 -13
- package/SVF-doxygen/html/html/classSVF_1_1SVFGStat-members.html +11 -8
- package/SVF-doxygen/html/html/classSVF_1_1SVFGStat.html +40 -36
- package/SVF-doxygen/html/html/classSVF_1_1SVFGlobal.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFInstruction.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFModule.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SVFValue.html +33 -33
- package/SVF-doxygen/html/html/classSVF_1_1SaberSVFGBuilder.html +4 -4
- package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +12 -12
- package/SVF-doxygen/html/html/classSVF_1_1Steensgaard.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1StorePE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1SymbolTableInfo.html +18 -18
- package/SVF-doxygen/html/html/classSVF_1_1TCT.html +16 -16
- package/SVF-doxygen/html/html/classSVF_1_1TDForkPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1TDJoinPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1ThreadAPI.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraph.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1TypeBasedHeapCloning.html +5 -5
- package/SVF-doxygen/html/html/classSVF_1_1TypeSystem.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1UnaryOPPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1UnaryOPVFGNode.html +1 -1
- package/SVF-doxygen/html/html/classSVF_1_1VFG.html +3 -3
- package/SVF-doxygen/html/html/classSVF_1_1ValPN.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1VariantGepPE.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive-members.html +161 -162
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +578 -539
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat-members.html +7 -4
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +31 -28
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive_1_1SCC-members.html +83 -0
- package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive_1_1SCC.html +297 -0
- package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1WPAPass.html +12 -12
- package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver.html +2 -2
- package/SVF-doxygen/html/html/classSVF_1_1WPASolver.html +1 -1
- package/SVF-doxygen/html/html/classes.html +96 -95
- package/SVF-doxygen/html/html/functions_b.html +11 -5
- package/SVF-doxygen/html/html/functions_c.html +24 -18
- package/SVF-doxygen/html/html/functions_d.html +13 -4
- package/SVF-doxygen/html/html/functions_e.html +3 -0
- package/SVF-doxygen/html/html/functions_enum.html +3 -0
- package/SVF-doxygen/html/html/functions_eval_c.html +3 -0
- package/SVF-doxygen/html/html/functions_eval_w.html +76 -0
- package/SVF-doxygen/html/html/functions_f.html +14 -14
- package/SVF-doxygen/html/html/functions_func_b.html +6 -0
- package/SVF-doxygen/html/html/functions_func_d.html +7 -4
- package/SVF-doxygen/html/html/functions_func_g.html +15 -9
- package/SVF-doxygen/html/html/functions_func_i.html +11 -11
- package/SVF-doxygen/html/html/functions_func_m.html +0 -3
- package/SVF-doxygen/html/html/functions_func_n.html +1 -4
- package/SVF-doxygen/html/html/functions_func_o.html +6 -4
- package/SVF-doxygen/html/html/functions_func_r.html +4 -1
- package/SVF-doxygen/html/html/functions_func_s.html +1 -1
- package/SVF-doxygen/html/html/functions_func_v.html +2 -1
- package/SVF-doxygen/html/html/functions_g.html +15 -9
- package/SVF-doxygen/html/html/functions_i.html +23 -16
- package/SVF-doxygen/html/html/functions_l.html +12 -15
- package/SVF-doxygen/html/html/functions_m.html +1 -16
- package/SVF-doxygen/html/html/functions_n.html +3 -3
- package/SVF-doxygen/html/html/functions_o.html +17 -16
- package/SVF-doxygen/html/html/functions_p.html +16 -13
- package/SVF-doxygen/html/html/functions_r.html +6 -8
- package/SVF-doxygen/html/html/functions_s.html +14 -16
- package/SVF-doxygen/html/html/functions_t.html +9 -9
- package/SVF-doxygen/html/html/functions_type_l.html +1 -4
- package/SVF-doxygen/html/html/functions_type_m.html +1 -1
- package/SVF-doxygen/html/html/functions_type_n.html +3 -0
- package/SVF-doxygen/html/html/functions_type_o.html +0 -3
- package/SVF-doxygen/html/html/functions_type_v.html +0 -3
- package/SVF-doxygen/html/html/functions_u.html +3 -3
- package/SVF-doxygen/html/html/functions_v.html +8 -10
- package/SVF-doxygen/html/html/functions_vars_c.html +3 -3
- package/SVF-doxygen/html/html/functions_vars_d.html +6 -0
- package/SVF-doxygen/html/html/functions_vars_e.html +3 -0
- package/SVF-doxygen/html/html/functions_vars_i.html +7 -0
- package/SVF-doxygen/html/html/functions_vars_l.html +3 -3
- package/SVF-doxygen/html/html/functions_vars_m.html +0 -12
- package/SVF-doxygen/html/html/functions_vars_o.html +3 -3
- package/SVF-doxygen/html/html/functions_vars_p.html +3 -0
- package/SVF-doxygen/html/html/functions_vars_r.html +0 -3
- package/SVF-doxygen/html/html/functions_vars_v.html +3 -3
- package/SVF-doxygen/html/html/functions_vars_y.html +0 -3
- package/SVF-doxygen/html/html/functions_w.html +5 -6
- package/SVF-doxygen/html/html/functions_y.html +0 -3
- package/SVF-doxygen/html/html/globals_f.html +3 -3
- package/SVF-doxygen/html/html/globals_func_i.html +8 -8
- package/SVF-doxygen/html/html/globals_func_s.html +6 -6
- package/SVF-doxygen/html/html/globals_r.html +3 -3
- package/SVF-doxygen/html/html/globals_s.html +12 -14
- package/SVF-doxygen/html/html/hierarchy.html +176 -173
- package/SVF-doxygen/html/html/menudata.js +2 -1
- package/SVF-doxygen/html/html/namespaceSVF.html +70 -32
- package/SVF-doxygen/html/html/namespaceSVF_1_1SVFUtil.html +13 -12
- package/SVF-doxygen/html/html/namespacemembers_type_v.html +6 -0
- package/SVF-doxygen/html/html/namespacemembers_v.html +6 -0
- package/SVF-doxygen/html/html/search/all_10.js +4 -3
- package/SVF-doxygen/html/html/search/all_12.js +4 -4
- package/SVF-doxygen/html/html/search/all_13.js +13 -13
- package/SVF-doxygen/html/html/search/all_14.js +6 -6
- package/SVF-doxygen/html/html/search/all_15.js +2 -2
- package/SVF-doxygen/html/html/search/all_16.js +5 -4
- package/SVF-doxygen/html/html/search/all_17.js +2 -1
- package/SVF-doxygen/html/html/search/all_19.js +0 -1
- package/SVF-doxygen/html/html/search/all_2.js +2 -0
- package/SVF-doxygen/html/html/search/all_3.js +2 -1
- package/SVF-doxygen/html/html/search/all_4.js +5 -2
- package/SVF-doxygen/html/html/search/all_5.js +1 -0
- package/SVF-doxygen/html/html/search/all_6.js +6 -6
- package/SVF-doxygen/html/html/search/all_7.js +5 -3
- package/SVF-doxygen/html/html/search/all_8.js +2 -0
- package/SVF-doxygen/html/html/search/all_9.js +6 -4
- package/SVF-doxygen/html/html/search/all_c.js +4 -5
- package/SVF-doxygen/html/html/search/all_d.js +1 -6
- package/SVF-doxygen/html/html/search/all_e.js +5 -5
- package/SVF-doxygen/html/html/search/all_f.js +2 -3
- package/SVF-doxygen/html/html/search/classes_12.js +0 -1
- package/SVF-doxygen/html/html/search/classes_7.js +2 -0
- package/SVF-doxygen/html/html/search/classes_b.js +1 -0
- package/SVF-doxygen/html/html/search/classes_f.js +1 -0
- package/SVF-doxygen/html/html/search/enums_1.js +1 -0
- package/SVF-doxygen/html/html/search/enumvalues_13.js +1 -1
- package/SVF-doxygen/html/html/search/enumvalues_2.js +1 -0
- package/SVF-doxygen/html/html/search/functions_1.js +2 -0
- package/SVF-doxygen/html/html/search/functions_10.js +3 -3
- package/SVF-doxygen/html/html/search/functions_13.js +1 -1
- package/SVF-doxygen/html/html/search/functions_3.js +3 -2
- package/SVF-doxygen/html/html/search/functions_6.js +5 -3
- package/SVF-doxygen/html/html/search/functions_8.js +3 -3
- package/SVF-doxygen/html/html/search/functions_b.js +0 -1
- package/SVF-doxygen/html/html/search/functions_c.js +0 -1
- package/SVF-doxygen/html/html/search/functions_d.js +1 -1
- package/SVF-doxygen/html/html/search/functions_f.js +1 -0
- package/SVF-doxygen/html/html/search/searchdata.js +1 -1
- package/SVF-doxygen/html/html/search/typedefs_14.js +2 -1
- package/SVF-doxygen/html/html/search/typedefs_b.js +1 -2
- package/SVF-doxygen/html/html/search/typedefs_c.js +1 -1
- package/SVF-doxygen/html/html/search/typedefs_d.js +1 -0
- package/SVF-doxygen/html/html/search/typedefs_e.js +0 -1
- package/SVF-doxygen/html/html/search/variables_10.js +1 -0
- package/SVF-doxygen/html/html/search/variables_12.js +0 -1
- package/SVF-doxygen/html/html/search/variables_14.js +2 -2
- package/SVF-doxygen/html/html/search/variables_15.js +1 -1
- package/SVF-doxygen/html/html/search/variables_16.js +1 -1
- package/SVF-doxygen/html/html/search/variables_19.js +0 -1
- package/SVF-doxygen/html/html/search/variables_3.js +1 -1
- package/SVF-doxygen/html/html/search/variables_4.js +2 -0
- package/SVF-doxygen/html/html/search/variables_5.js +1 -0
- package/SVF-doxygen/html/html/search/variables_6.js +1 -1
- package/SVF-doxygen/html/html/search/variables_9.js +3 -1
- package/SVF-doxygen/html/html/search/variables_c.js +1 -1
- package/SVF-doxygen/html/html/search/variables_d.js +0 -4
- package/SVF-doxygen/html/html/search/variables_e.js +2 -2
- package/SVF-doxygen/html/html/search/variables_f.js +1 -1
- package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01CoreBitVector_01_4-members.html +81 -0
- package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01CoreBitVector_01_4.html +126 -0
- package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01NodePair_01_4.html +3 -3
- package/SVF-doxygen/html/html/structSVF_1_1VersionedFlowSensitive_1_1SCC_1_1NodeData-members.html +83 -0
- package/SVF-doxygen/html/html/structSVF_1_1VersionedFlowSensitive_1_1SCC_1_1NodeData.html +145 -0
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01CHGraph_01_5_01_4.html +12 -12
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ConstraintGraph_01_5_01_4.html +1 -1
- package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ICFG_01_5_01_4.html +1 -1
- package/SVF-doxygen/html/html/structstd_1_1hash_3_01SVF_1_1NodePair_01_4.html +3 -3
- package/SVF-doxygen/html/html/structstd_1_1hash_3_01SVF_1_1SmallVector_3_01T_00_01N_01_4_01_4.html +3 -3
- package/SVF-doxygen/html/html/structstd_1_1hash_3_01llvm_1_1SparseBitVector_3_01N_01_4_01_4.html +3 -3
- package/SVF-doxygen/html/html/structstd_1_1hash_3_01std_1_1vector_3_01T_01_4_01_4-members.html +81 -0
- package/SVF-doxygen/html/html/structstd_1_1hash_3_01std_1_1vector_3_01T_01_4_01_4.html +129 -0
- package/SVF-doxygen/html/html/svf-ex_8cpp.html +2 -2
- package/SVF-doxygen/html/html/svf-ex_8cpp_source.html +1 -1
- package/SVF-doxygen/html/html/tools_2DDA_2CMakeLists_8txt.html +1 -1
- package/SVF-doxygen/html/html/tools_2Example_2CMakeLists_8txt.html +1 -1
- package/SVF-doxygen/html/html/tools_2MTA_2CMakeLists_8txt.html +1 -1
- package/SVF-doxygen/html/html/tools_2SABER_2CMakeLists_8txt.html +1 -1
- package/SVF-doxygen/html/html/tools_2WPA_2CMakeLists_8txt.html +9 -9
- package/include/Graphs/SVFGStat.h +10 -10
- package/include/MemoryModel/PTAStat.h +8 -2
- package/include/Util/CoreBitVector.h +8 -0
- package/include/Util/Options.h +6 -0
- package/include/Util/SVFBasicTypes.h +22 -2
- package/include/WPA/VersionedFlowSensitive.h +96 -65
- package/lib/MemoryModel/PointsTo.cpp +3 -3
- package/lib/SVF-FE/CHG.cpp +3 -2
- package/lib/Util/Options.cpp +16 -0
- package/lib/Util/PTAStat.cpp +16 -2
- package/lib/Util/SVFUtil.cpp +1 -0
- package/lib/WPA/VersionedFlowSensitive.cpp +503 -229
- package/lib/WPA/VersionedFlowSensitiveStat.cpp +23 -38
- package/package.json +1 -1
- package/tools/WPA/CMakeLists.txt +3 -1
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
#include "Util/Options.h"
|
|
13
13
|
#include "MemoryModel/PointsTo.h"
|
|
14
14
|
#include <iostream>
|
|
15
|
+
#include <queue>
|
|
16
|
+
#include <thread>
|
|
17
|
+
#include <mutex>
|
|
15
18
|
|
|
16
19
|
using namespace SVF;
|
|
17
20
|
|
|
@@ -28,11 +31,15 @@ VersionedFlowSensitive::VersionedFlowSensitive(PAG *_pag, PTATY type)
|
|
|
28
31
|
: FlowSensitive(_pag, type)
|
|
29
32
|
{
|
|
30
33
|
numPrelabeledNodes = numPrelabelVersions = 0;
|
|
31
|
-
|
|
34
|
+
prelabelingTime = meldLabelingTime = versionPropTime = 0.0;
|
|
32
35
|
// We'll grab vPtD in initialize.
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
37
|
+
for (PAG::const_iterator it = pag->begin(); it != pag->end(); ++it)
|
|
38
|
+
{
|
|
39
|
+
if (SVFUtil::isa<ObjPN>(it->second)) equivalentObject[it->first] = it->first;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
assert(!Options::OPTSVFG && "VFS: -opt-svfg not currently supported with VFS.");
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
void VersionedFlowSensitive::initialize()
|
|
@@ -44,11 +51,15 @@ void VersionedFlowSensitive::initialize()
|
|
|
44
51
|
|
|
45
52
|
vPtD = getVersionedPTDataTy();
|
|
46
53
|
|
|
54
|
+
buildIsStoreLoadMaps();
|
|
55
|
+
buildDeltaMaps();
|
|
56
|
+
consume.resize(svfg->getTotalNodeNum());
|
|
57
|
+
yield.resize(svfg->getTotalNodeNum());
|
|
58
|
+
|
|
47
59
|
prelabel();
|
|
48
60
|
meldLabel();
|
|
49
|
-
mapMeldVersions();
|
|
50
61
|
|
|
51
|
-
|
|
62
|
+
removeAllIndirectSVFGEdges();
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
void VersionedFlowSensitive::finalize()
|
|
@@ -72,10 +83,9 @@ void VersionedFlowSensitive::prelabel(void)
|
|
|
72
83
|
// l: *p = q.
|
|
73
84
|
// If p points to o (Andersen's), l yields a new version for o.
|
|
74
85
|
NodeID p = stn->getPAGDstNodeID();
|
|
75
|
-
ObjToMeldVersionMap &myl = meldYield[l];
|
|
76
86
|
for (NodeID o : ander->getPts(p))
|
|
77
87
|
{
|
|
78
|
-
|
|
88
|
+
prelabeledObjects.insert(o);
|
|
79
89
|
}
|
|
80
90
|
|
|
81
91
|
vWorklist.push(l);
|
|
@@ -91,10 +101,9 @@ void VersionedFlowSensitive::prelabel(void)
|
|
|
91
101
|
const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(ln);
|
|
92
102
|
if (mr != nullptr)
|
|
93
103
|
{
|
|
94
|
-
ObjToMeldVersionMap &mcl = meldConsume[l];
|
|
95
104
|
for (const NodeID o : mr->getPointsTo())
|
|
96
105
|
{
|
|
97
|
-
|
|
106
|
+
prelabeledObjects.insert(o);
|
|
98
107
|
}
|
|
99
108
|
|
|
100
109
|
// Push into worklist because its consume == its yield.
|
|
@@ -108,220 +117,412 @@ void VersionedFlowSensitive::prelabel(void)
|
|
|
108
117
|
prelabelingTime = (end - start) / TIMEINTERVAL;
|
|
109
118
|
}
|
|
110
119
|
|
|
111
|
-
void VersionedFlowSensitive::meldLabel(void)
|
|
120
|
+
void VersionedFlowSensitive::meldLabel(void)
|
|
121
|
+
{
|
|
112
122
|
double start = stat->getClk(true);
|
|
113
123
|
|
|
114
|
-
|
|
115
|
-
NodeID l = vWorklist.pop();
|
|
116
|
-
const SVFGNode *ln = svfg->getSVFGNode(l);
|
|
117
|
-
|
|
118
|
-
// Propagate l's y to lp's c for all l --o--> lp.
|
|
119
|
-
for (const SVFGEdge *e : ln->getOutEdges()) {
|
|
120
|
-
const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
|
|
121
|
-
if (!ie) continue;
|
|
122
|
-
|
|
123
|
-
NodeID lp = ie->getDstNode()->getId();
|
|
124
|
-
// Delta nodes had c set already and they are permanent.
|
|
125
|
-
if (delta(lp)) continue;
|
|
126
|
-
|
|
127
|
-
bool lpIsStore = SVFUtil::isa<StoreSVFGNode>(svfg->getSVFGNode(lp));
|
|
128
|
-
// Consume and yield are the same at non-stores, so ignore any self-loop
|
|
129
|
-
// at a non-store.
|
|
130
|
-
if (l == lp && !lpIsStore) continue;
|
|
131
|
-
|
|
132
|
-
// At stores yield != consume, otherwise they are the same (so just use meldConsume).
|
|
133
|
-
const ObjToMeldVersionMap &myl = SVFUtil::isa<StoreSVFGNode>(ln) ? meldYield[l] : meldConsume[l];
|
|
134
|
-
ObjToMeldVersionMap &mclp = meldConsume[lp];
|
|
135
|
-
bool yieldChanged = false;
|
|
136
|
-
for (NodeID o : ie->getPointsTo()) {
|
|
137
|
-
ObjToMeldVersionMap::const_iterator myloIt = myl.find(o);
|
|
138
|
-
if (myloIt == myl.end()) continue;
|
|
139
|
-
|
|
140
|
-
// Yield == consume for non-stores, so when consume is updated, so is yield.
|
|
141
|
-
// For stores, yield was already set, and it's static.
|
|
142
|
-
yieldChanged = (meld(mclp[o], myloIt->second) && !lpIsStore) || yieldChanged;
|
|
143
|
-
}
|
|
124
|
+
assert(Options::VersioningThreads > 0 && "VFS::meldLabel: number of versioning threads must be > 0!");
|
|
144
125
|
|
|
145
|
-
|
|
146
|
-
|
|
126
|
+
// Nodes which have at least one object on them given a prelabel.
|
|
127
|
+
std::vector<const SVFGNode *> prelabeledNodes;
|
|
128
|
+
// Fast query for the above.
|
|
129
|
+
std::vector<bool> isPrelabeled(svfg->getTotalNodeNum(), false);
|
|
130
|
+
while (!vWorklist.empty())
|
|
131
|
+
{
|
|
132
|
+
const NodeID n = vWorklist.pop();
|
|
133
|
+
prelabeledNodes.push_back(svfg->getSVFGNode(n));
|
|
134
|
+
isPrelabeled[n] = true;
|
|
147
135
|
}
|
|
148
136
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
137
|
+
// Delta, delta source, store, and load nodes, which require versions during
|
|
138
|
+
// solving, unlike other nodes with which we can make do with the reliance map.
|
|
139
|
+
std::vector<NodeID> nodesWhichNeedVersions;
|
|
140
|
+
for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
|
|
141
|
+
{
|
|
142
|
+
const NodeID n = it->first;
|
|
143
|
+
if (delta(n) || deltaSource(n) || isStore(n) || isLoad(n)) nodesWhichNeedVersions.push_back(n);
|
|
144
|
+
}
|
|
158
145
|
|
|
159
|
-
|
|
160
|
-
{
|
|
161
|
-
double start = stat->getClk(true);
|
|
146
|
+
std::mutex *versionMutexes = new std::mutex[nodesWhichNeedVersions.size()];
|
|
162
147
|
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
Map<MeldVersion, Version> mvv;
|
|
166
|
-
Version curVersion = 1;
|
|
148
|
+
// Map of footprints to the canonical object "owning" the footprint.
|
|
149
|
+
Map<std::vector<const IndirectSVFGEdge *>, NodeID> footprintOwner;
|
|
167
150
|
|
|
168
|
-
|
|
169
|
-
for (
|
|
151
|
+
std::queue<NodeID> objectQueue;
|
|
152
|
+
for (const NodeID o : prelabeledObjects)
|
|
170
153
|
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
NodeID o = omv.first;
|
|
176
|
-
MeldVersion &mv = omv.second;
|
|
177
|
-
|
|
178
|
-
Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
|
|
179
|
-
// If a mapping for foudnVersion exists, use it, otherwise create a new Version (++),
|
|
180
|
-
// keep track of it ([mv]), and use that.
|
|
181
|
-
Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
|
|
182
|
-
setConsume(l, o, v);
|
|
183
|
-
// At non-stores, consume == yield.
|
|
184
|
-
// Unlike meldYield, we use yield for all yields, not just where consume != yield.
|
|
185
|
-
// This affords simplicity later. meldYield is expensive to explicitly represent
|
|
186
|
-
// always, unlike yield.
|
|
187
|
-
if (!lIsStore) setYield(l, o, v);
|
|
188
|
-
}
|
|
154
|
+
// "Touch" maps with o so we don't need to lock on them.
|
|
155
|
+
versionReliance[o];
|
|
156
|
+
stmtReliance[o];
|
|
157
|
+
objectQueue.push(o);
|
|
189
158
|
}
|
|
190
159
|
|
|
191
|
-
|
|
192
|
-
|
|
160
|
+
std::mutex objectQueueMutex;
|
|
161
|
+
std::mutex footprintOwnerMutex;
|
|
162
|
+
|
|
163
|
+
auto meldVersionWorker = [this, &footprintOwner, &objectQueue,
|
|
164
|
+
&objectQueueMutex, &footprintOwnerMutex, &versionMutexes,
|
|
165
|
+
&prelabeledNodes, &isPrelabeled, &nodesWhichNeedVersions]
|
|
166
|
+
(const unsigned thread)
|
|
193
167
|
{
|
|
194
|
-
|
|
195
|
-
for (ObjToMeldVersionMap::value_type &omv : lomv.second)
|
|
168
|
+
while (true)
|
|
196
169
|
{
|
|
197
|
-
NodeID o
|
|
198
|
-
|
|
170
|
+
NodeID o;
|
|
171
|
+
{ std::lock_guard<std::mutex> guard(objectQueueMutex);
|
|
172
|
+
// No more objects? Done.
|
|
173
|
+
if (objectQueue.empty()) return;
|
|
174
|
+
o = objectQueue.front();
|
|
175
|
+
objectQueue.pop();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 1. Compute the SCCs for the nodes on the graph overlay of o.
|
|
179
|
+
// For starting nodes, we only need those which did prelabeling for o specifically.
|
|
180
|
+
// TODO: maybe we should move this to prelabel with a map (o -> starting nodes).
|
|
181
|
+
std::vector<const SVFGNode *> osStartingNodes;
|
|
182
|
+
for (const SVFGNode *sn : prelabeledNodes)
|
|
183
|
+
{
|
|
184
|
+
if (const StoreSVFGNode *store = SVFUtil::dyn_cast<StoreSVFGNode>(sn))
|
|
185
|
+
{
|
|
186
|
+
const NodeID p = store->getPAGDstNodeID();
|
|
187
|
+
if (this->ander->getPts(p).test(o)) osStartingNodes.push_back(sn);
|
|
188
|
+
}
|
|
189
|
+
else if (delta(sn->getId()))
|
|
190
|
+
{
|
|
191
|
+
const MRSVFGNode *mr = SVFUtil::dyn_cast<MRSVFGNode>(sn);
|
|
192
|
+
if (mr != nullptr)
|
|
193
|
+
{
|
|
194
|
+
if (mr->getPointsTo().test(o)) osStartingNodes.push_back(sn);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
std::vector<int> partOf;
|
|
200
|
+
std::vector<const IndirectSVFGEdge *> footprint;
|
|
201
|
+
unsigned numSCCs = SCC::detectSCCs(this, this->svfg, o, osStartingNodes, partOf, footprint);
|
|
202
|
+
|
|
203
|
+
// 2. Skip any further processing of a footprint we have seen before.
|
|
204
|
+
{ std::lock_guard<std::mutex> guard(footprintOwnerMutex);
|
|
205
|
+
const Map<std::vector<const IndirectSVFGEdge *>, NodeID>::const_iterator canonOwner
|
|
206
|
+
= footprintOwner.find(footprint);
|
|
207
|
+
if (canonOwner == footprintOwner.end())
|
|
208
|
+
{
|
|
209
|
+
this->equivalentObject[o] = o;
|
|
210
|
+
footprintOwner[footprint] = o;
|
|
211
|
+
}
|
|
212
|
+
else
|
|
213
|
+
{
|
|
214
|
+
this->equivalentObject[o] = canonOwner->second;
|
|
215
|
+
// Same version and stmt reliance as the canonical. During solving we cannot just reuse
|
|
216
|
+
// the canonical object's reliance because it may change due to on-the-fly call graph
|
|
217
|
+
// construction. Something like copy-on-write could be good... probably negligible.
|
|
218
|
+
this->versionReliance.at(o) = this->versionReliance.at(canonOwner->second);
|
|
219
|
+
this->stmtReliance.at(o) = this->stmtReliance.at(canonOwner->second);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// 3. a. Initialise the MeldVersion of prelabeled nodes (SCCs).
|
|
225
|
+
// b. Initialise a todo list of all the nodes we need to version,
|
|
226
|
+
// sorted according to topological order.
|
|
227
|
+
// We will use a map of sccs to meld versions for what is consumed.
|
|
228
|
+
std::vector<MeldVersion> sccToMeldVersion(numSCCs);
|
|
229
|
+
// At stores, what is consumed is different to what is yielded, so we
|
|
230
|
+
// maintain that separately.
|
|
231
|
+
Map<NodeID, MeldVersion> storesYieldedMeldVersion;
|
|
232
|
+
// SVFG nodes of interest -- those part of an SCC from the starting nodes.
|
|
233
|
+
std::vector<NodeID> todoList;
|
|
234
|
+
unsigned bit = 0;
|
|
235
|
+
for (NodeID n = 0; n < partOf.size(); ++n)
|
|
236
|
+
{
|
|
237
|
+
if (partOf[n] == -1) continue;
|
|
238
|
+
|
|
239
|
+
if (isPrelabeled[n])
|
|
240
|
+
{
|
|
241
|
+
if (this->isStore(n)) storesYieldedMeldVersion[n].set(bit);
|
|
242
|
+
else sccToMeldVersion[partOf[n]].set(bit);
|
|
243
|
+
++bit;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
todoList.push_back(n);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Sort topologically so each nodes is only visited once.
|
|
250
|
+
auto cmp = [&partOf](const NodeID a, const NodeID b)
|
|
251
|
+
{
|
|
252
|
+
return partOf[a] > partOf[b];
|
|
253
|
+
};
|
|
254
|
+
std::sort(todoList.begin(), todoList.end(), cmp);
|
|
255
|
+
|
|
256
|
+
// 4. a. Do meld versioning.
|
|
257
|
+
// b. Determine SCC reliances.
|
|
258
|
+
// c. Build a footprint for o (all edges which it is found on).
|
|
259
|
+
// d. Determine which SCCs belong to stores.
|
|
260
|
+
|
|
261
|
+
// sccReliance[x] = { y_1, y_2, ... } if there exists an edge from a node
|
|
262
|
+
// in SCC x to SCC y_i.
|
|
263
|
+
std::vector<Set<int>> sccReliance(numSCCs);
|
|
264
|
+
// Maps SCC to the store it corresponds to or -1 if it doesn't. TODO: unsigned vs signed -- nasty.
|
|
265
|
+
std::vector<int> storeSCC(numSCCs, -1);
|
|
266
|
+
for (size_t i = 0; i < todoList.size(); ++i)
|
|
267
|
+
{
|
|
268
|
+
const NodeID n = todoList[i];
|
|
269
|
+
const SVFGNode *sn = this->svfg->getSVFGNode(n);
|
|
270
|
+
const bool nIsStore = this->isStore(n);
|
|
271
|
+
|
|
272
|
+
int nSCC = partOf[n];
|
|
273
|
+
if (nIsStore) storeSCC[nSCC] = n;
|
|
274
|
+
|
|
275
|
+
// Given n -> m, the yielded version of n will be melded into m.
|
|
276
|
+
// For stores, that is in storesYieldedMeldVersion, otherwise, consume == yield and
|
|
277
|
+
// we can just use sccToMeldVersion.
|
|
278
|
+
const MeldVersion &nMV = nIsStore ? storesYieldedMeldVersion[n] : sccToMeldVersion[nSCC];
|
|
279
|
+
for (const SVFGEdge *e : sn->getOutEdges())
|
|
280
|
+
{
|
|
281
|
+
const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
|
|
282
|
+
if (!ie) continue;
|
|
283
|
+
|
|
284
|
+
const NodeID m = ie->getDstNode()->getId();
|
|
285
|
+
// Ignoreedges which don't involve o.
|
|
286
|
+
if (!ie->getPointsTo().test(o)) continue;
|
|
287
|
+
|
|
288
|
+
int mSCC = partOf[m];
|
|
289
|
+
|
|
290
|
+
// There is an edge from the SCC n belongs to to that m belongs to.
|
|
291
|
+
sccReliance[nSCC].insert(mSCC);
|
|
292
|
+
|
|
293
|
+
// Ignore edges to delta nodes (prelabeled consume).
|
|
294
|
+
// No point propagating when n's SCC == m's SCC (same meld version there)
|
|
295
|
+
// except when it is a store, because we are actually propagating n's yielded
|
|
296
|
+
// into m's consumed. Store nodes are in their own SCCs, so it is a self
|
|
297
|
+
// loop on a store node.
|
|
298
|
+
if (!this->delta(m) && (nSCC != mSCC || nIsStore))
|
|
299
|
+
{
|
|
300
|
+
sccToMeldVersion[mSCC] |= nMV;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// 5. Transform meld versions belonging to SCCs into versions.
|
|
306
|
+
Map<MeldVersion, Version> mvv;
|
|
307
|
+
std::vector<Version> sccToVersion(numSCCs, invalidVersion);
|
|
308
|
+
Version curVersion = 0;
|
|
309
|
+
for (int scc = 0; scc < sccToMeldVersion.size(); ++scc)
|
|
310
|
+
{
|
|
311
|
+
const MeldVersion &mv = sccToMeldVersion[scc];
|
|
312
|
+
Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
|
|
313
|
+
Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
|
|
314
|
+
sccToVersion[scc] = v;
|
|
315
|
+
}
|
|
199
316
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
317
|
+
sccToMeldVersion.clear();
|
|
318
|
+
|
|
319
|
+
// Same for storesYieldedMeldVersion.
|
|
320
|
+
Map<NodeID, Version> storesYieldedVersion;
|
|
321
|
+
for (const std::pair<NodeID, MeldVersion> &nmv : storesYieldedMeldVersion)
|
|
322
|
+
{
|
|
323
|
+
const NodeID n = nmv.first;
|
|
324
|
+
const MeldVersion &mv = nmv.second;
|
|
325
|
+
|
|
326
|
+
Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
|
|
327
|
+
Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
|
|
328
|
+
storesYieldedVersion[n] = v;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
storesYieldedMeldVersion.clear();
|
|
332
|
+
|
|
333
|
+
mvv.clear();
|
|
334
|
+
|
|
335
|
+
// 6. From SCC reliance, determine version reliances.
|
|
336
|
+
Map<Version, std::vector<Version>> &osVersionReliance = this->versionReliance.at(o);
|
|
337
|
+
for (int scc = 0; scc < numSCCs; ++scc)
|
|
338
|
+
{
|
|
339
|
+
if (sccReliance[scc].empty()) continue;
|
|
340
|
+
|
|
341
|
+
// Some consume relies on a yield. When it's a store, we need to pick whether to
|
|
342
|
+
// use the consume or yield unlike when it is not because they are the same.
|
|
343
|
+
const Version version
|
|
344
|
+
= storeSCC[scc] != -1 ? storesYieldedVersion[storeSCC[scc]] : sccToVersion[scc];
|
|
345
|
+
|
|
346
|
+
std::vector<Version> &reliantVersions = osVersionReliance[version];
|
|
347
|
+
for (const int reliantSCC : sccReliance[scc])
|
|
348
|
+
{
|
|
349
|
+
const Version reliantVersion = sccToVersion[reliantSCC];
|
|
350
|
+
if (version != reliantVersion)
|
|
351
|
+
{
|
|
352
|
+
// sccReliance is a set, no need to worry about duplicates.
|
|
353
|
+
reliantVersions.push_back(reliantVersion);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// 7. a. Save versions for nodes which need them.
|
|
359
|
+
// b. Fill in stmtReliance.
|
|
360
|
+
// TODO: maybe randomise iteration order for less contention? Needs profiling.
|
|
361
|
+
Map<Version, NodeBS> &osStmtReliance = this->stmtReliance.at(o);
|
|
362
|
+
for (size_t i = 0; i < nodesWhichNeedVersions.size(); ++i)
|
|
363
|
+
{
|
|
364
|
+
const NodeID n = nodesWhichNeedVersions[i];
|
|
365
|
+
std::mutex &mutex = versionMutexes[i];
|
|
366
|
+
|
|
367
|
+
const int scc = partOf[n];
|
|
368
|
+
if (scc == -1) continue;
|
|
369
|
+
|
|
370
|
+
std::lock_guard<std::mutex> guard(mutex);
|
|
371
|
+
|
|
372
|
+
const Version c = sccToVersion[scc];
|
|
373
|
+
if (c != invalidVersion)
|
|
374
|
+
{
|
|
375
|
+
this->setConsume(n, o, c);
|
|
376
|
+
if (this->isStore(n) || this->isLoad(n)) osStmtReliance[c].set(n);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (this->isStore(n))
|
|
380
|
+
{
|
|
381
|
+
const Map<NodeID, Version>::const_iterator yIt = storesYieldedVersion.find(n);
|
|
382
|
+
if (yIt != storesYieldedVersion.end()) this->setYield(n, o, yIt->second);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
203
385
|
}
|
|
204
|
-
}
|
|
386
|
+
};
|
|
205
387
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
388
|
+
std::vector<std::thread> workers;
|
|
389
|
+
for (unsigned i = 0; i < Options::VersioningThreads; ++i) workers.push_back(std::thread(meldVersionWorker, i));
|
|
390
|
+
for (std::thread &worker : workers) worker.join();
|
|
391
|
+
|
|
392
|
+
delete[] versionMutexes;
|
|
209
393
|
|
|
210
394
|
double end = stat->getClk(true);
|
|
211
|
-
|
|
395
|
+
meldLabelingTime = (end - start) / TIMEINTERVAL;
|
|
212
396
|
}
|
|
213
397
|
|
|
214
|
-
bool VersionedFlowSensitive::
|
|
398
|
+
bool VersionedFlowSensitive::meld(MeldVersion &mv1, const MeldVersion &mv2)
|
|
215
399
|
{
|
|
216
|
-
//
|
|
217
|
-
|
|
400
|
+
// Meld operator is union of bit vectors.
|
|
401
|
+
return mv1 |= mv2;
|
|
402
|
+
}
|
|
218
403
|
|
|
219
|
-
|
|
220
|
-
|
|
404
|
+
bool VersionedFlowSensitive::delta(const NodeID l) const
|
|
405
|
+
{
|
|
406
|
+
assert(l < deltaMap.size() && "VFS::delta: deltaMap is missing SVFG nodes!");
|
|
407
|
+
return deltaMap[l];
|
|
408
|
+
}
|
|
221
409
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
isDelta = !callsites.empty();
|
|
234
|
-
}
|
|
235
|
-
else if (const CallBlockNode *cbn = svfg->isCallSiteRetSVFGNode(s))
|
|
410
|
+
bool VersionedFlowSensitive::deltaSource(const NodeID l) const
|
|
411
|
+
{
|
|
412
|
+
assert(l < deltaSourceMap.size() && "VFS::delta: deltaSourceMap is missing SVFG nodes!");
|
|
413
|
+
return deltaSourceMap[l];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
void VersionedFlowSensitive::buildIsStoreLoadMaps(void)
|
|
417
|
+
{
|
|
418
|
+
isStoreMap.resize(svfg->getTotalNodeNum(), false);
|
|
419
|
+
isLoadMap.resize(svfg->getTotalNodeNum(), false);
|
|
420
|
+
for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
|
|
236
421
|
{
|
|
237
|
-
|
|
422
|
+
if (SVFUtil::isa<StoreSVFGNode>(it->second)) isStoreMap[it->first] = true;
|
|
423
|
+
else if (SVFUtil::isa<LoadSVFGNode>(it->second)) isLoadMap[it->first] = true;
|
|
238
424
|
}
|
|
239
|
-
|
|
240
|
-
deltaCache[l] = isDelta;
|
|
241
|
-
return isDelta;
|
|
242
425
|
}
|
|
243
426
|
|
|
427
|
+
bool VersionedFlowSensitive::isStore(const NodeID l) const
|
|
428
|
+
{
|
|
429
|
+
assert(l < isStoreMap.size() && "VFS::isStore: isStoreMap is missing SVFG nodes!");
|
|
430
|
+
return isStoreMap[l];
|
|
431
|
+
}
|
|
244
432
|
|
|
245
|
-
|
|
433
|
+
bool VersionedFlowSensitive::isLoad(const NodeID l) const
|
|
246
434
|
{
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
nv.set(++meldVersions[o]);
|
|
250
|
-
return nv;
|
|
435
|
+
assert(l < isLoadMap.size() && "VFS::isLoad: isLoadMap is missing SVFG nodes!");
|
|
436
|
+
return isLoadMap[l];
|
|
251
437
|
}
|
|
252
438
|
|
|
253
|
-
void VersionedFlowSensitive::
|
|
439
|
+
void VersionedFlowSensitive::buildDeltaMaps(void)
|
|
254
440
|
{
|
|
255
|
-
|
|
256
|
-
Map<NodeID, Map<Version, Set<Version>>> setVersionReliance;
|
|
441
|
+
deltaMap.resize(svfg->getTotalNodeNum(), false);
|
|
257
442
|
|
|
258
|
-
|
|
259
|
-
|
|
443
|
+
// Call block nodes corresponding to all delta nodes.
|
|
444
|
+
Set<const CallBlockNode *> deltaCBNs;
|
|
445
|
+
|
|
446
|
+
for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
|
|
260
447
|
{
|
|
261
|
-
NodeID l = it->first;
|
|
262
|
-
const SVFGNode *
|
|
263
|
-
|
|
448
|
+
const NodeID l = it->first;
|
|
449
|
+
const SVFGNode *s = it->second;
|
|
450
|
+
|
|
451
|
+
// Cases:
|
|
452
|
+
// * Function entry: can get new incoming indirect edges through ind. callsites.
|
|
453
|
+
// * Callsite returns: can get new incoming indirect edges if the callsite is indirect.
|
|
454
|
+
// * Otherwise: static.
|
|
455
|
+
bool isDelta = false;
|
|
456
|
+
if (const SVFFunction *fn = svfg->isFunEntrySVFGNode(s))
|
|
264
457
|
{
|
|
265
|
-
|
|
266
|
-
|
|
458
|
+
PTACallGraphEdge::CallInstSet callsites;
|
|
459
|
+
/// use pre-analysis call graph to approximate all potential callsites
|
|
460
|
+
ander->getPTACallGraph()->getIndCallSitesInvokingCallee(fn, callsites);
|
|
461
|
+
isDelta = !callsites.empty();
|
|
267
462
|
|
|
268
|
-
|
|
463
|
+
if (isDelta)
|
|
269
464
|
{
|
|
270
|
-
//
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
const Version y = getYield(l, o);
|
|
274
|
-
if (y == invalidVersion) continue;
|
|
275
|
-
const Version cp = getConsume(lp, o);
|
|
276
|
-
if (cp == invalidVersion) continue;
|
|
277
|
-
|
|
278
|
-
if (cp != y) setVersionReliance[o][y].insert(cp);
|
|
465
|
+
// TODO: could we use deltaCBNs in the call above, avoiding this loop?
|
|
466
|
+
for (const CallBlockNode *cbn : callsites) deltaCBNs.insert(cbn);
|
|
279
467
|
}
|
|
280
468
|
}
|
|
469
|
+
else if (const CallBlockNode *cbn = svfg->isCallSiteRetSVFGNode(s))
|
|
470
|
+
{
|
|
471
|
+
isDelta = cbn->isIndirectCall();
|
|
472
|
+
if (isDelta) deltaCBNs.insert(cbn);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
deltaMap[l] = isDelta;
|
|
476
|
+
}
|
|
281
477
|
|
|
282
|
-
|
|
283
|
-
|
|
478
|
+
deltaSourceMap.resize(svfg->getTotalNodeNum(), false);
|
|
479
|
+
|
|
480
|
+
for (SVFG::const_iterator it = svfg->begin(); it != svfg->end(); ++it)
|
|
481
|
+
{
|
|
482
|
+
const NodeID l = it->first;
|
|
483
|
+
const SVFGNode *s = it->second;
|
|
484
|
+
|
|
485
|
+
if (const CallBlockNode *cbn = SVFUtil::dyn_cast<CallBlockNode>(s->getICFGNode()))
|
|
284
486
|
{
|
|
285
|
-
|
|
286
|
-
if (lovmIt != consume.end())
|
|
287
|
-
{
|
|
288
|
-
for (const ObjToVersionMap::value_type &ov : lovmIt->second)
|
|
289
|
-
{
|
|
290
|
-
const NodeID o = ov.first;
|
|
291
|
-
const Version v = ov.second;
|
|
292
|
-
stmtReliance[o][v].set(l);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
487
|
+
if (deltaCBNs.find(cbn) != deltaCBNs.end()) deltaSourceMap[l] = true;
|
|
295
488
|
}
|
|
489
|
+
|
|
490
|
+
// TODO: this is an over-approximation but it sound, marking every formal out as
|
|
491
|
+
// a delta-source.
|
|
492
|
+
if (SVFUtil::isa<FormalOUTSVFGNode>(s)) deltaSourceMap[l] = true;
|
|
296
493
|
}
|
|
494
|
+
}
|
|
297
495
|
|
|
298
|
-
|
|
496
|
+
void VersionedFlowSensitive::removeAllIndirectSVFGEdges(void)
|
|
497
|
+
{
|
|
498
|
+
for (SVFG::iterator nodeIt = svfg->begin(); nodeIt != svfg->end(); ++nodeIt)
|
|
299
499
|
{
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
500
|
+
SVFGNode *sn = nodeIt->second;
|
|
501
|
+
|
|
502
|
+
const SVFGEdgeSetTy &inEdges = sn->getInEdges();
|
|
503
|
+
std::vector<SVFGEdge *> toDeleteFromIn;
|
|
504
|
+
for (SVFGEdge *e : inEdges)
|
|
303
505
|
{
|
|
304
|
-
|
|
305
|
-
const Set<Version> &vs = vvs.second;
|
|
306
|
-
osRelying[v] = std::vector<Version>(vs.begin(), vs.end());
|
|
506
|
+
if (SVFUtil::isa<IndirectSVFGEdge>(e)) toDeleteFromIn.push_back(e);
|
|
307
507
|
}
|
|
508
|
+
|
|
509
|
+
for (SVFGEdge *e : toDeleteFromIn) svfg->removeSVFGEdge(e);
|
|
510
|
+
|
|
511
|
+
// Only need to iterate over incoming edges for each node because edges
|
|
512
|
+
// will be deleted from in/out through removeSVFGEdge.
|
|
308
513
|
}
|
|
309
514
|
|
|
310
|
-
|
|
311
|
-
relianceTime = (end - start) / TIMEINTERVAL;
|
|
515
|
+
setGraph(svfg);
|
|
312
516
|
}
|
|
313
517
|
|
|
314
518
|
void VersionedFlowSensitive::propagateVersion(NodeID o, Version v)
|
|
315
519
|
{
|
|
316
520
|
double start = stat->getClk();
|
|
317
521
|
|
|
318
|
-
|
|
319
|
-
|
|
522
|
+
const std::vector<Version> &reliantVersions = getReliantVersions(o, v);
|
|
523
|
+
for (Version r : reliantVersions)
|
|
320
524
|
{
|
|
321
|
-
|
|
322
|
-
{
|
|
323
|
-
propagateVersion(o, v, r, false);
|
|
324
|
-
}
|
|
525
|
+
propagateVersion(o, v, r, false);
|
|
325
526
|
}
|
|
326
527
|
|
|
327
528
|
double end = stat->getClk();
|
|
@@ -350,7 +551,7 @@ void VersionedFlowSensitive::propagateVersion(const NodeID o, const Version v, c
|
|
|
350
551
|
pushIntoWorklist(dvp->getId());
|
|
351
552
|
|
|
352
553
|
// Notify nodes which rely on o:vp that it changed.
|
|
353
|
-
for (NodeID s :
|
|
554
|
+
for (NodeID s : getStmtReliance(o, vp)) pushIntoWorklist(s);
|
|
354
555
|
}
|
|
355
556
|
|
|
356
557
|
double end = time ? stat->getClk() : 0.0;
|
|
@@ -380,8 +581,6 @@ void VersionedFlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& newEdges)
|
|
|
380
581
|
NodeID src = e->getSrcNode()->getId();
|
|
381
582
|
NodeID dst = dstNode->getId();
|
|
382
583
|
|
|
383
|
-
assert(delta(dst) && "VFS::updateConnectedNodes: new edges should be to delta nodes!");
|
|
384
|
-
|
|
385
584
|
if (SVFUtil::isa<PHISVFGNode>(dstNode)
|
|
386
585
|
|| SVFUtil::isa<FormalParmSVFGNode>(dstNode)
|
|
387
586
|
|| SVFUtil::isa<ActualRetSVFGNode>(dstNode))
|
|
@@ -393,6 +592,9 @@ void VersionedFlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& newEdges)
|
|
|
393
592
|
const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
|
|
394
593
|
assert(ie != nullptr && "VFS::updateConnectedNodes: given direct edge?");
|
|
395
594
|
|
|
595
|
+
assert(delta(dst) && "VFS::updateConnectedNodes: new edges should be to delta nodes!");
|
|
596
|
+
assert(deltaSource(src) && "VFS::updateConnectedNodes: new indirect edges should be from delta source nodes!");
|
|
597
|
+
|
|
396
598
|
const NodeBS &ept = ie->getPointsTo();
|
|
397
599
|
// For every o, such that src --o--> dst, we need to set up reliance (and propagate).
|
|
398
600
|
for (const NodeID o : ept)
|
|
@@ -402,7 +604,7 @@ void VersionedFlowSensitive::updateConnectedNodes(const SVFGEdgeSetTy& newEdges)
|
|
|
402
604
|
Version dstC = getConsume(dst, o);
|
|
403
605
|
if (dstC == invalidVersion) continue;
|
|
404
606
|
|
|
405
|
-
std::vector<Version> &versionsRelyingOnSrcY =
|
|
607
|
+
std::vector<Version> &versionsRelyingOnSrcY = getReliantVersions(o, srcY);
|
|
406
608
|
if (std::find(versionsRelyingOnSrcY.begin(), versionsRelyingOnSrcY.end(), dstC) == versionsRelyingOnSrcY.end())
|
|
407
609
|
{
|
|
408
610
|
versionsRelyingOnSrcY.push_back(dstC);
|
|
@@ -501,23 +703,19 @@ bool VersionedFlowSensitive::processStore(const StoreSVFGNode* store)
|
|
|
501
703
|
|
|
502
704
|
// For all objects, perform pts(o:y) = pts(o:y) U pts(o:c) at loc,
|
|
503
705
|
// except when a strong update is taking place.
|
|
504
|
-
const
|
|
505
|
-
if (lovmIt != consume.end())
|
|
706
|
+
for (const ObjToVersionMap::value_type &oc : consume[l])
|
|
506
707
|
{
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
const NodeID o = oc.first;
|
|
510
|
-
const Version c = oc.second;
|
|
708
|
+
const NodeID o = oc.first;
|
|
709
|
+
const Version c = oc.second;
|
|
511
710
|
|
|
512
|
-
|
|
513
|
-
|
|
711
|
+
// Strong-updated; don't propagate.
|
|
712
|
+
if (isSU && o == singleton) continue;
|
|
514
713
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
}
|
|
714
|
+
const Version y = getYield(l, o);
|
|
715
|
+
if (y != invalidVersion && vPtD->unionPts(atKey(o, y), atKey(o, c)))
|
|
716
|
+
{
|
|
717
|
+
changed = true;
|
|
718
|
+
changedObjects.set(o);
|
|
521
719
|
}
|
|
522
720
|
}
|
|
523
721
|
|
|
@@ -536,7 +734,7 @@ bool VersionedFlowSensitive::processStore(const StoreSVFGNode* store)
|
|
|
536
734
|
propagateVersion(o, y);
|
|
537
735
|
|
|
538
736
|
// Some o/v pairs changed: statements need to know.
|
|
539
|
-
for (NodeID s :
|
|
737
|
+
for (NodeID s : getStmtReliance(o, y)) pushIntoWorklist(s);
|
|
540
738
|
}
|
|
541
739
|
}
|
|
542
740
|
|
|
@@ -563,75 +761,54 @@ void VersionedFlowSensitive::cluster(void)
|
|
|
563
761
|
PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
|
|
564
762
|
}
|
|
565
763
|
|
|
566
|
-
Version VersionedFlowSensitive::getVersion(const NodeID l, const NodeID o,
|
|
764
|
+
Version VersionedFlowSensitive::getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const
|
|
567
765
|
{
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
ObjToVersionMap::const_iterator foundVersion = cache.ovm->find(o);
|
|
571
|
-
return foundVersion == cache.ovm->end() ? invalidVersion : foundVersion->second;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
// Not const because the cache isn't as it is shared with setVersion.
|
|
575
|
-
LocVersionMap::iterator foundObjToVersionMap = lvm.find(l);
|
|
576
|
-
// If there are no obj -> version maps at l, then obviously there is no version for o.
|
|
577
|
-
if (foundObjToVersionMap == lvm.end()) return invalidVersion;
|
|
578
|
-
|
|
579
|
-
// We can cache lvm[l].
|
|
580
|
-
cache.l = l;
|
|
581
|
-
cache.ovm = &foundObjToVersionMap->second;
|
|
582
|
-
cache.valid = true;
|
|
766
|
+
const Map<NodeID, NodeID>::const_iterator canonObjectIt = equivalentObject.find(o);
|
|
767
|
+
const NodeID op = canonObjectIt == equivalentObject.end() ? o : canonObjectIt->second;
|
|
583
768
|
|
|
584
|
-
ObjToVersionMap
|
|
585
|
-
|
|
769
|
+
const ObjToVersionMap &ovm = lvm[l];
|
|
770
|
+
const ObjToVersionMap::const_iterator foundVersion = ovm.find(op);
|
|
771
|
+
return foundVersion == ovm.end() ? invalidVersion : foundVersion->second;
|
|
586
772
|
}
|
|
587
773
|
|
|
588
|
-
Version VersionedFlowSensitive::getConsume(const NodeID l, const NodeID o)
|
|
774
|
+
Version VersionedFlowSensitive::getConsume(const NodeID l, const NodeID o) const
|
|
589
775
|
{
|
|
590
|
-
return getVersion(l, o,
|
|
776
|
+
return getVersion(l, o, consume);
|
|
591
777
|
}
|
|
592
778
|
|
|
593
|
-
Version VersionedFlowSensitive::getYield(const NodeID l, const NodeID o)
|
|
779
|
+
Version VersionedFlowSensitive::getYield(const NodeID l, const NodeID o) const
|
|
594
780
|
{
|
|
595
|
-
|
|
781
|
+
// Non-store: consume == yield.
|
|
782
|
+
if (isStore(l)) return getVersion(l, o, yield);
|
|
783
|
+
else return getVersion(l, o, consume);
|
|
596
784
|
}
|
|
597
785
|
|
|
598
|
-
void VersionedFlowSensitive::setVersion(const NodeID l, const NodeID o, const Version v,
|
|
786
|
+
void VersionedFlowSensitive::setVersion(const NodeID l, const NodeID o, const Version v, LocVersionMap &lvm)
|
|
599
787
|
{
|
|
600
|
-
if (cache.valid && l == cache.l)
|
|
601
|
-
{
|
|
602
|
-
(*cache.ovm)[o] = v;
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
// This can invalidate the cache but we're updating it in the next statement anyway.
|
|
607
788
|
ObjToVersionMap &ovm = lvm[l];
|
|
608
|
-
|
|
609
|
-
// We can cache lvm[l].
|
|
610
|
-
cache.l = l;
|
|
611
|
-
cache.ovm = &ovm;
|
|
612
|
-
cache.valid = true;
|
|
613
|
-
|
|
614
789
|
ovm[o] = v;
|
|
615
790
|
}
|
|
616
791
|
|
|
617
792
|
void VersionedFlowSensitive::setConsume(const NodeID l, const NodeID o, const Version v)
|
|
618
793
|
{
|
|
619
|
-
setVersion(l, o, v,
|
|
794
|
+
setVersion(l, o, v, consume);
|
|
620
795
|
}
|
|
621
796
|
|
|
622
797
|
void VersionedFlowSensitive::setYield(const NodeID l, const NodeID o, const Version v)
|
|
623
798
|
{
|
|
624
|
-
|
|
799
|
+
// Non-store: consume == yield.
|
|
800
|
+
if (isStore(l)) setVersion(l, o, v, yield);
|
|
801
|
+
else setVersion(l, o, v, consume);
|
|
625
802
|
}
|
|
626
803
|
|
|
627
|
-
|
|
804
|
+
std::vector<Version> &VersionedFlowSensitive::getReliantVersions(const NodeID o, const Version v)
|
|
628
805
|
{
|
|
629
|
-
|
|
806
|
+
return versionReliance[o][v];
|
|
630
807
|
}
|
|
631
808
|
|
|
632
|
-
|
|
809
|
+
NodeBS &VersionedFlowSensitive::getStmtReliance(const NodeID o, const Version v)
|
|
633
810
|
{
|
|
634
|
-
|
|
811
|
+
return stmtReliance[o][v];
|
|
635
812
|
}
|
|
636
813
|
|
|
637
814
|
void VersionedFlowSensitive::dumpReliances(void) const
|
|
@@ -700,7 +877,7 @@ void VersionedFlowSensitive::dumpLocVersionMaps(void) const
|
|
|
700
877
|
bool locPrinted = false;
|
|
701
878
|
for (const LocVersionMap *lvm : { &consume, &yield })
|
|
702
879
|
{
|
|
703
|
-
if (lvm->
|
|
880
|
+
if (lvm->at(loc).empty()) continue;
|
|
704
881
|
if (!locPrinted)
|
|
705
882
|
{
|
|
706
883
|
SVFUtil::outs() << " " << "SVFG node " << loc << "\n";
|
|
@@ -741,3 +918,100 @@ void VersionedFlowSensitive::dumpMeldVersion(MeldVersion &v)
|
|
|
741
918
|
|
|
742
919
|
SVFUtil::outs() << " ]";
|
|
743
920
|
}
|
|
921
|
+
|
|
922
|
+
unsigned VersionedFlowSensitive::SCC::detectSCCs(VersionedFlowSensitive *vfs,
|
|
923
|
+
const SVFG *svfg, const NodeID object,
|
|
924
|
+
const std::vector<const SVFGNode *> &startingNodes,
|
|
925
|
+
std::vector<int> &partOf,
|
|
926
|
+
std::vector<const IndirectSVFGEdge *> &footprint)
|
|
927
|
+
{
|
|
928
|
+
partOf.resize(svfg->getTotalNodeNum());
|
|
929
|
+
std::fill(partOf.begin(), partOf.end(), -1);
|
|
930
|
+
footprint.clear();
|
|
931
|
+
|
|
932
|
+
std::vector<NodeData> nodeData(svfg->getTotalNodeNum(), { -1, -1, false});
|
|
933
|
+
std::stack<const SVFGNode *> stack;
|
|
934
|
+
|
|
935
|
+
int index = 0;
|
|
936
|
+
int currentSCC = 0;
|
|
937
|
+
|
|
938
|
+
for (const SVFGNode *v : startingNodes)
|
|
939
|
+
{
|
|
940
|
+
if (nodeData[v->getId()].index == -1)
|
|
941
|
+
{
|
|
942
|
+
visit(vfs, object, partOf, footprint, nodeData, stack, index, currentSCC, v);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// Make sure footprints with the same edges pass ==/hash the same.
|
|
947
|
+
std::sort(footprint.begin(), footprint.end());
|
|
948
|
+
|
|
949
|
+
return currentSCC;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
void VersionedFlowSensitive::SCC::visit(VersionedFlowSensitive *vfs,
|
|
953
|
+
const NodeID object,
|
|
954
|
+
std::vector<int> &partOf,
|
|
955
|
+
std::vector<const IndirectSVFGEdge *> &footprint,
|
|
956
|
+
std::vector<NodeData> &nodeData,
|
|
957
|
+
std::stack<const SVFGNode *> &stack,
|
|
958
|
+
int &index,
|
|
959
|
+
int ¤tSCC,
|
|
960
|
+
const SVFGNode *v)
|
|
961
|
+
{
|
|
962
|
+
const NodeID vId = v->getId();
|
|
963
|
+
|
|
964
|
+
nodeData[vId].index = index;
|
|
965
|
+
nodeData[vId].lowlink = index;
|
|
966
|
+
++index;
|
|
967
|
+
|
|
968
|
+
stack.push(v);
|
|
969
|
+
nodeData[vId].onStack = true;
|
|
970
|
+
|
|
971
|
+
for (const SVFGEdge *e : v->getOutEdges())
|
|
972
|
+
{
|
|
973
|
+
const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
|
|
974
|
+
if (!ie) continue;
|
|
975
|
+
|
|
976
|
+
const SVFGNode *w = ie->getDstNode();
|
|
977
|
+
const NodeID wId = w->getId();
|
|
978
|
+
|
|
979
|
+
// If object is not part of the edge, there is no edge from v to w.
|
|
980
|
+
if (!ie->getPointsTo().test(object)) continue;
|
|
981
|
+
|
|
982
|
+
// Even if we don't count edges to stores and deltas for SCCs' sake, they
|
|
983
|
+
// are relevant to the footprint as a propagation still occurs over such edges.
|
|
984
|
+
footprint.push_back(ie);
|
|
985
|
+
|
|
986
|
+
// Ignore edges to delta nodes because they are prelabeled so cannot
|
|
987
|
+
// be part of the SCC v is in (already in nodesTodo from the prelabeled set).
|
|
988
|
+
// Similarly, store nodes.
|
|
989
|
+
if (vfs->delta(wId) || vfs->isStore(wId)) continue;
|
|
990
|
+
|
|
991
|
+
if (nodeData[wId].index == -1)
|
|
992
|
+
{
|
|
993
|
+
visit(vfs, object, partOf, footprint, nodeData, stack, index, currentSCC, w);
|
|
994
|
+
nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].lowlink);
|
|
995
|
+
}
|
|
996
|
+
else if (nodeData[wId].onStack)
|
|
997
|
+
{
|
|
998
|
+
nodeData[vId].lowlink = std::min(nodeData[vId].lowlink, nodeData[wId].index);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
if (nodeData[vId].lowlink == nodeData[vId].index)
|
|
1003
|
+
{
|
|
1004
|
+
const SVFGNode *w = nullptr;
|
|
1005
|
+
do
|
|
1006
|
+
{
|
|
1007
|
+
w = stack.top();
|
|
1008
|
+
stack.pop();
|
|
1009
|
+
const NodeID wId = w->getId();
|
|
1010
|
+
nodeData[wId].onStack = false;
|
|
1011
|
+
partOf[wId] = currentSCC;
|
|
1012
|
+
} while (w != v);
|
|
1013
|
+
|
|
1014
|
+
// For the next SCC.
|
|
1015
|
+
++currentSCC;
|
|
1016
|
+
}
|
|
1017
|
+
}
|