svf-tools 1.0.414 → 1.0.415

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.
@@ -227,9 +227,8 @@ Static Private Attributes</h2></td></tr>
227
227
  <p>Returns vector mapping previously allocated node IDs to a smarter allocation based on the points-to sets in pta accessed through keys. The second part of the keys pairs are the number of (potential) occurrences of that points-to set or a subset, depending on the client's wish. TODO: interfaces are getting unwieldy, an initialised object may be better. TODO: kind of sucks pta can't be const here because getPts isn't. </p>
228
228
 
229
229
  <p class="definition">Definition at line <a class="el" href="NodeIDAllocator_8cpp_source.html#l00188">188</a> of file <a class="el" href="NodeIDAllocator_8cpp_source.html">NodeIDAllocator.cpp</a>.</p>
230
- <div class="fragment"><div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160; {</div><div class="line"><a name="l00190"></a><span class="lineno"> 190</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(pta != <span class="keyword">nullptr</span> &amp;&amp; <span class="stringliteral">&quot;Clusterer::cluster: given null BVDataPTAImpl&quot;</span>);</div><div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(<a class="code" href="classSVF_1_1Options.html#a2537be131132830c63d408133619a065">Options::NodeAllocStrat</a> == Strategy::DENSE &amp;&amp; <span class="stringliteral">&quot;Clusterer::cluster: only dense allocation clustering currently supported&quot;</span>);</div><div class="line"><a name="l00192"></a><span class="lineno"> 192</span>&#160;</div><div class="line"><a name="l00193"></a><span class="lineno"> 193</span>&#160; Map&lt;std::string, std::string&gt; overallStats;</div><div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160; <span class="keywordtype">double</span> fastClusterTime = 0.0;</div><div class="line"><a name="l00195"></a><span class="lineno"> 195</span>&#160; <span class="keywordtype">double</span> distanceMatrixTime = 0.0;</div><div class="line"><a name="l00196"></a><span class="lineno"> 196</span>&#160; <span class="keywordtype">double</span> dendrogramTraversalTime = 0.0;</div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160; <span class="keywordtype">double</span> regioningTime = 0.0;</div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160; <span class="keywordtype">double</span> evalTime = 0.0;</div><div class="line"><a name="l00199"></a><span class="lineno"> 199</span>&#160;</div><div class="line"><a name="l00200"></a><span class="lineno"> 200</span>&#160; <span class="comment">// Pair of nodes to their (minimum) distance and the number of occurrences of that distance.</span></div><div class="line"><a name="l00201"></a><span class="lineno"> 201</span>&#160; Map&lt;std::pair&lt;NodeID, NodeID&gt;, std::pair&lt;unsigned, unsigned&gt;&gt; distances;</div><div class="line"><a name="l00202"></a><span class="lineno"> 202</span>&#160;</div><div class="line"><a name="l00203"></a><span class="lineno"> 203</span>&#160; <span class="keywordtype">double</span> clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160;</div><div class="line"><a name="l00205"></a><span class="lineno"> 205</span>&#160; <span class="comment">// Map points-to sets to occurrences.</span></div><div class="line"><a name="l00206"></a><span class="lineno"> 206</span>&#160; Map&lt;PointsTo, unsigned&gt; pointsToSets;</div><div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160;</div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160; <span class="comment">// Objects each object shares at least a points-to set with.</span></div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160; Map&lt;NodeID, Set&lt;NodeID&gt;&gt; coPointeeGraph;</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> std::pair&lt;NodeID, unsigned&gt; &amp;keyOcc : keys)</div><div class="line"><a name="l00211"></a><span class="lineno"> 211</span>&#160; {</div><div class="line"><a name="l00212"></a><span class="lineno"> 212</span>&#160; <span class="keyword">const</span> PointsTo &amp;pts = pta-&gt;getPts(keyOcc.first);</div><div class="line"><a name="l00213"></a><span class="lineno"> 213</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldSize = pointsToSets.size();</div><div class="line"><a name="l00214"></a><span class="lineno"> 214</span>&#160; pointsToSets[pts] += keyOcc.second;;</div><div class="line"><a name="l00215"></a><span class="lineno"> 215</span>&#160;</div><div class="line"><a name="l00216"></a><span class="lineno"> 216</span>&#160; <span class="comment">// Edges in this graph have no weight or uniqueness, so we only need to</span></div><div class="line"><a name="l00217"></a><span class="lineno"> 217</span>&#160; <span class="comment">// do this for each points-to set once.</span></div><div class="line"><a name="l00218"></a><span class="lineno"> 218</span>&#160; <span class="keywordflow">if</span> (oldSize != pointsToSets.size())</div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span>&#160; {</div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span>&#160; <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> firstO = !pts.empty() ? *(pts.begin()) : 0;</div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span>&#160; Set&lt;NodeID&gt; &amp;firstOsNeighbours = coPointeeGraph[firstO];</div><div class="line"><a name="l00222"></a><span class="lineno"> 222</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : pts)</div><div class="line"><a name="l00223"></a><span class="lineno"> 223</span>&#160; {</div><div class="line"><a name="l00224"></a><span class="lineno"> 224</span>&#160; <span class="keywordflow">if</span> (o != firstO)</div><div class="line"><a name="l00225"></a><span class="lineno"> 225</span>&#160; {</div><div class="line"><a name="l00226"></a><span class="lineno"> 226</span>&#160; firstOsNeighbours.insert(o);</div><div class="line"><a name="l00227"></a><span class="lineno"> 227</span>&#160; coPointeeGraph[o].insert(firstO);</div><div class="line"><a name="l00228"></a><span class="lineno"> 228</span>&#160; }</div><div class="line"><a name="l00229"></a><span class="lineno"> 229</span>&#160; }</div><div class="line"><a name="l00230"></a><span class="lineno"> 230</span>&#160; }</div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span>&#160; }</div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span>&#160;</div><div class="line"><a name="l00233"></a><span class="lineno"> 233</span>&#160; <span class="keywordtype">size_t</span> <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a> = <a class="code" href="classSVF_1_1NodeIDAllocator.html#a2bd3ca30fc9669d9a0327544bdb4557b">NodeIDAllocator::get</a>()-&gt;<a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>;</div><div class="line"><a name="l00234"></a><span class="lineno"> 234</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#afa74c5ccd22bebe0b76db33066d8b498">NumObjects</a>] = std::to_string(numObjects);</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span>&#160;</div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span>&#160; <span class="keywordtype">size_t</span> numRegions = 0;</div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span>&#160; std::vector&lt;unsigned&gt; objectsRegion;</div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#ab6115b28808af348e1f6a6b58b4cd84f">Options::RegionedClustering</a>)</div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span>&#160; {</div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span>&#160; objectsRegion = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a7d34542f34a8e8008119c3d61943daa2">regionObjects</a>(coPointeeGraph, numObjects, numRegions);</div><div class="line"><a name="l00241"></a><span class="lineno"> 241</span>&#160; }</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span>&#160; <span class="keywordflow">else</span></div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span>&#160; {</div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span>&#160; <span class="comment">// Just a single big region (0).</span></div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span>&#160; objectsRegion.insert(objectsRegion.end(), <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>, 0);</div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span>&#160; numRegions = 1;</div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span>&#160; }</div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span>&#160;</div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span>&#160; <span class="comment">// Set needs to be ordered because getDistanceMatrix, in its n^2 iteration, expects</span></div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span>&#160; <span class="comment">// sets to be ordered (we are building a condensed matrix, not a full matrix, so it</span></div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span>&#160; <span class="comment">// matters). In getDistanceMatrix, doing regionReverseMapping for oi and oj, where</span></div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span>&#160; <span class="comment">// oi &lt; oj, and getting a result moi &gt; moj gives incorrect results.</span></div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span>&#160; <span class="comment">// In the condensed matrix, [b][a] where b &gt;= a, is incorrect.</span></div><div class="line"><a name="l00254"></a><span class="lineno"> 254</span>&#160; std::vector&lt;OrderedSet&lt;NodeID&gt;&gt; regionsObjects(numRegions);</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o = 0; o &lt; <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>; ++o) regionsObjects[objectsRegion[o]].insert(o);</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span>&#160;</div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span>&#160; <span class="comment">// Size of the return node mapping. It is potentially larger than the number of</span></div><div class="line"><a name="l00258"></a><span class="lineno"> 258</span>&#160; <span class="comment">// objects because we align each region to NATIVE_INT_SIZE.</span></div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span>&#160; <span class="keywordtype">size_t</span> numMappings = 0;</div><div class="line"><a name="l00260"></a><span class="lineno"> 260</span>&#160;</div><div class="line"><a name="l00261"></a><span class="lineno"> 261</span>&#160; <span class="comment">// Maps a region to a mapping which maps 0 to n to all objects</span></div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span>&#160; <span class="comment">// in that region.</span></div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span>&#160; std::vector&lt;std::vector&lt;NodeID&gt;&gt; regionMappings(numRegions);</div><div class="line"><a name="l00264"></a><span class="lineno"> 264</span>&#160; <span class="comment">// The reverse: region to mapping of objects to a 0 to n from above.</span></div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span>&#160; std::vector&lt;Map&lt;NodeID, unsigned&gt;&gt; regionReverseMappings(numRegions);</div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span>&#160; <span class="comment">// We can thus use 0 to n for each region to create smaller distance matrices.</span></div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> region = 0; region &lt; numRegions; ++region)</div><div class="line"><a name="l00268"></a><span class="lineno"> 268</span>&#160; {</div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span>&#160; <span class="keywordtype">size_t</span> curr = 0;</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span>&#160; <span class="comment">// With the OrderedSet above, o1 &lt; o2 =&gt; map[o1] &lt; map[o2].</span></div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : regionsObjects[region])</div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span>&#160; {</div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span>&#160; <span class="comment">// push_back here is just like p...[region][curr] = o.</span></div><div class="line"><a name="l00274"></a><span class="lineno"> 274</span>&#160; regionMappings[region].push_back(o);</div><div class="line"><a name="l00275"></a><span class="lineno"> 275</span>&#160; regionReverseMappings[region][o] = curr++;</div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span>&#160; }</div><div class="line"><a name="l00277"></a><span class="lineno"> 277</span>&#160;</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span>&#160; <span class="comment">// curr is the number of objects. A region with no objects makes no sense.</span></div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(curr != 0);</div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span>&#160;</div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span>&#160; <span class="comment">// Number of bits needed for this region if we were</span></div><div class="line"><a name="l00282"></a><span class="lineno"> 282</span>&#160; <span class="comment">// to start assigning from 0 rounded up to the fewest needed</span></div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>&#160; <span class="comment">// native ints. This is added to the number of mappings since</span></div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span>&#160; <span class="comment">// we align each region to a native int.</span></div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span>&#160; numMappings += <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a9aea96839c51ac1e2cbf4813174bb21c">requiredBits</a>(regionsObjects[region].size());</div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span>&#160; }</div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span>&#160;</div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span>&#160; <span class="comment">// Points-to sets which are relevant to a region, i.e., those whose elements</span></div><div class="line"><a name="l00289"></a><span class="lineno"> 289</span>&#160; <span class="comment">// belong to that region. Pair is for occurences.</span></div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span>&#160; std::vector&lt;std::vector&lt;std::pair&lt;const PointsTo *, unsigned&gt;&gt;&gt; regionsPointsTos(numRegions);</div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> Map&lt;PointsTo, unsigned&gt;::value_type &amp;ptocc : pointsToSets)</div><div class="line"><a name="l00292"></a><span class="lineno"> 292</span>&#160; {</div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span>&#160; <span class="keyword">const</span> PointsTo &amp;pt = ptocc.first;</div><div class="line"><a name="l00294"></a><span class="lineno"> 294</span>&#160; <span class="keyword">const</span> <span class="keywordtype">unsigned</span> occ = ptocc.second;</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span>&#160; <span class="keywordflow">if</span> (pt.empty()) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span>&#160; <span class="comment">// Guaranteed that begin() != end() because of the continue above. All objects in pt</span></div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span>&#160; <span class="comment">// will be relevant to the same region.</span></div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span>&#160; <span class="keywordtype">unsigned</span> region = objectsRegion[*(pt.begin())];</div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span>&#160; <span class="comment">// In our &quot;graph&quot;, objects in the same points-to set have an edge between them,</span></div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span>&#160; <span class="comment">// so they are all in the same connected component/region.</span></div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span>&#160; regionsPointsTos[region].push_back(std::make_pair(&amp;pt, occ));</div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span>&#160; }</div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span>&#160;</div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span>&#160; <span class="keywordtype">double</span> clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span>&#160; regioningTime = (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad5f733cad8a103a64e80270acb67567a">RegioningTime</a>] = std::to_string(regioningTime);</div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ac5fe44f10cdbca9754444943a0f5c3c1">NumRegions</a>] = std::to_string(numRegions);</div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span>&#160;</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span>&#160; std::vector&lt;hclust_fast_methods&gt; methods;</div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#a8e0538a7f2e3c5bece69bc69f7074819">Options::ClusterMethod</a> == <a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda66ab3fde95842ef6da0dae1f702a9618">HCLUST_METHOD_SVF_BEST</a>)</div><div class="line"><a name="l00311"></a><span class="lineno"> 311</span>&#160; {</div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913ddad16cc6362447cc32292c4af4c6fe8024">HCLUST_METHOD_SINGLE</a>);</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda44ce22fdfc560f27242e9b8f8e7009f4">HCLUST_METHOD_COMPLETE</a>);</div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda3ab72664fc61704a1ba46bddbc347115">HCLUST_METHOD_AVERAGE</a>);</div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span>&#160; }</div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span>&#160; <span class="keywordflow">else</span></div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span>&#160; {</div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span>&#160; methods.push_back(<a class="code" href="classSVF_1_1Options.html#a8e0538a7f2e3c5bece69bc69f7074819">Options::ClusterMethod</a>);</div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span>&#160; }</div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span>&#160;</div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dd">hclust_fast_methods</a> method : methods)</div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span>&#160; {</div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span>&#160; std::vector&lt;NodeID&gt; nodeMap(numObjects, UINT_MAX);</div><div class="line"><a name="l00324"></a><span class="lineno"> 324</span>&#160;</div><div class="line"><a name="l00325"></a><span class="lineno"> 325</span>&#160; <span class="keywordtype">unsigned</span> numGtIntRegions = 0;</div><div class="line"><a name="l00326"></a><span class="lineno"> 326</span>&#160; <span class="keywordtype">unsigned</span> largestRegion = 0;</div><div class="line"><a name="l00327"></a><span class="lineno"> 327</span>&#160; <span class="keywordtype">unsigned</span> nonTrivialRegionObjects = 0;</div><div class="line"><a name="l00328"></a><span class="lineno"> 328</span>&#160; <span class="keywordtype">unsigned</span> allocCounter = 0;</div><div class="line"><a name="l00329"></a><span class="lineno"> 329</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> region = 0; region &lt; numRegions; ++region)</div><div class="line"><a name="l00330"></a><span class="lineno"> 330</span>&#160; {</div><div class="line"><a name="l00331"></a><span class="lineno"> 331</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> regionNumObjects = regionsObjects[region].size();</div><div class="line"><a name="l00332"></a><span class="lineno"> 332</span>&#160; <span class="comment">// Round up to next Word: ceiling of current allocation to get how</span></div><div class="line"><a name="l00333"></a><span class="lineno"> 333</span>&#160; <span class="comment">// many words and multiply to get the number of bits; if we&#39;re aligning.</span></div><div class="line"><a name="l00334"></a><span class="lineno"> 334</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#a88550ed8c4ec2ccc5d5e40869499787b">Options::RegionAlign</a>)</div><div class="line"><a name="l00335"></a><span class="lineno"> 335</span>&#160; {</div><div class="line"><a name="l00336"></a><span class="lineno"> 336</span>&#160; allocCounter =</div><div class="line"><a name="l00337"></a><span class="lineno"> 337</span>&#160; ((allocCounter + <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a> - 1) / <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>) * <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>;</div><div class="line"><a name="l00338"></a><span class="lineno"> 338</span>&#160; }</div><div class="line"><a name="l00339"></a><span class="lineno"> 339</span>&#160;</div><div class="line"><a name="l00340"></a><span class="lineno"> 340</span>&#160; <span class="keywordflow">if</span> (regionNumObjects &gt; largestRegion) largestRegion = regionNumObjects;</div><div class="line"><a name="l00341"></a><span class="lineno"> 341</span>&#160;</div><div class="line"><a name="l00342"></a><span class="lineno"> 342</span>&#160; <span class="comment">// For regions with fewer than 64 objects, we can just allocate them</span></div><div class="line"><a name="l00343"></a><span class="lineno"> 343</span>&#160; <span class="comment">// however as they will be in the one int regardless..</span></div><div class="line"><a name="l00344"></a><span class="lineno"> 344</span>&#160; <span class="keywordflow">if</span> (regionNumObjects &lt; <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>)</div><div class="line"><a name="l00345"></a><span class="lineno"> 345</span>&#160; {</div><div class="line"><a name="l00346"></a><span class="lineno"> 346</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : regionsObjects[region]) nodeMap[o] = allocCounter++;</div><div class="line"><a name="l00347"></a><span class="lineno"> 347</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00348"></a><span class="lineno"> 348</span>&#160; }</div><div class="line"><a name="l00349"></a><span class="lineno"> 349</span>&#160;</div><div class="line"><a name="l00350"></a><span class="lineno"> 350</span>&#160; ++numGtIntRegions;</div><div class="line"><a name="l00351"></a><span class="lineno"> 351</span>&#160; nonTrivialRegionObjects += regionNumObjects;</div><div class="line"><a name="l00352"></a><span class="lineno"> 352</span>&#160;</div><div class="line"><a name="l00353"></a><span class="lineno"> 353</span>&#160; <span class="keywordtype">double</span> *distMatrix = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#adf415d244ef1fafe7a7de3c360553c0f">getDistanceMatrix</a>(regionsPointsTos[region], regionNumObjects,</div><div class="line"><a name="l00354"></a><span class="lineno"> 354</span>&#160; regionReverseMappings[region], distanceMatrixTime);</div><div class="line"><a name="l00355"></a><span class="lineno"> 355</span>&#160;</div><div class="line"><a name="l00356"></a><span class="lineno"> 356</span>&#160; clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00357"></a><span class="lineno"> 357</span>&#160; <span class="keywordtype">int</span> *dendrogram = <span class="keyword">new</span> <span class="keywordtype">int</span>[2 * (regionNumObjects - 1)];</div><div class="line"><a name="l00358"></a><span class="lineno"> 358</span>&#160; <span class="keywordtype">double</span> *height = <span class="keyword">new</span> <span class="keywordtype">double</span>[regionNumObjects - 1];</div><div class="line"><a name="l00359"></a><span class="lineno"> 359</span>&#160; <a class="code" href="fastcluster_8h.html#acccd226cbdf0944b5c9e24c84a4599c9">hclust_fast</a>(regionNumObjects, distMatrix, method, dendrogram, height);</div><div class="line"><a name="l00360"></a><span class="lineno"> 360</span>&#160; <span class="keyword">delete</span>[] distMatrix;</div><div class="line"><a name="l00361"></a><span class="lineno"> 361</span>&#160; <span class="keyword">delete</span>[] height;</div><div class="line"><a name="l00362"></a><span class="lineno"> 362</span>&#160; clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00363"></a><span class="lineno"> 363</span>&#160; fastClusterTime += (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00364"></a><span class="lineno"> 364</span>&#160;</div><div class="line"><a name="l00365"></a><span class="lineno"> 365</span>&#160; clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00366"></a><span class="lineno"> 366</span>&#160; Set&lt;int&gt; visited;</div><div class="line"><a name="l00367"></a><span class="lineno"> 367</span>&#160; <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#abd44e3b07b0482bacf6b1a080fe650c6">traverseDendrogram</a>(nodeMap, dendrogram, regionNumObjects, allocCounter,</div><div class="line"><a name="l00368"></a><span class="lineno"> 368</span>&#160; visited, regionNumObjects - 1, regionMappings[region]);</div><div class="line"><a name="l00369"></a><span class="lineno"> 369</span>&#160; <span class="keyword">delete</span>[] dendrogram;</div><div class="line"><a name="l00370"></a><span class="lineno"> 370</span>&#160; clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00371"></a><span class="lineno"> 371</span>&#160; dendrogramTraversalTime += (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00372"></a><span class="lineno"> 372</span>&#160; }</div><div class="line"><a name="l00373"></a><span class="lineno"> 373</span>&#160;</div><div class="line"><a name="l00374"></a><span class="lineno"> 374</span>&#160; candidates.push_back(std::make_pair(method, nodeMap));</div><div class="line"><a name="l00375"></a><span class="lineno"> 375</span>&#160;</div><div class="line"><a name="l00376"></a><span class="lineno"> 376</span>&#160; <span class="comment">// Though we &quot;update&quot; these in the loop, they will be the same every iteration.</span></div><div class="line"><a name="l00377"></a><span class="lineno"> 377</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad7cb36a1f0f67864fb8290e9dfd7b639">NumGtIntRegions</a>] = std::to_string(numGtIntRegions);</div><div class="line"><a name="l00378"></a><span class="lineno"> 378</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a172d72ae4ae45fa2baf2f20ff2b499dc">LargestRegion</a>] = std::to_string(largestRegion);</div><div class="line"><a name="l00379"></a><span class="lineno"> 379</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a1bf9461c717e8dabaee6a57f3d76d61f">NumNonTrivialRegionObjects</a>] = std::to_string(nonTrivialRegionObjects);</div><div class="line"><a name="l00380"></a><span class="lineno"> 380</span>&#160; }</div><div class="line"><a name="l00381"></a><span class="lineno"> 381</span>&#160;</div><div class="line"><a name="l00382"></a><span class="lineno"> 382</span>&#160; <span class="comment">// Work out which of the mappings we generated looks best.</span></div><div class="line"><a name="l00383"></a><span class="lineno"> 383</span>&#160; std::pair&lt;hclust_fast_methods, std::vector&lt;NodeID&gt;&gt; bestMapping = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a3f86e733cc075180e9682887c554b8fa">determineBestMapping</a>(candidates, pointsToSets,</div><div class="line"><a name="l00384"></a><span class="lineno"> 384</span>&#160; evalSubtitle, evalTime);</div><div class="line"><a name="l00385"></a><span class="lineno"> 385</span>&#160;</div><div class="line"><a name="l00386"></a><span class="lineno"> 386</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a09d2dbb2faab0a0e03bfa353534116a8">DistanceMatrixTime</a>] = std::to_string(distanceMatrixTime);</div><div class="line"><a name="l00387"></a><span class="lineno"> 387</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a67ab9cffacc1584b2e7bae5d1b08c541">DendrogramTraversalTime</a>] = std::to_string(dendrogramTraversalTime);</div><div class="line"><a name="l00388"></a><span class="lineno"> 388</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ae78d2b60035350c634f6f58d7a043c22">FastClusterTime</a>] = std::to_string(fastClusterTime);</div><div class="line"><a name="l00389"></a><span class="lineno"> 389</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a1d98862e19affdd08740f85490d0d856">EvalTime</a>] = std::to_string(evalTime);</div><div class="line"><a name="l00390"></a><span class="lineno"> 390</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#afef85f0ecacd681357b3945f97d52964">TotalTime</a>] = std::to_string(distanceMatrixTime + dendrogramTraversalTime + fastClusterTime + regioningTime + evalTime);</div><div class="line"><a name="l00391"></a><span class="lineno"> 391</span>&#160;</div><div class="line"><a name="l00392"></a><span class="lineno"> 392</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a3556bdda6725b72d0ca88364daeae32e">BestCandidate</a>] = <a class="code" href="namespaceSVF_1_1SVFUtil.html#a14a4c5124f2fd03ca3d898e2acd54160">SVFUtil::hclustMethodToString</a>(bestMapping.first);</div><div class="line"><a name="l00393"></a><span class="lineno"> 393</span>&#160; <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ac10cbda6a84ce890c9946a5ff35800b7">printStats</a>(evalSubtitle + <span class="stringliteral">&quot;: overall&quot;</span>, overallStats);</div><div class="line"><a name="l00394"></a><span class="lineno"> 394</span>&#160;</div><div class="line"><a name="l00395"></a><span class="lineno"> 395</span>&#160; <span class="keywordflow">return</span> bestMapping.second;</div><div class="line"><a name="l00396"></a><span class="lineno"> 396</span>&#160; }</div><div class="ttc" id="classSVF_1_1NodeIDAllocator_1_1Clusterer_html_ad7cb36a1f0f67864fb8290e9dfd7b639"><div class="ttname"><a href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad7cb36a1f0f67864fb8290e9dfd7b639">SVF::NodeIDAllocator::Clusterer::NumGtIntRegions</a></div><div class="ttdeci">static const std::string NumGtIntRegions</div><div class="ttdef"><b>Definition:</b> <a href="NodeIDAllocator_8h_source.html#l00127">NodeIDAllocator.h:127</a></div></div>
230
+ <div class="fragment"><div class="line"><a name="l00189"></a><span class="lineno"> 189</span>&#160; {</div><div class="line"><a name="l00190"></a><span class="lineno"> 190</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(pta != <span class="keyword">nullptr</span> &amp;&amp; <span class="stringliteral">&quot;Clusterer::cluster: given null BVDataPTAImpl&quot;</span>);</div><div class="line"><a name="l00191"></a><span class="lineno"> 191</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(<a class="code" href="classSVF_1_1Options.html#a2537be131132830c63d408133619a065">Options::NodeAllocStrat</a> == Strategy::DENSE &amp;&amp; <span class="stringliteral">&quot;Clusterer::cluster: only dense allocation clustering currently supported&quot;</span>);</div><div class="line"><a name="l00192"></a><span class="lineno"> 192</span>&#160;</div><div class="line"><a name="l00193"></a><span class="lineno"> 193</span>&#160; Map&lt;std::string, std::string&gt; overallStats;</div><div class="line"><a name="l00194"></a><span class="lineno"> 194</span>&#160; <span class="keywordtype">double</span> fastClusterTime = 0.0;</div><div class="line"><a name="l00195"></a><span class="lineno"> 195</span>&#160; <span class="keywordtype">double</span> distanceMatrixTime = 0.0;</div><div class="line"><a name="l00196"></a><span class="lineno"> 196</span>&#160; <span class="keywordtype">double</span> dendrogramTraversalTime = 0.0;</div><div class="line"><a name="l00197"></a><span class="lineno"> 197</span>&#160; <span class="keywordtype">double</span> regioningTime = 0.0;</div><div class="line"><a name="l00198"></a><span class="lineno"> 198</span>&#160; <span class="keywordtype">double</span> evalTime = 0.0;</div><div class="line"><a name="l00199"></a><span class="lineno"> 199</span>&#160;</div><div class="line"><a name="l00200"></a><span class="lineno"> 200</span>&#160; <span class="comment">// Pair of nodes to their (minimum) distance and the number of occurrences of that distance.</span></div><div class="line"><a name="l00201"></a><span class="lineno"> 201</span>&#160; Map&lt;std::pair&lt;NodeID, NodeID&gt;, std::pair&lt;unsigned, unsigned&gt;&gt; distances;</div><div class="line"><a name="l00202"></a><span class="lineno"> 202</span>&#160;</div><div class="line"><a name="l00203"></a><span class="lineno"> 203</span>&#160; <span class="keywordtype">double</span> clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00204"></a><span class="lineno"> 204</span>&#160;</div><div class="line"><a name="l00205"></a><span class="lineno"> 205</span>&#160; <span class="comment">// Map points-to sets to occurrences.</span></div><div class="line"><a name="l00206"></a><span class="lineno"> 206</span>&#160; Map&lt;PointsTo, unsigned&gt; pointsToSets;</div><div class="line"><a name="l00207"></a><span class="lineno"> 207</span>&#160;</div><div class="line"><a name="l00208"></a><span class="lineno"> 208</span>&#160; <span class="comment">// Objects each object shares at least a points-to set with.</span></div><div class="line"><a name="l00209"></a><span class="lineno"> 209</span>&#160; Map&lt;NodeID, Set&lt;NodeID&gt;&gt; coPointeeGraph;</div><div class="line"><a name="l00210"></a><span class="lineno"> 210</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> std::pair&lt;NodeID, unsigned&gt; &amp;keyOcc : keys)</div><div class="line"><a name="l00211"></a><span class="lineno"> 211</span>&#160; {</div><div class="line"><a name="l00212"></a><span class="lineno"> 212</span>&#160; <span class="keyword">const</span> PointsTo &amp;pts = pta-&gt;getPts(keyOcc.first);</div><div class="line"><a name="l00213"></a><span class="lineno"> 213</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> oldSize = pointsToSets.size();</div><div class="line"><a name="l00214"></a><span class="lineno"> 214</span>&#160; pointsToSets[pts] += keyOcc.second;;</div><div class="line"><a name="l00215"></a><span class="lineno"> 215</span>&#160;</div><div class="line"><a name="l00216"></a><span class="lineno"> 216</span>&#160; <span class="comment">// Edges in this graph have no weight or uniqueness, so we only need to</span></div><div class="line"><a name="l00217"></a><span class="lineno"> 217</span>&#160; <span class="comment">// do this for each points-to set once.</span></div><div class="line"><a name="l00218"></a><span class="lineno"> 218</span>&#160; <span class="keywordflow">if</span> (oldSize != pointsToSets.size())</div><div class="line"><a name="l00219"></a><span class="lineno"> 219</span>&#160; {</div><div class="line"><a name="l00220"></a><span class="lineno"> 220</span>&#160; <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> firstO = !pts.empty() ? *(pts.begin()) : 0;</div><div class="line"><a name="l00221"></a><span class="lineno"> 221</span>&#160; Set&lt;NodeID&gt; &amp;firstOsNeighbours = coPointeeGraph[firstO];</div><div class="line"><a name="l00222"></a><span class="lineno"> 222</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : pts)</div><div class="line"><a name="l00223"></a><span class="lineno"> 223</span>&#160; {</div><div class="line"><a name="l00224"></a><span class="lineno"> 224</span>&#160; <span class="keywordflow">if</span> (o != firstO)</div><div class="line"><a name="l00225"></a><span class="lineno"> 225</span>&#160; {</div><div class="line"><a name="l00226"></a><span class="lineno"> 226</span>&#160; firstOsNeighbours.insert(o);</div><div class="line"><a name="l00227"></a><span class="lineno"> 227</span>&#160; coPointeeGraph[o].insert(firstO);</div><div class="line"><a name="l00228"></a><span class="lineno"> 228</span>&#160; }</div><div class="line"><a name="l00229"></a><span class="lineno"> 229</span>&#160; }</div><div class="line"><a name="l00230"></a><span class="lineno"> 230</span>&#160; }</div><div class="line"><a name="l00231"></a><span class="lineno"> 231</span>&#160; }</div><div class="line"><a name="l00232"></a><span class="lineno"> 232</span>&#160;</div><div class="line"><a name="l00233"></a><span class="lineno"> 233</span>&#160; <span class="keywordtype">size_t</span> <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a> = <a class="code" href="classSVF_1_1NodeIDAllocator.html#a2bd3ca30fc9669d9a0327544bdb4557b">NodeIDAllocator::get</a>()-&gt;<a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>;</div><div class="line"><a name="l00234"></a><span class="lineno"> 234</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#afa74c5ccd22bebe0b76db33066d8b498">NumObjects</a>] = std::to_string(numObjects);</div><div class="line"><a name="l00235"></a><span class="lineno"> 235</span>&#160;</div><div class="line"><a name="l00236"></a><span class="lineno"> 236</span>&#160; <span class="keywordtype">size_t</span> numRegions = 0;</div><div class="line"><a name="l00237"></a><span class="lineno"> 237</span>&#160; std::vector&lt;unsigned&gt; objectsRegion;</div><div class="line"><a name="l00238"></a><span class="lineno"> 238</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#ab6115b28808af348e1f6a6b58b4cd84f">Options::RegionedClustering</a>)</div><div class="line"><a name="l00239"></a><span class="lineno"> 239</span>&#160; {</div><div class="line"><a name="l00240"></a><span class="lineno"> 240</span>&#160; objectsRegion = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a7d34542f34a8e8008119c3d61943daa2">regionObjects</a>(coPointeeGraph, numObjects, numRegions);</div><div class="line"><a name="l00241"></a><span class="lineno"> 241</span>&#160; }</div><div class="line"><a name="l00242"></a><span class="lineno"> 242</span>&#160; <span class="keywordflow">else</span></div><div class="line"><a name="l00243"></a><span class="lineno"> 243</span>&#160; {</div><div class="line"><a name="l00244"></a><span class="lineno"> 244</span>&#160; <span class="comment">// Just a single big region (0).</span></div><div class="line"><a name="l00245"></a><span class="lineno"> 245</span>&#160; objectsRegion.insert(objectsRegion.end(), <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>, 0);</div><div class="line"><a name="l00246"></a><span class="lineno"> 246</span>&#160; numRegions = 1;</div><div class="line"><a name="l00247"></a><span class="lineno"> 247</span>&#160; }</div><div class="line"><a name="l00248"></a><span class="lineno"> 248</span>&#160;</div><div class="line"><a name="l00249"></a><span class="lineno"> 249</span>&#160; <span class="comment">// Set needs to be ordered because getDistanceMatrix, in its n^2 iteration, expects</span></div><div class="line"><a name="l00250"></a><span class="lineno"> 250</span>&#160; <span class="comment">// sets to be ordered (we are building a condensed matrix, not a full matrix, so it</span></div><div class="line"><a name="l00251"></a><span class="lineno"> 251</span>&#160; <span class="comment">// matters). In getDistanceMatrix, doing regionReverseMapping for oi and oj, where</span></div><div class="line"><a name="l00252"></a><span class="lineno"> 252</span>&#160; <span class="comment">// oi &lt; oj, and getting a result moi &gt; moj gives incorrect results.</span></div><div class="line"><a name="l00253"></a><span class="lineno"> 253</span>&#160; <span class="comment">// In the condensed matrix, [b][a] where b &gt;= a, is incorrect.</span></div><div class="line"><a name="l00254"></a><span class="lineno"> 254</span>&#160; std::vector&lt;OrderedSet&lt;NodeID&gt;&gt; regionsObjects(numRegions);</div><div class="line"><a name="l00255"></a><span class="lineno"> 255</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o = 0; o &lt; <a class="code" href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">numObjects</a>; ++o) regionsObjects[objectsRegion[o]].insert(o);</div><div class="line"><a name="l00256"></a><span class="lineno"> 256</span>&#160;</div><div class="line"><a name="l00257"></a><span class="lineno"> 257</span>&#160; <span class="comment">// Size of the return node mapping. It is potentially larger than the number of</span></div><div class="line"><a name="l00258"></a><span class="lineno"> 258</span>&#160; <span class="comment">// objects because we align each region to NATIVE_INT_SIZE.</span></div><div class="line"><a name="l00259"></a><span class="lineno"> 259</span>&#160; <span class="comment">// size_t numMappings = 0;</span></div><div class="line"><a name="l00260"></a><span class="lineno"> 260</span>&#160;</div><div class="line"><a name="l00261"></a><span class="lineno"> 261</span>&#160; <span class="comment">// Maps a region to a mapping which maps 0 to n to all objects</span></div><div class="line"><a name="l00262"></a><span class="lineno"> 262</span>&#160; <span class="comment">// in that region.</span></div><div class="line"><a name="l00263"></a><span class="lineno"> 263</span>&#160; std::vector&lt;std::vector&lt;NodeID&gt;&gt; regionMappings(numRegions);</div><div class="line"><a name="l00264"></a><span class="lineno"> 264</span>&#160; <span class="comment">// The reverse: region to mapping of objects to a 0 to n from above.</span></div><div class="line"><a name="l00265"></a><span class="lineno"> 265</span>&#160; std::vector&lt;Map&lt;NodeID, unsigned&gt;&gt; regionReverseMappings(numRegions);</div><div class="line"><a name="l00266"></a><span class="lineno"> 266</span>&#160; <span class="comment">// We can thus use 0 to n for each region to create smaller distance matrices.</span></div><div class="line"><a name="l00267"></a><span class="lineno"> 267</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> region = 0; region &lt; numRegions; ++region)</div><div class="line"><a name="l00268"></a><span class="lineno"> 268</span>&#160; {</div><div class="line"><a name="l00269"></a><span class="lineno"> 269</span>&#160; <span class="keywordtype">size_t</span> curr = 0;</div><div class="line"><a name="l00270"></a><span class="lineno"> 270</span>&#160; <span class="comment">// With the OrderedSet above, o1 &lt; o2 =&gt; map[o1] &lt; map[o2].</span></div><div class="line"><a name="l00271"></a><span class="lineno"> 271</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : regionsObjects[region])</div><div class="line"><a name="l00272"></a><span class="lineno"> 272</span>&#160; {</div><div class="line"><a name="l00273"></a><span class="lineno"> 273</span>&#160; <span class="comment">// push_back here is just like p...[region][curr] = o.</span></div><div class="line"><a name="l00274"></a><span class="lineno"> 274</span>&#160; regionMappings[region].push_back(o);</div><div class="line"><a name="l00275"></a><span class="lineno"> 275</span>&#160; regionReverseMappings[region][o] = curr++;</div><div class="line"><a name="l00276"></a><span class="lineno"> 276</span>&#160; }</div><div class="line"><a name="l00277"></a><span class="lineno"> 277</span>&#160;</div><div class="line"><a name="l00278"></a><span class="lineno"> 278</span>&#160; <span class="comment">// curr is the number of objects. A region with no objects makes no sense.</span></div><div class="line"><a name="l00279"></a><span class="lineno"> 279</span>&#160; <a class="code" href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a>(curr != 0);</div><div class="line"><a name="l00280"></a><span class="lineno"> 280</span>&#160;</div><div class="line"><a name="l00281"></a><span class="lineno"> 281</span>&#160; <span class="comment">// Number of bits needed for this region if we were</span></div><div class="line"><a name="l00282"></a><span class="lineno"> 282</span>&#160; <span class="comment">// to start assigning from 0 rounded up to the fewest needed</span></div><div class="line"><a name="l00283"></a><span class="lineno"> 283</span>&#160; <span class="comment">// native ints. This is added to the number of mappings since</span></div><div class="line"><a name="l00284"></a><span class="lineno"> 284</span>&#160; <span class="comment">// we align each region to a native int.</span></div><div class="line"><a name="l00285"></a><span class="lineno"> 285</span>&#160; <span class="comment">// numMappings += requiredBits(regionsObjects[region].size());</span></div><div class="line"><a name="l00286"></a><span class="lineno"> 286</span>&#160; }</div><div class="line"><a name="l00287"></a><span class="lineno"> 287</span>&#160;</div><div class="line"><a name="l00288"></a><span class="lineno"> 288</span>&#160; <span class="comment">// Points-to sets which are relevant to a region, i.e., those whose elements</span></div><div class="line"><a name="l00289"></a><span class="lineno"> 289</span>&#160; <span class="comment">// belong to that region. Pair is for occurences.</span></div><div class="line"><a name="l00290"></a><span class="lineno"> 290</span>&#160; std::vector&lt;std::vector&lt;std::pair&lt;const PointsTo *, unsigned&gt;&gt;&gt; regionsPointsTos(numRegions);</div><div class="line"><a name="l00291"></a><span class="lineno"> 291</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> Map&lt;PointsTo, unsigned&gt;::value_type &amp;ptocc : pointsToSets)</div><div class="line"><a name="l00292"></a><span class="lineno"> 292</span>&#160; {</div><div class="line"><a name="l00293"></a><span class="lineno"> 293</span>&#160; <span class="keyword">const</span> PointsTo &amp;pt = ptocc.first;</div><div class="line"><a name="l00294"></a><span class="lineno"> 294</span>&#160; <span class="keyword">const</span> <span class="keywordtype">unsigned</span> occ = ptocc.second;</div><div class="line"><a name="l00295"></a><span class="lineno"> 295</span>&#160; <span class="keywordflow">if</span> (pt.empty()) <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00296"></a><span class="lineno"> 296</span>&#160; <span class="comment">// Guaranteed that begin() != end() because of the continue above. All objects in pt</span></div><div class="line"><a name="l00297"></a><span class="lineno"> 297</span>&#160; <span class="comment">// will be relevant to the same region.</span></div><div class="line"><a name="l00298"></a><span class="lineno"> 298</span>&#160; <span class="keywordtype">unsigned</span> region = objectsRegion[*(pt.begin())];</div><div class="line"><a name="l00299"></a><span class="lineno"> 299</span>&#160; <span class="comment">// In our &quot;graph&quot;, objects in the same points-to set have an edge between them,</span></div><div class="line"><a name="l00300"></a><span class="lineno"> 300</span>&#160; <span class="comment">// so they are all in the same connected component/region.</span></div><div class="line"><a name="l00301"></a><span class="lineno"> 301</span>&#160; regionsPointsTos[region].push_back(std::make_pair(&amp;pt, occ));</div><div class="line"><a name="l00302"></a><span class="lineno"> 302</span>&#160; }</div><div class="line"><a name="l00303"></a><span class="lineno"> 303</span>&#160;</div><div class="line"><a name="l00304"></a><span class="lineno"> 304</span>&#160; <span class="keywordtype">double</span> clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00305"></a><span class="lineno"> 305</span>&#160; regioningTime = (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00306"></a><span class="lineno"> 306</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad5f733cad8a103a64e80270acb67567a">RegioningTime</a>] = std::to_string(regioningTime);</div><div class="line"><a name="l00307"></a><span class="lineno"> 307</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ac5fe44f10cdbca9754444943a0f5c3c1">NumRegions</a>] = std::to_string(numRegions);</div><div class="line"><a name="l00308"></a><span class="lineno"> 308</span>&#160;</div><div class="line"><a name="l00309"></a><span class="lineno"> 309</span>&#160; std::vector&lt;hclust_fast_methods&gt; methods;</div><div class="line"><a name="l00310"></a><span class="lineno"> 310</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#a8e0538a7f2e3c5bece69bc69f7074819">Options::ClusterMethod</a> == <a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda66ab3fde95842ef6da0dae1f702a9618">HCLUST_METHOD_SVF_BEST</a>)</div><div class="line"><a name="l00311"></a><span class="lineno"> 311</span>&#160; {</div><div class="line"><a name="l00312"></a><span class="lineno"> 312</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913ddad16cc6362447cc32292c4af4c6fe8024">HCLUST_METHOD_SINGLE</a>);</div><div class="line"><a name="l00313"></a><span class="lineno"> 313</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda44ce22fdfc560f27242e9b8f8e7009f4">HCLUST_METHOD_COMPLETE</a>);</div><div class="line"><a name="l00314"></a><span class="lineno"> 314</span>&#160; methods.push_back(<a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dda3ab72664fc61704a1ba46bddbc347115">HCLUST_METHOD_AVERAGE</a>);</div><div class="line"><a name="l00315"></a><span class="lineno"> 315</span>&#160; }</div><div class="line"><a name="l00316"></a><span class="lineno"> 316</span>&#160; <span class="keywordflow">else</span></div><div class="line"><a name="l00317"></a><span class="lineno"> 317</span>&#160; {</div><div class="line"><a name="l00318"></a><span class="lineno"> 318</span>&#160; methods.push_back(<a class="code" href="classSVF_1_1Options.html#a8e0538a7f2e3c5bece69bc69f7074819">Options::ClusterMethod</a>);</div><div class="line"><a name="l00319"></a><span class="lineno"> 319</span>&#160; }</div><div class="line"><a name="l00320"></a><span class="lineno"> 320</span>&#160;</div><div class="line"><a name="l00321"></a><span class="lineno"> 321</span>&#160; <span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code" href="fastcluster_8h.html#a4205a14ad66b3320d2e94c61d74913dd">hclust_fast_methods</a> method : methods)</div><div class="line"><a name="l00322"></a><span class="lineno"> 322</span>&#160; {</div><div class="line"><a name="l00323"></a><span class="lineno"> 323</span>&#160; std::vector&lt;NodeID&gt; nodeMap(numObjects, UINT_MAX);</div><div class="line"><a name="l00324"></a><span class="lineno"> 324</span>&#160;</div><div class="line"><a name="l00325"></a><span class="lineno"> 325</span>&#160; <span class="keywordtype">unsigned</span> numGtIntRegions = 0;</div><div class="line"><a name="l00326"></a><span class="lineno"> 326</span>&#160; <span class="keywordtype">unsigned</span> largestRegion = 0;</div><div class="line"><a name="l00327"></a><span class="lineno"> 327</span>&#160; <span class="keywordtype">unsigned</span> nonTrivialRegionObjects = 0;</div><div class="line"><a name="l00328"></a><span class="lineno"> 328</span>&#160; <span class="keywordtype">unsigned</span> allocCounter = 0;</div><div class="line"><a name="l00329"></a><span class="lineno"> 329</span>&#160; <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> region = 0; region &lt; numRegions; ++region)</div><div class="line"><a name="l00330"></a><span class="lineno"> 330</span>&#160; {</div><div class="line"><a name="l00331"></a><span class="lineno"> 331</span>&#160; <span class="keyword">const</span> <span class="keywordtype">size_t</span> regionNumObjects = regionsObjects[region].size();</div><div class="line"><a name="l00332"></a><span class="lineno"> 332</span>&#160; <span class="comment">// Round up to next Word: ceiling of current allocation to get how</span></div><div class="line"><a name="l00333"></a><span class="lineno"> 333</span>&#160; <span class="comment">// many words and multiply to get the number of bits; if we&#39;re aligning.</span></div><div class="line"><a name="l00334"></a><span class="lineno"> 334</span>&#160; <span class="keywordflow">if</span> (<a class="code" href="classSVF_1_1Options.html#a88550ed8c4ec2ccc5d5e40869499787b">Options::RegionAlign</a>)</div><div class="line"><a name="l00335"></a><span class="lineno"> 335</span>&#160; {</div><div class="line"><a name="l00336"></a><span class="lineno"> 336</span>&#160; allocCounter =</div><div class="line"><a name="l00337"></a><span class="lineno"> 337</span>&#160; ((allocCounter + <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a> - 1) / <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>) * <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>;</div><div class="line"><a name="l00338"></a><span class="lineno"> 338</span>&#160; }</div><div class="line"><a name="l00339"></a><span class="lineno"> 339</span>&#160;</div><div class="line"><a name="l00340"></a><span class="lineno"> 340</span>&#160; <span class="keywordflow">if</span> (regionNumObjects &gt; largestRegion) largestRegion = regionNumObjects;</div><div class="line"><a name="l00341"></a><span class="lineno"> 341</span>&#160;</div><div class="line"><a name="l00342"></a><span class="lineno"> 342</span>&#160; <span class="comment">// For regions with fewer than 64 objects, we can just allocate them</span></div><div class="line"><a name="l00343"></a><span class="lineno"> 343</span>&#160; <span class="comment">// however as they will be in the one int regardless..</span></div><div class="line"><a name="l00344"></a><span class="lineno"> 344</span>&#160; <span class="keywordflow">if</span> (regionNumObjects &lt; <a class="code" href="SVFBasicTypes_8h.html#ab8ca0fd9d0caa6817d305cae0f1cf022">NATIVE_INT_SIZE</a>)</div><div class="line"><a name="l00345"></a><span class="lineno"> 345</span>&#160; {</div><div class="line"><a name="l00346"></a><span class="lineno"> 346</span>&#160; <span class="keywordflow">for</span> (<a class="code" href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">NodeID</a> o : regionsObjects[region]) nodeMap[o] = allocCounter++;</div><div class="line"><a name="l00347"></a><span class="lineno"> 347</span>&#160; <span class="keywordflow">continue</span>;</div><div class="line"><a name="l00348"></a><span class="lineno"> 348</span>&#160; }</div><div class="line"><a name="l00349"></a><span class="lineno"> 349</span>&#160;</div><div class="line"><a name="l00350"></a><span class="lineno"> 350</span>&#160; ++numGtIntRegions;</div><div class="line"><a name="l00351"></a><span class="lineno"> 351</span>&#160; nonTrivialRegionObjects += regionNumObjects;</div><div class="line"><a name="l00352"></a><span class="lineno"> 352</span>&#160;</div><div class="line"><a name="l00353"></a><span class="lineno"> 353</span>&#160; <span class="keywordtype">double</span> *distMatrix = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#adf415d244ef1fafe7a7de3c360553c0f">getDistanceMatrix</a>(regionsPointsTos[region], regionNumObjects,</div><div class="line"><a name="l00354"></a><span class="lineno"> 354</span>&#160; regionReverseMappings[region], distanceMatrixTime);</div><div class="line"><a name="l00355"></a><span class="lineno"> 355</span>&#160;</div><div class="line"><a name="l00356"></a><span class="lineno"> 356</span>&#160; clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00357"></a><span class="lineno"> 357</span>&#160; <span class="keywordtype">int</span> *dendrogram = <span class="keyword">new</span> <span class="keywordtype">int</span>[2 * (regionNumObjects - 1)];</div><div class="line"><a name="l00358"></a><span class="lineno"> 358</span>&#160; <span class="keywordtype">double</span> *height = <span class="keyword">new</span> <span class="keywordtype">double</span>[regionNumObjects - 1];</div><div class="line"><a name="l00359"></a><span class="lineno"> 359</span>&#160; <a class="code" href="fastcluster_8h.html#acccd226cbdf0944b5c9e24c84a4599c9">hclust_fast</a>(regionNumObjects, distMatrix, method, dendrogram, height);</div><div class="line"><a name="l00360"></a><span class="lineno"> 360</span>&#160; <span class="keyword">delete</span>[] distMatrix;</div><div class="line"><a name="l00361"></a><span class="lineno"> 361</span>&#160; <span class="keyword">delete</span>[] height;</div><div class="line"><a name="l00362"></a><span class="lineno"> 362</span>&#160; clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00363"></a><span class="lineno"> 363</span>&#160; fastClusterTime += (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00364"></a><span class="lineno"> 364</span>&#160;</div><div class="line"><a name="l00365"></a><span class="lineno"> 365</span>&#160; clkStart = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00366"></a><span class="lineno"> 366</span>&#160; Set&lt;int&gt; visited;</div><div class="line"><a name="l00367"></a><span class="lineno"> 367</span>&#160; <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#abd44e3b07b0482bacf6b1a080fe650c6">traverseDendrogram</a>(nodeMap, dendrogram, regionNumObjects, allocCounter,</div><div class="line"><a name="l00368"></a><span class="lineno"> 368</span>&#160; visited, regionNumObjects - 1, regionMappings[region]);</div><div class="line"><a name="l00369"></a><span class="lineno"> 369</span>&#160; <span class="keyword">delete</span>[] dendrogram;</div><div class="line"><a name="l00370"></a><span class="lineno"> 370</span>&#160; clkEnd = <a class="code" href="classSVF_1_1PTAStat.html#a3c4eaa1695ea13405911ae1621f98edc">PTAStat::getClk</a>(<span class="keyword">true</span>);</div><div class="line"><a name="l00371"></a><span class="lineno"> 371</span>&#160; dendrogramTraversalTime += (clkEnd - clkStart) / <a class="code" href="SVFBasicTypes_8h.html#a1aeda3370621dc00e9a0fe8e7aabc736">TIMEINTERVAL</a>;</div><div class="line"><a name="l00372"></a><span class="lineno"> 372</span>&#160; }</div><div class="line"><a name="l00373"></a><span class="lineno"> 373</span>&#160;</div><div class="line"><a name="l00374"></a><span class="lineno"> 374</span>&#160; candidates.push_back(std::make_pair(method, nodeMap));</div><div class="line"><a name="l00375"></a><span class="lineno"> 375</span>&#160;</div><div class="line"><a name="l00376"></a><span class="lineno"> 376</span>&#160; <span class="comment">// Though we &quot;update&quot; these in the loop, they will be the same every iteration.</span></div><div class="line"><a name="l00377"></a><span class="lineno"> 377</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad7cb36a1f0f67864fb8290e9dfd7b639">NumGtIntRegions</a>] = std::to_string(numGtIntRegions);</div><div class="line"><a name="l00378"></a><span class="lineno"> 378</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a172d72ae4ae45fa2baf2f20ff2b499dc">LargestRegion</a>] = std::to_string(largestRegion);</div><div class="line"><a name="l00379"></a><span class="lineno"> 379</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a1bf9461c717e8dabaee6a57f3d76d61f">NumNonTrivialRegionObjects</a>] = std::to_string(nonTrivialRegionObjects);</div><div class="line"><a name="l00380"></a><span class="lineno"> 380</span>&#160; }</div><div class="line"><a name="l00381"></a><span class="lineno"> 381</span>&#160;</div><div class="line"><a name="l00382"></a><span class="lineno"> 382</span>&#160; <span class="comment">// Work out which of the mappings we generated looks best.</span></div><div class="line"><a name="l00383"></a><span class="lineno"> 383</span>&#160; std::pair&lt;hclust_fast_methods, std::vector&lt;NodeID&gt;&gt; bestMapping = <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a3f86e733cc075180e9682887c554b8fa">determineBestMapping</a>(candidates, pointsToSets,</div><div class="line"><a name="l00384"></a><span class="lineno"> 384</span>&#160; evalSubtitle, evalTime);</div><div class="line"><a name="l00385"></a><span class="lineno"> 385</span>&#160;</div><div class="line"><a name="l00386"></a><span class="lineno"> 386</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a09d2dbb2faab0a0e03bfa353534116a8">DistanceMatrixTime</a>] = std::to_string(distanceMatrixTime);</div><div class="line"><a name="l00387"></a><span class="lineno"> 387</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a67ab9cffacc1584b2e7bae5d1b08c541">DendrogramTraversalTime</a>] = std::to_string(dendrogramTraversalTime);</div><div class="line"><a name="l00388"></a><span class="lineno"> 388</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ae78d2b60035350c634f6f58d7a043c22">FastClusterTime</a>] = std::to_string(fastClusterTime);</div><div class="line"><a name="l00389"></a><span class="lineno"> 389</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a1d98862e19affdd08740f85490d0d856">EvalTime</a>] = std::to_string(evalTime);</div><div class="line"><a name="l00390"></a><span class="lineno"> 390</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#afef85f0ecacd681357b3945f97d52964">TotalTime</a>] = std::to_string(distanceMatrixTime + dendrogramTraversalTime + fastClusterTime + regioningTime + evalTime);</div><div class="line"><a name="l00391"></a><span class="lineno"> 391</span>&#160;</div><div class="line"><a name="l00392"></a><span class="lineno"> 392</span>&#160; overallStats[<a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a3556bdda6725b72d0ca88364daeae32e">BestCandidate</a>] = <a class="code" href="namespaceSVF_1_1SVFUtil.html#a14a4c5124f2fd03ca3d898e2acd54160">SVFUtil::hclustMethodToString</a>(bestMapping.first);</div><div class="line"><a name="l00393"></a><span class="lineno"> 393</span>&#160; <a class="code" href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ac10cbda6a84ce890c9946a5ff35800b7">printStats</a>(evalSubtitle + <span class="stringliteral">&quot;: overall&quot;</span>, overallStats);</div><div class="line"><a name="l00394"></a><span class="lineno"> 394</span>&#160;</div><div class="line"><a name="l00395"></a><span class="lineno"> 395</span>&#160; <span class="keywordflow">return</span> bestMapping.second;</div><div class="line"><a name="l00396"></a><span class="lineno"> 396</span>&#160; }</div><div class="ttc" id="classSVF_1_1NodeIDAllocator_1_1Clusterer_html_ad7cb36a1f0f67864fb8290e9dfd7b639"><div class="ttname"><a href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#ad7cb36a1f0f67864fb8290e9dfd7b639">SVF::NodeIDAllocator::Clusterer::NumGtIntRegions</a></div><div class="ttdeci">static const std::string NumGtIntRegions</div><div class="ttdef"><b>Definition:</b> <a href="NodeIDAllocator_8h_source.html#l00127">NodeIDAllocator.h:127</a></div></div>
231
231
  <div class="ttc" id="namespaceSVF_html_a43a65e0d33af3c743294f7a1139d2301"><div class="ttname"><a href="namespaceSVF.html#a43a65e0d33af3c743294f7a1139d2301">SVF::NodeID</a></div><div class="ttdeci">unsigned NodeID</div><div class="ttdef"><b>Definition:</b> <a href="MTAResultValidator_8h_source.html#l00018">MTAResultValidator.h:18</a></div></div>
232
- <div class="ttc" id="classSVF_1_1NodeIDAllocator_1_1Clusterer_html_a9aea96839c51ac1e2cbf4813174bb21c"><div class="ttname"><a href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a9aea96839c51ac1e2cbf4813174bb21c">SVF::NodeIDAllocator::Clusterer::requiredBits</a></div><div class="ttdeci">static unsigned requiredBits(const PointsTo &amp;pts)</div><div class="ttdoc">Returns the minimum number of bits required to represent pts in a perfect world. </div><div class="ttdef"><b>Definition:</b> <a href="NodeIDAllocator_8cpp_source.html#l00418">NodeIDAllocator.cpp:418</a></div></div>
233
232
  <div class="ttc" id="classSVF_1_1NodeIDAllocator_1_1Clusterer_html_a67ab9cffacc1584b2e7bae5d1b08c541"><div class="ttname"><a href="classSVF_1_1NodeIDAllocator_1_1Clusterer.html#a67ab9cffacc1584b2e7bae5d1b08c541">SVF::NodeIDAllocator::Clusterer::DendrogramTraversalTime</a></div><div class="ttdeci">static const std::string DendrogramTraversalTime</div><div class="ttdef"><b>Definition:</b> <a href="NodeIDAllocator_8h_source.html#l00118">NodeIDAllocator.h:118</a></div></div>
234
233
  <div class="ttc" id="util_8h_html_a07d17d6d5d1074c0969bc5d3c3d1d84a"><div class="ttname"><a href="util_8h.html#a07d17d6d5d1074c0969bc5d3c3d1d84a">assert</a></div><div class="ttdeci">#define assert(ex)</div><div class="ttdef"><b>Definition:</b> <a href="util_8h_source.html#l00141">util.h:141</a></div></div>
235
234
  <div class="ttc" id="classSVF_1_1NodeIDAllocator_html_a190c729a3f3f622f82cee4917946b50f"><div class="ttname"><a href="classSVF_1_1NodeIDAllocator.html#a190c729a3f3f622f82cee4917946b50f">SVF::NodeIDAllocator::numObjects</a></div><div class="ttdeci">NodeID numObjects</div><div class="ttdef"><b>Definition:</b> <a href="NodeIDAllocator_8h_source.html#l00087">NodeIDAllocator.h:87</a></div></div>
@@ -135,8 +135,8 @@ Typedefs</h2></td></tr>
135
135
  <tr class="separator:a68302f07b13f6e1f39aace5699762c41"><td class="memSeparator" colspan="2">&#160;</td></tr>
136
136
  <tr class="memitem:a5c2b39ae857d78ed9dda83880e703b0f"><td class="memItemLeft" align="right" valign="top">typedef struct <a class="el" href="structSVF_1_1SVFUtil_1_1equalNodeBS.html">SVF::SVFUtil::equalNodeBS</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#a5c2b39ae857d78ed9dda83880e703b0f">equalNodeBS</a></td></tr>
137
137
  <tr class="separator:a5c2b39ae857d78ed9dda83880e703b0f"><td class="memSeparator" colspan="2">&#160;</td></tr>
138
- <tr class="memitem:a798b7f30608d8c1688d4fdce2c3097f4"><td class="memItemLeft" align="right" valign="top">typedef <a class="el" href="namespaceSVF.html#a4f21e91ff8eaea5207afe5c60dbd78d7">OrderedSet</a>&lt; <a class="el" href="classSVF_1_1PointsTo.html">PointsTo</a>, <a class="el" href="structSVF_1_1SVFUtil_1_1equalNodeBS.html">equalNodeBS</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">PointsToList</a></td></tr>
139
- <tr class="separator:a798b7f30608d8c1688d4fdce2c3097f4"><td class="memSeparator" colspan="2">&#160;</td></tr>
138
+ <tr class="memitem:a4740b14abf7d308e7806a0d6d6c42ee2"><td class="memItemLeft" align="right" valign="top">typedef <a class="el" href="namespaceSVF.html#a4f21e91ff8eaea5207afe5c60dbd78d7">OrderedSet</a>&lt; <a class="el" href="classSVF_1_1PointsTo.html">PointsTo</a>, <a class="el" href="structSVF_1_1SVFUtil_1_1equalPointsTo.html">equalPointsTo</a> &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">PointsToList</a></td></tr>
139
+ <tr class="separator:a4740b14abf7d308e7806a0d6d6c42ee2"><td class="memSeparator" colspan="2">&#160;</td></tr>
140
140
  </table><table class="memberdecls">
141
141
  <tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="func-members"></a>
142
142
  Functions</h2></td></tr>
@@ -271,7 +271,7 @@ Functions</h2></td></tr>
271
271
  <tr class="separator:a8f749354b7e882ef3e5bf5081fa715b5"><td class="memSeparator" colspan="2">&#160;</td></tr>
272
272
  <tr class="memitem:a86ebab122895189be57637b84adc7642"><td class="memItemLeft" align="right" valign="top"><a class="el" href="namespaceSVF.html#a740396763e377643790c8b803ab3e4ea">NodeBS</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#a86ebab122895189be57637b84adc7642">ptsToNodeBS</a> (const <a class="el" href="classSVF_1_1PointsTo.html">PointsTo</a> &amp;pts)</td></tr>
273
273
  <tr class="separator:a86ebab122895189be57637b84adc7642"><td class="memSeparator" colspan="2">&#160;</td></tr>
274
- <tr class="memitem:af4ceddbe4d57b24e80201bc895f73810"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#af4ceddbe4d57b24e80201bc895f73810">dumpPointsToList</a> (const <a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">PointsToList</a> &amp;ptl)</td></tr>
274
+ <tr class="memitem:af4ceddbe4d57b24e80201bc895f73810"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#af4ceddbe4d57b24e80201bc895f73810">dumpPointsToList</a> (const <a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">PointsToList</a> &amp;ptl)</td></tr>
275
275
  <tr class="separator:af4ceddbe4d57b24e80201bc895f73810"><td class="memSeparator" colspan="2">&#160;</td></tr>
276
276
  <tr class="memitem:ad2c53be5490882768d51aa894b37cbf1"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespaceSVF_1_1SVFUtil.html#ad2c53be5490882768d51aa894b37cbf1">isIntrinsicFun</a> (const <a class="el" href="namespaceSVF.html#a5faee14fa1dd41447bc73ac365fe33c1">Function</a> *func)</td></tr>
277
277
  <tr class="separator:ad2c53be5490882768d51aa894b37cbf1"><td class="memSeparator" colspan="2">&#160;</td></tr>
@@ -580,14 +580,14 @@ Functions</h2></td></tr>
580
580
 
581
581
  </div>
582
582
  </div>
583
- <a id="a798b7f30608d8c1688d4fdce2c3097f4"></a>
584
- <h2 class="memtitle"><span class="permalink"><a href="#a798b7f30608d8c1688d4fdce2c3097f4">&#9670;&nbsp;</a></span>PointsToList</h2>
583
+ <a id="a4740b14abf7d308e7806a0d6d6c42ee2"></a>
584
+ <h2 class="memtitle"><span class="permalink"><a href="#a4740b14abf7d308e7806a0d6d6c42ee2">&#9670;&nbsp;</a></span>PointsToList</h2>
585
585
 
586
586
  <div class="memitem">
587
587
  <div class="memproto">
588
588
  <table class="memname">
589
589
  <tr>
590
- <td class="memname">typedef <a class="el" href="namespaceSVF.html#a4f21e91ff8eaea5207afe5c60dbd78d7">OrderedSet</a>&lt;<a class="el" href="classSVF_1_1PointsTo.html">PointsTo</a>, <a class="el" href="structSVF_1_1SVFUtil_1_1equalNodeBS.html">equalNodeBS</a>&gt; <a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">SVF::SVFUtil::PointsToList</a></td>
590
+ <td class="memname">typedef <a class="el" href="namespaceSVF.html#a4f21e91ff8eaea5207afe5c60dbd78d7">OrderedSet</a>&lt;<a class="el" href="classSVF_1_1PointsTo.html">PointsTo</a>, <a class="el" href="structSVF_1_1SVFUtil_1_1equalPointsTo.html">equalPointsTo</a>&gt; <a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">SVF::SVFUtil::PointsToList</a></td>
591
591
  </tr>
592
592
  </table>
593
593
  </div><div class="memdoc">
@@ -1004,7 +1004,7 @@ template&lt;class X , class Y &gt; </div>
1004
1004
  <tr>
1005
1005
  <td class="memname">void SVF::SVFUtil::dumpPointsToList </td>
1006
1006
  <td>(</td>
1007
- <td class="paramtype">const <a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">PointsToList</a> &amp;&#160;</td>
1007
+ <td class="paramtype">const <a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">PointsToList</a> &amp;&#160;</td>
1008
1008
  <td class="paramname"><em>ptl</em></td><td>)</td>
1009
1009
  <td></td>
1010
1010
  </tr>
@@ -89,7 +89,7 @@ $(function() {
89
89
  : <a class="el" href="namespaceSVF.html#ae545a88267bd2246de827cf590675aca">SVF</a>
90
90
  </li>
91
91
  <li>PointsToList
92
- : <a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">SVF::SVFUtil</a>
92
+ : <a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">SVF::SVFUtil</a>
93
93
  </li>
94
94
  <li>PostDominatorTree
95
95
  : <a class="el" href="namespaceSVF.html#ab34383ee87cd45eb485fa29db482ffef">SVF</a>
@@ -83,7 +83,7 @@ $(function() {
83
83
  : <a class="el" href="namespaceSVF.html#ae545a88267bd2246de827cf590675aca">SVF</a>
84
84
  </li>
85
85
  <li>PointsToList
86
- : <a class="el" href="namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4">SVF::SVFUtil</a>
86
+ : <a class="el" href="namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2">SVF::SVFUtil</a>
87
87
  </li>
88
88
  <li>PostDominatorTree
89
89
  : <a class="el" href="namespaceSVF.html#ab34383ee87cd45eb485fa29db482ffef">SVF</a>
@@ -137,7 +137,7 @@ var searchData=
137
137
  ['pointsto_2eh',['PointsTo.h',['../PointsTo_8h.html',1,'']]],
138
138
  ['pointstoid',['PointsToID',['../namespaceSVF.html#ae545a88267bd2246de827cf590675aca',1,'SVF']]],
139
139
  ['pointstoiterator',['PointsToIterator',['../classSVF_1_1PointsTo_1_1PointsToIterator.html',1,'SVF::PointsTo::PointsToIterator'],['../classSVF_1_1PointsTo_1_1PointsToIterator.html#a3974dee7680da3a43b58932766e77a16',1,'SVF::PointsTo::PointsToIterator::PointsToIterator(void)=delete'],['../classSVF_1_1PointsTo_1_1PointsToIterator.html#a19f371ccb5b1c84fb4adfd5b0c8a3eec',1,'SVF::PointsTo::PointsToIterator::PointsToIterator(const PointsToIterator &amp;pt)'],['../classSVF_1_1PointsTo_1_1PointsToIterator.html#abe128c47fb16093756195f789e5f68d5',1,'SVF::PointsTo::PointsToIterator::PointsToIterator(PointsToIterator &amp;&amp;pt)'],['../classSVF_1_1PointsTo_1_1PointsToIterator.html#ad9efcd9fb0c8201b9166a1560d06a71b',1,'SVF::PointsTo::PointsToIterator::PointsToIterator(const PointsTo *pt, bool end=false)']]],
140
- ['pointstolist',['PointsToList',['../classSVF_1_1MRGenerator.html#a8b254a0c5063e25f297d1b00fb0b515e',1,'SVF::MRGenerator::PointsToList()'],['../namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4',1,'SVF::SVFUtil::PointsToList()']]],
140
+ ['pointstolist',['PointsToList',['../classSVF_1_1MRGenerator.html#a8b254a0c5063e25f297d1b00fb0b515e',1,'SVF::MRGenerator::PointsToList()'],['../namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2',1,'SVF::SVFUtil::PointsToList()']]],
141
141
  ['pop',['pop',['../classSVF_1_1List.html#a6e85bd3d8b23ccc7752a72e2a5b171ab',1,'SVF::List::pop()'],['../classSVF_1_1FIFOWorkList.html#a8fa72918fce7e9c0b2dc34b683a797c6',1,'SVF::FIFOWorkList::pop()'],['../classSVF_1_1FILOWorkList.html#a3fd9acb6d09fd142bfd402fdf8cac93b',1,'SVF::FILOWorkList::pop()']]],
142
142
  ['popen',['popen',['../util_8h.html#a7a377e01cff8d8243569ddc8bfef959b',1,'util.h']]],
143
143
  ['popfromctpworklist',['popFromCTPWorkList',['../classSVF_1_1LockAnalysis.html#ac3de5acfb887c17ebf1213a1c2c38b58',1,'SVF::LockAnalysis::popFromCTPWorkList()'],['../classSVF_1_1TCT.html#ad84cdb0d192312f96d006f7b9e660da3',1,'SVF::TCT::popFromCTPWorkList()']]],
@@ -35,7 +35,7 @@ var searchData=
35
35
  ['pointer',['pointer',['../classSVF_1_1PointsTo_1_1PointsToIterator.html#aff5a4ee71f88ab9b0e1851d6e41e294f',1,'SVF::PointsTo::PointsToIterator::pointer()'],['../classSVF_1_1CoreBitVector_1_1CoreBitVectorIterator.html#a6d8d22b1c8b4405a8e3caddacae6f8f5',1,'SVF::CoreBitVector::CoreBitVectorIterator::pointer()']]],
36
36
  ['pointertype',['PointerType',['../structSVF_1_1SVFUtil_1_1cast__retty__impl_3_01To_00_01std_1_1unique__ptr_3_01From_01_4_01_4.html#a9d08abc346f3b77c487eba144f3cbd8d',1,'SVF::SVFUtil::cast_retty_impl&lt; To, std::unique_ptr&lt; From &gt; &gt;::PointerType()'],['../namespaceSVF.html#aa962cc1d782cc46553251e96b64a754b',1,'SVF::PointerType()']]],
37
37
  ['pointstoid',['PointsToID',['../namespaceSVF.html#ae545a88267bd2246de827cf590675aca',1,'SVF']]],
38
- ['pointstolist',['PointsToList',['../classSVF_1_1MRGenerator.html#a8b254a0c5063e25f297d1b00fb0b515e',1,'SVF::MRGenerator::PointsToList()'],['../namespaceSVF_1_1SVFUtil.html#a798b7f30608d8c1688d4fdce2c3097f4',1,'SVF::SVFUtil::PointsToList()']]],
38
+ ['pointstolist',['PointsToList',['../classSVF_1_1MRGenerator.html#a8b254a0c5063e25f297d1b00fb0b515e',1,'SVF::MRGenerator::PointsToList()'],['../namespaceSVF_1_1SVFUtil.html#a4740b14abf7d308e7806a0d6d6c42ee2',1,'SVF::SVFUtil::PointsToList()']]],
39
39
  ['postdominatortree',['PostDominatorTree',['../namespaceSVF.html#ab34383ee87cd45eb485fa29db482ffef',1,'SVF']]],
40
40
  ['postdominatortreewrapperpass',['PostDominatorTreeWrapperPass',['../namespaceSVF.html#a7f570d09953aa4ec60fd1d5f7f71b521',1,'SVF']]],
41
41
  ['ptacgnodeset',['PTACGNodeSet',['../classSVF_1_1TCT.html#afb579a5bdcc0a1c6b075bb9aae36c237',1,'SVF::TCT']]],
@@ -161,7 +161,7 @@ inline NodeBS ptsToNodeBS(const PointsTo &pts)
161
161
  return nbs;
162
162
  }
163
163
 
164
- typedef OrderedSet<PointsTo, equalNodeBS> PointsToList;
164
+ typedef OrderedSet<PointsTo, equalPointsTo> PointsToList;
165
165
  void dumpPointsToList(const PointsToList& ptl);
166
166
 
167
167
  inline bool isIntrinsicFun(const Function* func)
@@ -256,7 +256,7 @@ namespace SVF
256
256
 
257
257
  // Size of the return node mapping. It is potentially larger than the number of
258
258
  // objects because we align each region to NATIVE_INT_SIZE.
259
- size_t numMappings = 0;
259
+ // size_t numMappings = 0;
260
260
 
261
261
  // Maps a region to a mapping which maps 0 to n to all objects
262
262
  // in that region.
@@ -282,7 +282,7 @@ namespace SVF
282
282
  // to start assigning from 0 rounded up to the fewest needed
283
283
  // native ints. This is added to the number of mappings since
284
284
  // we align each region to a native int.
285
- numMappings += requiredBits(regionsObjects[region].size());
285
+ // numMappings += requiredBits(regionsObjects[region].size());
286
286
  }
287
287
 
288
288
  // Points-to sets which are relevant to a region, i.e., those whose elements
@@ -121,19 +121,15 @@ void AndersenStat::constraintGraphStat()
121
121
  u32_t cgNodeNumber = 0;
122
122
  u32_t objNodeNumber = 0;
123
123
  u32_t addrtotalIn = 0;
124
- u32_t addrtotalOut = 0;
125
124
  u32_t addrmaxIn = 0;
126
125
  u32_t addrmaxOut = 0;
127
126
  u32_t copytotalIn = 0;
128
- u32_t copytotalOut = 0;
129
127
  u32_t copymaxIn = 0;
130
128
  u32_t copymaxOut = 0;
131
129
  u32_t loadtotalIn = 0;
132
- u32_t loadtotalOut = 0;
133
130
  u32_t loadmaxIn = 0;
134
131
  u32_t loadmaxOut = 0;
135
132
  u32_t storetotalIn = 0;
136
- u32_t storetotalOut = 0;
137
133
  u32_t storemaxIn = 0;
138
134
  u32_t storemaxOut = 0;
139
135
 
@@ -155,7 +151,6 @@ void AndersenStat::constraintGraphStat()
155
151
  u32_t nCopyOut = nodeIt->second->getDirectOutEdges().size();
156
152
  if(nCopyOut > copymaxOut)
157
153
  copymaxOut = nCopyOut;
158
- copytotalOut +=nCopyOut;
159
154
  u32_t nLoadIn = nodeIt->second->getLoadInEdges().size();
160
155
  if(nLoadIn > loadmaxIn)
161
156
  loadmaxIn = nLoadIn;
@@ -163,7 +158,6 @@ void AndersenStat::constraintGraphStat()
163
158
  u32_t nLoadOut = nodeIt->second->getLoadOutEdges().size();
164
159
  if(nLoadOut > loadmaxOut)
165
160
  loadmaxOut = nLoadOut;
166
- loadtotalOut +=nLoadOut;
167
161
  u32_t nStoreIn = nodeIt->second->getStoreInEdges().size();
168
162
  if(nStoreIn > storemaxIn)
169
163
  storemaxIn = nStoreIn;
@@ -171,7 +165,6 @@ void AndersenStat::constraintGraphStat()
171
165
  u32_t nStoreOut = nodeIt->second->getStoreOutEdges().size();
172
166
  if(nStoreOut > storemaxOut)
173
167
  storemaxOut = nStoreOut;
174
- storetotalOut +=nStoreOut;
175
168
  u32_t nAddrIn = nodeIt->second->getAddrInEdges().size();
176
169
  if(nAddrIn > addrmaxIn)
177
170
  addrmaxIn = nAddrIn;
@@ -179,7 +172,6 @@ void AndersenStat::constraintGraphStat()
179
172
  u32_t nAddrOut = nodeIt->second->getAddrOutEdges().size();
180
173
  if(nAddrOut > addrmaxOut)
181
174
  addrmaxOut = nAddrOut;
182
- addrtotalOut +=nAddrOut;
183
175
  }
184
176
  double storeavgIn = (double)storetotalIn/cgNodeNumber;
185
177
  double loadavgIn = (double)loadtotalIn/cgNodeNumber;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svf-tools",
3
- "version": "1.0.414",
3
+ "version": "1.0.415",
4
4
  "description": "* <b>[TypeClone](https://github.com/SVF-tools/SVF/wiki/TypeClone) published in our [ECOOP paper](https://yuleisui.github.io/publications/ecoop20.pdf) is now available in SVF </b> * <b>SVF now uses a single script for its build. Just type [`source ./build.sh`](https://github.com/SVF-tools/SVF/blob/master/build.sh) in your terminal, that's it!</b> * <b>SVF now supports LLVM-10.0.0! </b> * <b>We thank [bsauce](https://github.com/bsauce) for writing a user manual of SVF ([link1](https://www.jianshu.com/p/068a08ec749c) and [link2](https://www.jianshu.com/p/777c30d4240e)) in Chinese </b> * <b>SVF now supports LLVM-9.0.0 (Thank [Byoungyoung Lee](https://github.com/SVF-tools/SVF/issues/142) for his help!). </b> * <b>SVF now supports a set of [field-sensitive pointer analyses](https://yuleisui.github.io/publications/sas2019a.pdf). </b> * <b>[Use SVF as an external lib](https://github.com/SVF-tools/SVF/wiki/Using-SVF-as-a-lib-in-your-own-tool) for your own project (Contributed by [Hongxu Chen](https://github.com/HongxuChen)). </b> * <b>SVF now supports LLVM-7.0.0. </b> * <b>SVF now supports Docker. [Try SVF in Docker](https://github.com/SVF-tools/SVF/wiki/Try-SVF-in-Docker)! </b> * <b>SVF now supports [LLVM-6.0.0](https://github.com/svf-tools/SVF/pull/38) (Contributed by [Jack Anthony](https://github.com/jackanth)). </b> * <b>SVF now supports [LLVM-4.0.0](https://github.com/svf-tools/SVF/pull/23) (Contributed by Jared Carlson. Thank [Jared](https://github.com/jcarlson23) and [Will](https://github.com/dtzWill) for their in-depth [discussions](https://github.com/svf-tools/SVF/pull/18) about updating SVF!) </b> * <b>SVF now supports analysis for C++ programs.</b> <br />",
5
5
  "main": "index.js",
6
6
  "scripts": {