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.
Files changed (468) hide show
  1. package/SVF-doxygen/html/html/AbstractPointsToDS_8h_source.html +1 -1
  2. package/SVF-doxygen/html/html/AndersenLCD_8cpp_source.html +3 -3
  3. package/SVF-doxygen/html/html/AndersenSCD_8cpp_source.html +4 -4
  4. package/SVF-doxygen/html/html/AndersenSFR_8cpp_source.html +3 -3
  5. package/SVF-doxygen/html/html/AndersenSFR_8h_source.html +4 -4
  6. package/SVF-doxygen/html/html/AndersenStat_8cpp_source.html +11 -11
  7. package/SVF-doxygen/html/html/AndersenWaveDiffWithType_8cpp_source.html +4 -4
  8. package/SVF-doxygen/html/html/AndersenWaveDiff_8cpp_source.html +2 -2
  9. package/SVF-doxygen/html/html/Andersen_8cpp_source.html +21 -21
  10. package/SVF-doxygen/html/html/Andersen_8h_source.html +8 -8
  11. package/SVF-doxygen/html/html/BasicTypes_8h_source.html +8 -8
  12. package/SVF-doxygen/html/html/CHG_8cpp.html +7 -6
  13. package/SVF-doxygen/html/html/CHG_8cpp_source.html +42 -41
  14. package/SVF-doxygen/html/html/CHG_8h_source.html +2 -2
  15. package/SVF-doxygen/html/html/CSC_8cpp_source.html +2 -2
  16. package/SVF-doxygen/html/html/CSC_8h_source.html +3 -3
  17. package/SVF-doxygen/html/html/CommonCHG_8h_source.html +1 -1
  18. package/SVF-doxygen/html/html/ConditionalPT_8h_source.html +2 -2
  19. package/SVF-doxygen/html/html/Conditions_8cpp_source.html +2 -2
  20. package/SVF-doxygen/html/html/Conditions_8h_source.html +2 -2
  21. package/SVF-doxygen/html/html/ConsGNode_8h_source.html +1 -1
  22. package/SVF-doxygen/html/html/ConsG_8cpp_source.html +3 -3
  23. package/SVF-doxygen/html/html/ConsG_8h_source.html +2 -2
  24. package/SVF-doxygen/html/html/ContextDDA_8cpp_source.html +9 -9
  25. package/SVF-doxygen/html/html/ContextDDA_8h_source.html +3 -3
  26. package/SVF-doxygen/html/html/CoreBitVector_8h.html +2 -0
  27. package/SVF-doxygen/html/html/CoreBitVector_8h_source.html +3 -1
  28. package/SVF-doxygen/html/html/CxtStmt_8h_source.html +1 -1
  29. package/SVF-doxygen/html/html/DCHG_8cpp_source.html +5 -5
  30. package/SVF-doxygen/html/html/DCHG_8h_source.html +4 -4
  31. package/SVF-doxygen/html/html/DDAClient_8cpp_source.html +5 -5
  32. package/SVF-doxygen/html/html/DDAClient_8h_source.html +3 -3
  33. package/SVF-doxygen/html/html/DDAPass_8cpp_source.html +11 -11
  34. package/SVF-doxygen/html/html/DDAPass_8h_source.html +1 -1
  35. package/SVF-doxygen/html/html/DDAStat_8cpp_source.html +8 -8
  36. package/SVF-doxygen/html/html/DDAStat_8h_source.html +2 -2
  37. package/SVF-doxygen/html/html/DDAVFSolver_8h_source.html +8 -8
  38. package/SVF-doxygen/html/html/DPItem_8h_source.html +1 -1
  39. package/SVF-doxygen/html/html/DataFlowUtil_8h_source.html +1 -1
  40. package/SVF-doxygen/html/html/ExtAPI_8h_source.html +2 -2
  41. package/SVF-doxygen/html/html/ExternalPAG_8cpp_source.html +3 -3
  42. package/SVF-doxygen/html/html/ExternalPAG_8h_source.html +3 -3
  43. package/SVF-doxygen/html/html/FSMPTA_8cpp_source.html +8 -8
  44. package/SVF-doxygen/html/html/FSMPTA_8h_source.html +3 -3
  45. package/SVF-doxygen/html/html/FlowDDA_8cpp_source.html +5 -5
  46. package/SVF-doxygen/html/html/FlowDDA_8h_source.html +2 -2
  47. package/SVF-doxygen/html/html/FlowSensitiveStat_8cpp_source.html +5 -5
  48. package/SVF-doxygen/html/html/FlowSensitiveTBHC_8cpp_source.html +7 -7
  49. package/SVF-doxygen/html/html/FlowSensitiveTBHC_8h_source.html +3 -3
  50. package/SVF-doxygen/html/html/FlowSensitive_8cpp_source.html +17 -17
  51. package/SVF-doxygen/html/html/FlowSensitive_8h_source.html +3 -3
  52. package/SVF-doxygen/html/html/GenericGraph_8h_source.html +2 -2
  53. package/SVF-doxygen/html/html/ICFGBuilder_8h_source.html +1 -1
  54. package/SVF-doxygen/html/html/ICFGNode_8h_source.html +1 -1
  55. package/SVF-doxygen/html/html/ICFGStat_8h_source.html +2 -2
  56. package/SVF-doxygen/html/html/ICFG_8cpp_source.html +4 -4
  57. package/SVF-doxygen/html/html/ICFG_8h_source.html +1 -1
  58. package/SVF-doxygen/html/html/LLVMModule_8cpp_source.html +3 -3
  59. package/SVF-doxygen/html/html/LLVMModule_8h_source.html +1 -1
  60. package/SVF-doxygen/html/html/LLVMUtil_8cpp_source.html +1 -1
  61. package/SVF-doxygen/html/html/LLVMUtil_8h_source.html +1 -1
  62. package/SVF-doxygen/html/html/LeakChecker_8cpp_source.html +2 -2
  63. package/SVF-doxygen/html/html/LeakChecker_8h_source.html +2 -2
  64. package/SVF-doxygen/html/html/LocationSet_8cpp_source.html +3 -3
  65. package/SVF-doxygen/html/html/LocationSet_8h_source.html +2 -2
  66. package/SVF-doxygen/html/html/LockAnalysis_8cpp_source.html +8 -8
  67. package/SVF-doxygen/html/html/LockAnalysis_8h_source.html +6 -6
  68. package/SVF-doxygen/html/html/LockResultValidator_8cpp_source.html +3 -3
  69. package/SVF-doxygen/html/html/LockResultValidator_8h_source.html +3 -3
  70. package/SVF-doxygen/html/html/MHP_8cpp_source.html +12 -12
  71. package/SVF-doxygen/html/html/MHP_8h_source.html +4 -4
  72. package/SVF-doxygen/html/html/MSSAMuChi_8h_source.html +1 -1
  73. package/SVF-doxygen/html/html/MTAAnnotator_8cpp_source.html +4 -4
  74. package/SVF-doxygen/html/html/MTAAnnotator_8h_source.html +1 -1
  75. package/SVF-doxygen/html/html/MTAResultValidator_8cpp_source.html +5 -5
  76. package/SVF-doxygen/html/html/MTAResultValidator_8h_source.html +3 -3
  77. package/SVF-doxygen/html/html/MTAStat_8cpp_source.html +5 -5
  78. package/SVF-doxygen/html/html/MTAStat_8h_source.html +1 -1
  79. package/SVF-doxygen/html/html/MTA_8cpp_source.html +7 -7
  80. package/SVF-doxygen/html/html/MTA_8h_source.html +2 -2
  81. package/SVF-doxygen/html/html/MemModel_8h_source.html +1 -1
  82. package/SVF-doxygen/html/html/MemPartition_8cpp_source.html +1 -1
  83. package/SVF-doxygen/html/html/MemPartition_8h_source.html +3 -3
  84. package/SVF-doxygen/html/html/MemRegion_8cpp_source.html +5 -5
  85. package/SVF-doxygen/html/html/MemRegion_8h_source.html +4 -4
  86. package/SVF-doxygen/html/html/MemSSA_8cpp_source.html +7 -7
  87. package/SVF-doxygen/html/html/MemSSA_8h_source.html +2 -2
  88. package/SVF-doxygen/html/html/MutablePointsToDS_8h_source.html +2 -2
  89. package/SVF-doxygen/html/html/NodeIDAllocator_8cpp_source.html +11 -11
  90. package/SVF-doxygen/html/html/NodeIDAllocator_8h_source.html +2 -2
  91. package/SVF-doxygen/html/html/OfflineConsG_8cpp_source.html +2 -2
  92. package/SVF-doxygen/html/html/OfflineConsG_8h_source.html +2 -2
  93. package/SVF-doxygen/html/html/Options_8cpp_source.html +112 -110
  94. package/SVF-doxygen/html/html/Options_8h.html +1 -0
  95. package/SVF-doxygen/html/html/Options_8h_source.html +114 -111
  96. package/SVF-doxygen/html/html/PAGBuilder_8cpp_source.html +3 -3
  97. package/SVF-doxygen/html/html/PAGEdge_8h_source.html +1 -1
  98. package/SVF-doxygen/html/html/PAG_8cpp_source.html +7 -7
  99. package/SVF-doxygen/html/html/PAG_8h_source.html +5 -5
  100. package/SVF-doxygen/html/html/PCG_8cpp_source.html +3 -3
  101. package/SVF-doxygen/html/html/PCG_8h_source.html +1 -1
  102. package/SVF-doxygen/html/html/PTACallGraph_8cpp_source.html +2 -2
  103. package/SVF-doxygen/html/html/PTACallGraph_8h_source.html +3 -3
  104. package/SVF-doxygen/html/html/PTAStat_8cpp_source.html +21 -18
  105. package/SVF-doxygen/html/html/PTAStat_8h_source.html +19 -17
  106. package/SVF-doxygen/html/html/PTAType_8h_source.html +4 -4
  107. package/SVF-doxygen/html/html/PathCondAllocator_8cpp_source.html +5 -5
  108. package/SVF-doxygen/html/html/PathCondAllocator_8h_source.html +3 -3
  109. package/SVF-doxygen/html/html/PersistentPointsToCache_8h_source.html +2 -2
  110. package/SVF-doxygen/html/html/PersistentPointsToDS_8h_source.html +2 -2
  111. package/SVF-doxygen/html/html/PointerAnalysisImpl_8cpp_source.html +5 -5
  112. package/SVF-doxygen/html/html/PointerAnalysisImpl_8h_source.html +4 -4
  113. package/SVF-doxygen/html/html/PointerAnalysis_8cpp_source.html +19 -19
  114. package/SVF-doxygen/html/html/PointerAnalysis_8h_source.html +5 -5
  115. package/SVF-doxygen/html/html/PointsTo_8cpp_source.html +4 -5
  116. package/SVF-doxygen/html/html/PointsTo_8h_source.html +2 -2
  117. package/SVF-doxygen/html/html/ProgSlice_8cpp_source.html +4 -4
  118. package/SVF-doxygen/html/html/ProgSlice_8h_source.html +2 -2
  119. package/SVF-doxygen/html/html/SCC_8h_source.html +3 -3
  120. package/SVF-doxygen/html/html/SVFBasicTypes_8h.html +33 -27
  121. package/SVF-doxygen/html/html/SVFBasicTypes_8h_source.html +52 -49
  122. package/SVF-doxygen/html/html/SVFGBuilder_8cpp_source.html +6 -6
  123. package/SVF-doxygen/html/html/SVFGEdge_8h_source.html +2 -2
  124. package/SVF-doxygen/html/html/SVFGNode_8h_source.html +3 -3
  125. package/SVF-doxygen/html/html/SVFGOPT_8cpp_source.html +7 -7
  126. package/SVF-doxygen/html/html/SVFGOPT_8h_source.html +3 -3
  127. package/SVF-doxygen/html/html/SVFGStat_8cpp_source.html +11 -11
  128. package/SVF-doxygen/html/html/SVFGStat_8h_source.html +5 -5
  129. package/SVF-doxygen/html/html/SVFG_8cpp_source.html +4 -4
  130. package/SVF-doxygen/html/html/SVFG_8h_source.html +2 -2
  131. package/SVF-doxygen/html/html/SVFModule_8cpp_source.html +2 -2
  132. package/SVF-doxygen/html/html/SVFModule_8h_source.html +1 -1
  133. package/SVF-doxygen/html/html/SVFUtil_8cpp_source.html +10 -9
  134. package/SVF-doxygen/html/html/SVFUtil_8h_source.html +7 -7
  135. package/SVF-doxygen/html/html/SaberCheckerAPI_8h_source.html +1 -1
  136. package/SVF-doxygen/html/html/SaberSVFGBuilder_8cpp_source.html +4 -4
  137. package/SVF-doxygen/html/html/SaberSVFGBuilder_8h_source.html +2 -2
  138. package/SVF-doxygen/html/html/SrcSnkDDA_8cpp_source.html +7 -7
  139. package/SVF-doxygen/html/html/SrcSnkDDA_8h_source.html +3 -3
  140. package/SVF-doxygen/html/html/Steensgaard_8cpp_source.html +1 -1
  141. package/SVF-doxygen/html/html/Steensgaard_8h_source.html +2 -2
  142. package/SVF-doxygen/html/html/SymbolTableInfo_8cpp_source.html +5 -5
  143. package/SVF-doxygen/html/html/SymbolTableInfo_8h_source.html +2 -2
  144. package/SVF-doxygen/html/html/TCT_8cpp_source.html +5 -5
  145. package/SVF-doxygen/html/html/TCT_8h_source.html +4 -4
  146. package/SVF-doxygen/html/html/ThreadAPI_8cpp_source.html +1 -1
  147. package/SVF-doxygen/html/html/ThreadAPI_8h_source.html +1 -1
  148. package/SVF-doxygen/html/html/ThreadCallGraph_8cpp_source.html +3 -3
  149. package/SVF-doxygen/html/html/ThreadCallGraph_8h_source.html +2 -2
  150. package/SVF-doxygen/html/html/TypeAnalysis_8cpp_source.html +1 -1
  151. package/SVF-doxygen/html/html/TypeAnalysis_8h_source.html +1 -1
  152. package/SVF-doxygen/html/html/TypeBasedHeapCloning_8cpp_source.html +2 -2
  153. package/SVF-doxygen/html/html/TypeBasedHeapCloning_8h_source.html +2 -2
  154. package/SVF-doxygen/html/html/VFGNode_8h_source.html +2 -2
  155. package/SVF-doxygen/html/html/VFG_8cpp_source.html +4 -4
  156. package/SVF-doxygen/html/html/VFG_8h_source.html +3 -3
  157. package/SVF-doxygen/html/html/VersionedFlowSensitiveStat_8cpp_source.html +10 -8
  158. package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp.html +3 -0
  159. package/SVF-doxygen/html/html/VersionedFlowSensitive_8cpp_source.html +78 -65
  160. package/SVF-doxygen/html/html/VersionedFlowSensitive_8h.html +3 -2
  161. package/SVF-doxygen/html/html/VersionedFlowSensitive_8h_source.html +78 -69
  162. package/SVF-doxygen/html/html/WPAFSSolver_8h_source.html +2 -2
  163. package/SVF-doxygen/html/html/WPAPass_8cpp_source.html +5 -5
  164. package/SVF-doxygen/html/html/WPASolver_8h_source.html +2 -2
  165. package/SVF-doxygen/html/html/WPAStat_8h_source.html +1 -1
  166. package/SVF-doxygen/html/html/WorkList_8h_source.html +1 -1
  167. package/SVF-doxygen/html/html/annotated.html +189 -186
  168. package/SVF-doxygen/html/html/classSVF_1_1ActualINSVFGNode.html +1 -1
  169. package/SVF-doxygen/html/html/classSVF_1_1ActualOUTSVFGNode.html +1 -1
  170. package/SVF-doxygen/html/html/classSVF_1_1AddrPE.html +2 -2
  171. package/SVF-doxygen/html/html/classSVF_1_1Andersen.html +24 -24
  172. package/SVF-doxygen/html/html/classSVF_1_1AndersenBase.html +10 -10
  173. package/SVF-doxygen/html/html/classSVF_1_1AndersenLCD.html +5 -5
  174. package/SVF-doxygen/html/html/classSVF_1_1AndersenSCD.html +12 -12
  175. package/SVF-doxygen/html/html/classSVF_1_1AndersenSFR.html +2 -2
  176. package/SVF-doxygen/html/html/classSVF_1_1AndersenStat-members.html +10 -7
  177. package/SVF-doxygen/html/html/classSVF_1_1AndersenStat.html +18 -14
  178. package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiff.html +5 -5
  179. package/SVF-doxygen/html/html/classSVF_1_1AndersenWaveDiffWithType.html +4 -4
  180. package/SVF-doxygen/html/html/classSVF_1_1BVDataPTAImpl.html +7 -7
  181. package/SVF-doxygen/html/html/classSVF_1_1BinaryOPPE.html +2 -2
  182. package/SVF-doxygen/html/html/classSVF_1_1BinaryOPVFGNode.html +1 -1
  183. package/SVF-doxygen/html/html/classSVF_1_1BranchCondManager.html +4 -4
  184. package/SVF-doxygen/html/html/classSVF_1_1CHGraph.html +91 -91
  185. package/SVF-doxygen/html/html/classSVF_1_1CHNode.html +2 -2
  186. package/SVF-doxygen/html/html/classSVF_1_1CSC.html +3 -3
  187. package/SVF-doxygen/html/html/classSVF_1_1CallBlockNode.html +2 -2
  188. package/SVF-doxygen/html/html/classSVF_1_1CallPE.html +2 -2
  189. package/SVF-doxygen/html/html/classSVF_1_1CmpPE.html +2 -2
  190. package/SVF-doxygen/html/html/classSVF_1_1CmpVFGNode.html +1 -1
  191. package/SVF-doxygen/html/html/classSVF_1_1CondPTAImpl.html +1 -1
  192. package/SVF-doxygen/html/html/classSVF_1_1ContextDDA.html +17 -17
  193. package/SVF-doxygen/html/html/classSVF_1_1CopyPE.html +2 -2
  194. package/SVF-doxygen/html/html/classSVF_1_1CxtProc.html +1 -1
  195. package/SVF-doxygen/html/html/classSVF_1_1CxtThreadProc.html +1 -1
  196. package/SVF-doxygen/html/html/classSVF_1_1DCHGraph.html +7 -7
  197. package/SVF-doxygen/html/html/classSVF_1_1DDAClient.html +3 -3
  198. package/SVF-doxygen/html/html/classSVF_1_1DDAPass.html +11 -11
  199. package/SVF-doxygen/html/html/classSVF_1_1DDAStat-members.html +5 -2
  200. package/SVF-doxygen/html/html/classSVF_1_1DDAStat.html +14 -10
  201. package/SVF-doxygen/html/html/classSVF_1_1DDAVFSolver.html +27 -27
  202. package/SVF-doxygen/html/html/classSVF_1_1DistinctMRG.html +3 -3
  203. package/SVF-doxygen/html/html/classSVF_1_1ExternalPAG.html +4 -4
  204. package/SVF-doxygen/html/html/classSVF_1_1FIObjPN.html +2 -2
  205. package/SVF-doxygen/html/html/classSVF_1_1FlowDDA.html +14 -14
  206. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitive.html +48 -48
  207. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat-members.html +5 -2
  208. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveStat.html +16 -12
  209. package/SVF-doxygen/html/html/classSVF_1_1FlowSensitiveTBHC.html +23 -23
  210. package/SVF-doxygen/html/html/classSVF_1_1ForkJoinAnalysis.html +13 -13
  211. package/SVF-doxygen/html/html/classSVF_1_1FormalINSVFGNode.html +1 -1
  212. package/SVF-doxygen/html/html/classSVF_1_1FormalOUTSVFGNode.html +1 -1
  213. package/SVF-doxygen/html/html/classSVF_1_1FormalParmVFGNode.html +1 -1
  214. package/SVF-doxygen/html/html/classSVF_1_1FormalRetVFGNode.html +1 -1
  215. package/SVF-doxygen/html/html/classSVF_1_1FunEntryBlockNode.html +1 -1
  216. package/SVF-doxygen/html/html/classSVF_1_1FunExitBlockNode.html +1 -1
  217. package/SVF-doxygen/html/html/classSVF_1_1FunptrDDAClient.html +1 -1
  218. package/SVF-doxygen/html/html/classSVF_1_1GepObjPN.html +2 -2
  219. package/SVF-doxygen/html/html/classSVF_1_1GepPE.html +2 -2
  220. package/SVF-doxygen/html/html/classSVF_1_1GepValPN.html +2 -2
  221. package/SVF-doxygen/html/html/classSVF_1_1ICFG.html +2 -2
  222. package/SVF-doxygen/html/html/classSVF_1_1ICFGStat-members.html +5 -2
  223. package/SVF-doxygen/html/html/classSVF_1_1ICFGStat.html +7 -3
  224. package/SVF-doxygen/html/html/classSVF_1_1InterDisjointMRG.html +1 -1
  225. package/SVF-doxygen/html/html/classSVF_1_1InterMSSAPHISVFGNode.html +1 -1
  226. package/SVF-doxygen/html/html/classSVF_1_1InterPHIVFGNode.html +1 -1
  227. package/SVF-doxygen/html/html/classSVF_1_1IntraBlockNode.html +2 -2
  228. package/SVF-doxygen/html/html/classSVF_1_1IntraDisjointMRG.html +3 -3
  229. package/SVF-doxygen/html/html/classSVF_1_1IntraMSSAPHISVFGNode.html +1 -1
  230. package/SVF-doxygen/html/html/classSVF_1_1IntraPHIVFGNode.html +1 -1
  231. package/SVF-doxygen/html/html/classSVF_1_1LLVMModuleSet.html +8 -8
  232. package/SVF-doxygen/html/html/classSVF_1_1LeakChecker.html +3 -3
  233. package/SVF-doxygen/html/html/classSVF_1_1LoadPE.html +2 -2
  234. package/SVF-doxygen/html/html/classSVF_1_1LocationSet.html +3 -3
  235. package/SVF-doxygen/html/html/classSVF_1_1LockAnalysis.html +36 -36
  236. package/SVF-doxygen/html/html/classSVF_1_1LockResultValidator.html +4 -4
  237. package/SVF-doxygen/html/html/classSVF_1_1MHP.html +31 -31
  238. package/SVF-doxygen/html/html/classSVF_1_1MRGenerator.html +20 -20
  239. package/SVF-doxygen/html/html/classSVF_1_1MSSAPHISVFGNode.html +1 -1
  240. package/SVF-doxygen/html/html/classSVF_1_1MTA.html +9 -9
  241. package/SVF-doxygen/html/html/classSVF_1_1MTAAnnotator.html +9 -9
  242. package/SVF-doxygen/html/html/classSVF_1_1MTAResultValidator.html +12 -12
  243. package/SVF-doxygen/html/html/classSVF_1_1MTASVFGBuilder.html +18 -18
  244. package/SVF-doxygen/html/html/classSVF_1_1MTAStat-members.html +6 -3
  245. package/SVF-doxygen/html/html/classSVF_1_1MTAStat.html +17 -13
  246. package/SVF-doxygen/html/html/classSVF_1_1MemObj.html +2 -2
  247. package/SVF-doxygen/html/html/classSVF_1_1MemSSA.html +19 -19
  248. package/SVF-doxygen/html/html/classSVF_1_1MemSSAStat-members.html +5 -2
  249. package/SVF-doxygen/html/html/classSVF_1_1MemSSAStat.html +12 -8
  250. package/SVF-doxygen/html/html/classSVF_1_1MutableDFPTData.html +1 -1
  251. package/SVF-doxygen/html/html/classSVF_1_1NodeIDAllocator.html +1 -1
  252. package/SVF-doxygen/html/html/classSVF_1_1NodeIDAllocator_1_1Clusterer.html +17 -17
  253. package/SVF-doxygen/html/html/classSVF_1_1NormalGepPE.html +2 -2
  254. package/SVF-doxygen/html/html/classSVF_1_1ObjPN.html +2 -2
  255. package/SVF-doxygen/html/html/classSVF_1_1OfflineConsG.html +2 -2
  256. package/SVF-doxygen/html/html/classSVF_1_1Options-members.html +102 -100
  257. package/SVF-doxygen/html/html/classSVF_1_1Options.html +166 -111
  258. package/SVF-doxygen/html/html/classSVF_1_1PAG.html +6 -6
  259. package/SVF-doxygen/html/html/classSVF_1_1PAGBuilder.html +29 -29
  260. package/SVF-doxygen/html/html/classSVF_1_1PCG.html +3 -3
  261. package/SVF-doxygen/html/html/classSVF_1_1PHIVFGNode.html +1 -1
  262. package/SVF-doxygen/html/html/classSVF_1_1PTACallGraph.html +2 -2
  263. package/SVF-doxygen/html/html/classSVF_1_1PTACallGraphNode.html +2 -2
  264. package/SVF-doxygen/html/html/classSVF_1_1PTAStat-members.html +6 -3
  265. package/SVF-doxygen/html/html/classSVF_1_1PTAStat.html +88 -56
  266. package/SVF-doxygen/html/html/classSVF_1_1PathCondAllocator.html +8 -8
  267. package/SVF-doxygen/html/html/classSVF_1_1PersistentDFPTData.html +3 -3
  268. package/SVF-doxygen/html/html/classSVF_1_1PersistentDiffPTData.html +3 -3
  269. package/SVF-doxygen/html/html/classSVF_1_1PersistentPTData.html +6 -6
  270. package/SVF-doxygen/html/html/classSVF_1_1PersistentPointsToCache.html +6 -6
  271. package/SVF-doxygen/html/html/classSVF_1_1PointerAnalysis.html +23 -23
  272. package/SVF-doxygen/html/html/classSVF_1_1PointsTo.html +9 -8
  273. package/SVF-doxygen/html/html/classSVF_1_1ProgSlice.html +5 -5
  274. package/SVF-doxygen/html/html/classSVF_1_1RetBlockNode.html +2 -2
  275. package/SVF-doxygen/html/html/classSVF_1_1RetPE.html +2 -2
  276. package/SVF-doxygen/html/html/classSVF_1_1SVFBasicBlock.html +2 -2
  277. package/SVF-doxygen/html/html/classSVF_1_1SVFFunction.html +8 -8
  278. package/SVF-doxygen/html/html/classSVF_1_1SVFG.html +8 -8
  279. package/SVF-doxygen/html/html/classSVF_1_1SVFGBuilder.html +8 -8
  280. package/SVF-doxygen/html/html/classSVF_1_1SVFGOPT.html +13 -13
  281. package/SVF-doxygen/html/html/classSVF_1_1SVFGStat-members.html +11 -8
  282. package/SVF-doxygen/html/html/classSVF_1_1SVFGStat.html +40 -36
  283. package/SVF-doxygen/html/html/classSVF_1_1SVFGlobal.html +2 -2
  284. package/SVF-doxygen/html/html/classSVF_1_1SVFInstruction.html +2 -2
  285. package/SVF-doxygen/html/html/classSVF_1_1SVFModule.html +2 -2
  286. package/SVF-doxygen/html/html/classSVF_1_1SVFValue.html +33 -33
  287. package/SVF-doxygen/html/html/classSVF_1_1SaberSVFGBuilder.html +4 -4
  288. package/SVF-doxygen/html/html/classSVF_1_1SrcSnkDDA.html +12 -12
  289. package/SVF-doxygen/html/html/classSVF_1_1Steensgaard.html +1 -1
  290. package/SVF-doxygen/html/html/classSVF_1_1StorePE.html +2 -2
  291. package/SVF-doxygen/html/html/classSVF_1_1SymbolTableInfo.html +18 -18
  292. package/SVF-doxygen/html/html/classSVF_1_1TCT.html +16 -16
  293. package/SVF-doxygen/html/html/classSVF_1_1TDForkPE.html +2 -2
  294. package/SVF-doxygen/html/html/classSVF_1_1TDJoinPE.html +2 -2
  295. package/SVF-doxygen/html/html/classSVF_1_1ThreadAPI.html +1 -1
  296. package/SVF-doxygen/html/html/classSVF_1_1ThreadCallGraph.html +3 -3
  297. package/SVF-doxygen/html/html/classSVF_1_1TypeAnalysis.html +2 -2
  298. package/SVF-doxygen/html/html/classSVF_1_1TypeBasedHeapCloning.html +5 -5
  299. package/SVF-doxygen/html/html/classSVF_1_1TypeSystem.html +1 -1
  300. package/SVF-doxygen/html/html/classSVF_1_1UnaryOPPE.html +2 -2
  301. package/SVF-doxygen/html/html/classSVF_1_1UnaryOPVFGNode.html +1 -1
  302. package/SVF-doxygen/html/html/classSVF_1_1VFG.html +3 -3
  303. package/SVF-doxygen/html/html/classSVF_1_1ValPN.html +2 -2
  304. package/SVF-doxygen/html/html/classSVF_1_1VariantGepPE.html +2 -2
  305. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive-members.html +161 -162
  306. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive.html +578 -539
  307. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat-members.html +7 -4
  308. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitiveStat.html +31 -28
  309. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive_1_1SCC-members.html +83 -0
  310. package/SVF-doxygen/html/html/classSVF_1_1VersionedFlowSensitive_1_1SCC.html +297 -0
  311. package/SVF-doxygen/html/html/classSVF_1_1WPAFSSolver.html +2 -2
  312. package/SVF-doxygen/html/html/classSVF_1_1WPAMinimumSolver.html +2 -2
  313. package/SVF-doxygen/html/html/classSVF_1_1WPAPass.html +12 -12
  314. package/SVF-doxygen/html/html/classSVF_1_1WPASCCSolver.html +2 -2
  315. package/SVF-doxygen/html/html/classSVF_1_1WPASolver.html +1 -1
  316. package/SVF-doxygen/html/html/classes.html +96 -95
  317. package/SVF-doxygen/html/html/functions_b.html +11 -5
  318. package/SVF-doxygen/html/html/functions_c.html +24 -18
  319. package/SVF-doxygen/html/html/functions_d.html +13 -4
  320. package/SVF-doxygen/html/html/functions_e.html +3 -0
  321. package/SVF-doxygen/html/html/functions_enum.html +3 -0
  322. package/SVF-doxygen/html/html/functions_eval_c.html +3 -0
  323. package/SVF-doxygen/html/html/functions_eval_w.html +76 -0
  324. package/SVF-doxygen/html/html/functions_f.html +14 -14
  325. package/SVF-doxygen/html/html/functions_func_b.html +6 -0
  326. package/SVF-doxygen/html/html/functions_func_d.html +7 -4
  327. package/SVF-doxygen/html/html/functions_func_g.html +15 -9
  328. package/SVF-doxygen/html/html/functions_func_i.html +11 -11
  329. package/SVF-doxygen/html/html/functions_func_m.html +0 -3
  330. package/SVF-doxygen/html/html/functions_func_n.html +1 -4
  331. package/SVF-doxygen/html/html/functions_func_o.html +6 -4
  332. package/SVF-doxygen/html/html/functions_func_r.html +4 -1
  333. package/SVF-doxygen/html/html/functions_func_s.html +1 -1
  334. package/SVF-doxygen/html/html/functions_func_v.html +2 -1
  335. package/SVF-doxygen/html/html/functions_g.html +15 -9
  336. package/SVF-doxygen/html/html/functions_i.html +23 -16
  337. package/SVF-doxygen/html/html/functions_l.html +12 -15
  338. package/SVF-doxygen/html/html/functions_m.html +1 -16
  339. package/SVF-doxygen/html/html/functions_n.html +3 -3
  340. package/SVF-doxygen/html/html/functions_o.html +17 -16
  341. package/SVF-doxygen/html/html/functions_p.html +16 -13
  342. package/SVF-doxygen/html/html/functions_r.html +6 -8
  343. package/SVF-doxygen/html/html/functions_s.html +14 -16
  344. package/SVF-doxygen/html/html/functions_t.html +9 -9
  345. package/SVF-doxygen/html/html/functions_type_l.html +1 -4
  346. package/SVF-doxygen/html/html/functions_type_m.html +1 -1
  347. package/SVF-doxygen/html/html/functions_type_n.html +3 -0
  348. package/SVF-doxygen/html/html/functions_type_o.html +0 -3
  349. package/SVF-doxygen/html/html/functions_type_v.html +0 -3
  350. package/SVF-doxygen/html/html/functions_u.html +3 -3
  351. package/SVF-doxygen/html/html/functions_v.html +8 -10
  352. package/SVF-doxygen/html/html/functions_vars_c.html +3 -3
  353. package/SVF-doxygen/html/html/functions_vars_d.html +6 -0
  354. package/SVF-doxygen/html/html/functions_vars_e.html +3 -0
  355. package/SVF-doxygen/html/html/functions_vars_i.html +7 -0
  356. package/SVF-doxygen/html/html/functions_vars_l.html +3 -3
  357. package/SVF-doxygen/html/html/functions_vars_m.html +0 -12
  358. package/SVF-doxygen/html/html/functions_vars_o.html +3 -3
  359. package/SVF-doxygen/html/html/functions_vars_p.html +3 -0
  360. package/SVF-doxygen/html/html/functions_vars_r.html +0 -3
  361. package/SVF-doxygen/html/html/functions_vars_v.html +3 -3
  362. package/SVF-doxygen/html/html/functions_vars_y.html +0 -3
  363. package/SVF-doxygen/html/html/functions_w.html +5 -6
  364. package/SVF-doxygen/html/html/functions_y.html +0 -3
  365. package/SVF-doxygen/html/html/globals_f.html +3 -3
  366. package/SVF-doxygen/html/html/globals_func_i.html +8 -8
  367. package/SVF-doxygen/html/html/globals_func_s.html +6 -6
  368. package/SVF-doxygen/html/html/globals_r.html +3 -3
  369. package/SVF-doxygen/html/html/globals_s.html +12 -14
  370. package/SVF-doxygen/html/html/hierarchy.html +176 -173
  371. package/SVF-doxygen/html/html/menudata.js +2 -1
  372. package/SVF-doxygen/html/html/namespaceSVF.html +70 -32
  373. package/SVF-doxygen/html/html/namespaceSVF_1_1SVFUtil.html +13 -12
  374. package/SVF-doxygen/html/html/namespacemembers_type_v.html +6 -0
  375. package/SVF-doxygen/html/html/namespacemembers_v.html +6 -0
  376. package/SVF-doxygen/html/html/search/all_10.js +4 -3
  377. package/SVF-doxygen/html/html/search/all_12.js +4 -4
  378. package/SVF-doxygen/html/html/search/all_13.js +13 -13
  379. package/SVF-doxygen/html/html/search/all_14.js +6 -6
  380. package/SVF-doxygen/html/html/search/all_15.js +2 -2
  381. package/SVF-doxygen/html/html/search/all_16.js +5 -4
  382. package/SVF-doxygen/html/html/search/all_17.js +2 -1
  383. package/SVF-doxygen/html/html/search/all_19.js +0 -1
  384. package/SVF-doxygen/html/html/search/all_2.js +2 -0
  385. package/SVF-doxygen/html/html/search/all_3.js +2 -1
  386. package/SVF-doxygen/html/html/search/all_4.js +5 -2
  387. package/SVF-doxygen/html/html/search/all_5.js +1 -0
  388. package/SVF-doxygen/html/html/search/all_6.js +6 -6
  389. package/SVF-doxygen/html/html/search/all_7.js +5 -3
  390. package/SVF-doxygen/html/html/search/all_8.js +2 -0
  391. package/SVF-doxygen/html/html/search/all_9.js +6 -4
  392. package/SVF-doxygen/html/html/search/all_c.js +4 -5
  393. package/SVF-doxygen/html/html/search/all_d.js +1 -6
  394. package/SVF-doxygen/html/html/search/all_e.js +5 -5
  395. package/SVF-doxygen/html/html/search/all_f.js +2 -3
  396. package/SVF-doxygen/html/html/search/classes_12.js +0 -1
  397. package/SVF-doxygen/html/html/search/classes_7.js +2 -0
  398. package/SVF-doxygen/html/html/search/classes_b.js +1 -0
  399. package/SVF-doxygen/html/html/search/classes_f.js +1 -0
  400. package/SVF-doxygen/html/html/search/enums_1.js +1 -0
  401. package/SVF-doxygen/html/html/search/enumvalues_13.js +1 -1
  402. package/SVF-doxygen/html/html/search/enumvalues_2.js +1 -0
  403. package/SVF-doxygen/html/html/search/functions_1.js +2 -0
  404. package/SVF-doxygen/html/html/search/functions_10.js +3 -3
  405. package/SVF-doxygen/html/html/search/functions_13.js +1 -1
  406. package/SVF-doxygen/html/html/search/functions_3.js +3 -2
  407. package/SVF-doxygen/html/html/search/functions_6.js +5 -3
  408. package/SVF-doxygen/html/html/search/functions_8.js +3 -3
  409. package/SVF-doxygen/html/html/search/functions_b.js +0 -1
  410. package/SVF-doxygen/html/html/search/functions_c.js +0 -1
  411. package/SVF-doxygen/html/html/search/functions_d.js +1 -1
  412. package/SVF-doxygen/html/html/search/functions_f.js +1 -0
  413. package/SVF-doxygen/html/html/search/searchdata.js +1 -1
  414. package/SVF-doxygen/html/html/search/typedefs_14.js +2 -1
  415. package/SVF-doxygen/html/html/search/typedefs_b.js +1 -2
  416. package/SVF-doxygen/html/html/search/typedefs_c.js +1 -1
  417. package/SVF-doxygen/html/html/search/typedefs_d.js +1 -0
  418. package/SVF-doxygen/html/html/search/typedefs_e.js +0 -1
  419. package/SVF-doxygen/html/html/search/variables_10.js +1 -0
  420. package/SVF-doxygen/html/html/search/variables_12.js +0 -1
  421. package/SVF-doxygen/html/html/search/variables_14.js +2 -2
  422. package/SVF-doxygen/html/html/search/variables_15.js +1 -1
  423. package/SVF-doxygen/html/html/search/variables_16.js +1 -1
  424. package/SVF-doxygen/html/html/search/variables_19.js +0 -1
  425. package/SVF-doxygen/html/html/search/variables_3.js +1 -1
  426. package/SVF-doxygen/html/html/search/variables_4.js +2 -0
  427. package/SVF-doxygen/html/html/search/variables_5.js +1 -0
  428. package/SVF-doxygen/html/html/search/variables_6.js +1 -1
  429. package/SVF-doxygen/html/html/search/variables_9.js +3 -1
  430. package/SVF-doxygen/html/html/search/variables_c.js +1 -1
  431. package/SVF-doxygen/html/html/search/variables_d.js +0 -4
  432. package/SVF-doxygen/html/html/search/variables_e.js +2 -2
  433. package/SVF-doxygen/html/html/search/variables_f.js +1 -1
  434. package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01CoreBitVector_01_4-members.html +81 -0
  435. package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01CoreBitVector_01_4.html +126 -0
  436. package/SVF-doxygen/html/html/structSVF_1_1Hash_3_01NodePair_01_4.html +3 -3
  437. package/SVF-doxygen/html/html/structSVF_1_1VersionedFlowSensitive_1_1SCC_1_1NodeData-members.html +83 -0
  438. package/SVF-doxygen/html/html/structSVF_1_1VersionedFlowSensitive_1_1SCC_1_1NodeData.html +145 -0
  439. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01CHGraph_01_5_01_4.html +12 -12
  440. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ConstraintGraph_01_5_01_4.html +1 -1
  441. package/SVF-doxygen/html/html/structllvm_1_1DOTGraphTraits_3_01ICFG_01_5_01_4.html +1 -1
  442. package/SVF-doxygen/html/html/structstd_1_1hash_3_01SVF_1_1NodePair_01_4.html +3 -3
  443. package/SVF-doxygen/html/html/structstd_1_1hash_3_01SVF_1_1SmallVector_3_01T_00_01N_01_4_01_4.html +3 -3
  444. package/SVF-doxygen/html/html/structstd_1_1hash_3_01llvm_1_1SparseBitVector_3_01N_01_4_01_4.html +3 -3
  445. package/SVF-doxygen/html/html/structstd_1_1hash_3_01std_1_1vector_3_01T_01_4_01_4-members.html +81 -0
  446. package/SVF-doxygen/html/html/structstd_1_1hash_3_01std_1_1vector_3_01T_01_4_01_4.html +129 -0
  447. package/SVF-doxygen/html/html/svf-ex_8cpp.html +2 -2
  448. package/SVF-doxygen/html/html/svf-ex_8cpp_source.html +1 -1
  449. package/SVF-doxygen/html/html/tools_2DDA_2CMakeLists_8txt.html +1 -1
  450. package/SVF-doxygen/html/html/tools_2Example_2CMakeLists_8txt.html +1 -1
  451. package/SVF-doxygen/html/html/tools_2MTA_2CMakeLists_8txt.html +1 -1
  452. package/SVF-doxygen/html/html/tools_2SABER_2CMakeLists_8txt.html +1 -1
  453. package/SVF-doxygen/html/html/tools_2WPA_2CMakeLists_8txt.html +9 -9
  454. package/include/Graphs/SVFGStat.h +10 -10
  455. package/include/MemoryModel/PTAStat.h +8 -2
  456. package/include/Util/CoreBitVector.h +8 -0
  457. package/include/Util/Options.h +6 -0
  458. package/include/Util/SVFBasicTypes.h +22 -2
  459. package/include/WPA/VersionedFlowSensitive.h +96 -65
  460. package/lib/MemoryModel/PointsTo.cpp +3 -3
  461. package/lib/SVF-FE/CHG.cpp +3 -2
  462. package/lib/Util/Options.cpp +16 -0
  463. package/lib/Util/PTAStat.cpp +16 -2
  464. package/lib/Util/SVFUtil.cpp +1 -0
  465. package/lib/WPA/VersionedFlowSensitive.cpp +503 -229
  466. package/lib/WPA/VersionedFlowSensitiveStat.cpp +23 -38
  467. package/package.json +1 -1
  468. 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
- relianceTime = prelabelingTime = meldLabelingTime = meldMappingTime = versionPropTime = 0.0;
34
+ prelabelingTime = meldLabelingTime = versionPropTime = 0.0;
32
35
  // We'll grab vPtD in initialize.
33
36
 
34
- consumeCache = { 0, nullptr, false };
35
- yieldCache = { 0, nullptr, false };
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
- determineReliance();
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
- myl[o] = newMeldVersion(o);
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
- mcl[o] = newMeldVersion(o);
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
- while (!vWorklist.empty()) {
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
- if (yieldChanged) vWorklist.push(lp);
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
- double end = stat->getClk(true);
150
- meldLabelingTime = (end - start) / TIMEINTERVAL;
151
- }
152
-
153
- bool VersionedFlowSensitive::meld(MeldVersion &mv1, const MeldVersion &mv2)
154
- {
155
- // Meld operator is union of bit vectors.
156
- return mv1 |= mv2;
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
- void VersionedFlowSensitive::mapMeldVersions(void)
160
- {
161
- double start = stat->getClk(true);
146
+ std::mutex *versionMutexes = new std::mutex[nodesWhichNeedVersions.size()];
162
147
 
163
- // We want to uniquely map MeldVersions (SparseBitVectors) to a Version (unsigned integer).
164
- // mvv keeps track, and curVersion is used to generate new Versions.
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
- // meldConsume -> consume.
169
- for (LocMeldVersionMap::value_type &lomv : meldConsume)
151
+ std::queue<NodeID> objectQueue;
152
+ for (const NodeID o : prelabeledObjects)
170
153
  {
171
- NodeID l = lomv.first;
172
- bool lIsStore = SVFUtil::isa<StoreSVFGNode>(svfg->getSVFGNode(l));
173
- for (ObjToMeldVersionMap::value_type &omv : lomv.second)
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
- // meldYield -> yield.
192
- for (LocMeldVersionMap::value_type &lomv : meldYield)
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
- NodeID l = lomv.first;
195
- for (ObjToMeldVersionMap::value_type &omv : lomv.second)
168
+ while (true)
196
169
  {
197
- NodeID o = omv.first;
198
- MeldVersion &mv = omv.second;
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
- Map<MeldVersion, Version>::const_iterator foundVersion = mvv.find(mv);
201
- Version v = foundVersion == mvv.end() ? mvv[mv] = ++curVersion : foundVersion->second;
202
- setYield(l, o, v);
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
- // No longer necessary.
207
- meldConsume.clear();
208
- meldYield.clear();
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
- meldMappingTime += (end - start) / TIMEINTERVAL;
395
+ meldLabelingTime = (end - start) / TIMEINTERVAL;
212
396
  }
213
397
 
214
- bool VersionedFlowSensitive::delta(NodeID l) const
398
+ bool VersionedFlowSensitive::meld(MeldVersion &mv1, const MeldVersion &mv2)
215
399
  {
216
- // Whether a node is a delta node or not. Decent boon to performance.
217
- static Map<NodeID, bool> deltaCache;
400
+ // Meld operator is union of bit vectors.
401
+ return mv1 |= mv2;
402
+ }
218
403
 
219
- Map<NodeID, bool>::const_iterator isDeltaIt = deltaCache.find(l);
220
- if (isDeltaIt != deltaCache.end()) return isDeltaIt->second;
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
- const SVFGNode *s = svfg->getSVFGNode(l);
223
- // Cases:
224
- // * Function entry: can get new incoming indirect edges through ind. callsites.
225
- // * Callsite returns: can get new incoming indirect edges if the callsite is indirect.
226
- // * Otherwise: static.
227
- bool isDelta = false;
228
- if (const SVFFunction *fn = svfg->isFunEntrySVFGNode(s))
229
- {
230
- PTACallGraphEdge::CallInstSet callsites;
231
- /// use pre-analysis call graph to approximate all potential callsites
232
- ander->getPTACallGraph()->getIndCallSitesInvokingCallee(fn, callsites);
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
- isDelta = cbn->isIndirectCall();
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
- VersionedFlowSensitive::MeldVersion VersionedFlowSensitive::newMeldVersion(NodeID o)
433
+ bool VersionedFlowSensitive::isLoad(const NodeID l) const
246
434
  {
247
- ++numPrelabelVersions;
248
- MeldVersion nv;
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::determineReliance(void)
439
+ void VersionedFlowSensitive::buildDeltaMaps(void)
254
440
  {
255
- // Use a set-based version to build, then we'll move things to vectors.
256
- Map<NodeID, Map<Version, Set<Version>>> setVersionReliance;
441
+ deltaMap.resize(svfg->getTotalNodeNum(), false);
257
442
 
258
- double start = stat->getClk(true);
259
- for (SVFG::iterator it = svfg->begin(); it != svfg->end(); ++it)
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 *ln = it->second;
263
- for (const SVFGEdge *e : ln->getOutEdges())
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
- const IndirectSVFGEdge *ie = SVFUtil::dyn_cast<IndirectSVFGEdge>(e);
266
- if (!ie) continue;
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
- for (const NodeID o : ie->getPointsTo())
463
+ if (isDelta)
269
464
  {
270
- // Given l --o--> lp, c(o) at lp relies on y(o) at l.
271
- const NodeID lp = ie->getDstNode()->getId();
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
- // When an object/version points-to set changes, these nodes need to know.
283
- if (SVFUtil::isa<LoadSVFGNode>(ln) || SVFUtil::isa<StoreSVFGNode>(ln))
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
- const LocVersionMap::const_iterator lovmIt = consume.find(l);
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
- for (const std::pair<NodeID, Map<Version, Set<Version>>> &ovvs : setVersionReliance)
496
+ void VersionedFlowSensitive::removeAllIndirectSVFGEdges(void)
497
+ {
498
+ for (SVFG::iterator nodeIt = svfg->begin(); nodeIt != svfg->end(); ++nodeIt)
299
499
  {
300
- const NodeID o = ovvs.first;
301
- Map<Version, std::vector<Version>> &osRelying = versionReliance[o];
302
- for (const std::pair<Version, Set<Version>> &vvs : ovvs.second)
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
- const Version v = vvs.first;
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
- double end = stat->getClk(true);
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
- Map<Version, std::vector<Version>>::iterator relyingVersions = versionReliance[o].find(v);
319
- if (relyingVersions != versionReliance[o].end())
522
+ const std::vector<Version> &reliantVersions = getReliantVersions(o, v);
523
+ for (Version r : reliantVersions)
320
524
  {
321
- for (Version r : relyingVersions->second)
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 : stmtReliance[o][vp]) pushIntoWorklist(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 = versionReliance[o][srcY];
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 LocVersionMap::const_iterator lovmIt = consume.find(l);
505
- if (lovmIt != consume.end())
706
+ for (const ObjToVersionMap::value_type &oc : consume[l])
506
707
  {
507
- for (const ObjToVersionMap::value_type &oc : lovmIt->second)
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
- // Strong-updated; don't propagate.
513
- if (isSU && o == singleton) continue;
711
+ // Strong-updated; don't propagate.
712
+ if (isSU && o == singleton) continue;
514
713
 
515
- const Version y = getYield(l, o);
516
- if (y != invalidVersion && vPtD->unionPts(atKey(o, y), atKey(o, c)))
517
- {
518
- changed = true;
519
- changedObjects.set(o);
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 : stmtReliance[o][y]) pushIntoWorklist(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, VersionCache &cache, LocVersionMap &lvm)
764
+ Version VersionedFlowSensitive::getVersion(const NodeID l, const NodeID o, const LocVersionMap &lvm) const
567
765
  {
568
- if (cache.valid && l == cache.l)
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::const_iterator foundVersion = cache.ovm->find(o);
585
- return foundVersion == cache.ovm->end() ? invalidVersion : foundVersion->second;
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, consumeCache, consume);
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
- return getVersion(l, o, yieldCache, yield);
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, VersionCache &cache, LocVersionMap &lvm)
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, consumeCache, consume);
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
- setVersion(l, o, v, yieldCache, yield);
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
- void VersionedFlowSensitive::invalidateYieldCache(void)
804
+ std::vector<Version> &VersionedFlowSensitive::getReliantVersions(const NodeID o, const Version v)
628
805
  {
629
- yieldCache.valid = false;
806
+ return versionReliance[o][v];
630
807
  }
631
808
 
632
- void VersionedFlowSensitive::invalidateConsumeCache(void)
809
+ NodeBS &VersionedFlowSensitive::getStmtReliance(const NodeID o, const Version v)
633
810
  {
634
- consumeCache.valid = false;
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->find(loc) == lvm->end() || lvm->at(loc).empty()) continue;
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 &currentSCC,
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
+ }