331{
332
333
334
335
336
337
338
339 std::vector<const ICFGNode*> removed;
342 it != eit; ++it)
343 {
344 const ICFGNode* node = it->second;
346 continue;
347 removedNodeIndex[node] = static_cast<int>(removed.size());
348 removed.push_back(node);
349 }
350 const int removedNodeCount = static_cast<int>(removed.size());
351
352
353
354
357 it != eit; ++it)
358 {
361 continue;
365 {
367 break;
368 }
369 }
370
371
372 std::vector<std::vector<int>> removedSuccessors(removedNodeCount);
373 std::vector<std::vector<const ICFGNode*>>
374 keptSuccessors(removedNodeCount);
375 std::vector<const ICFGNode*> successors;
376 for (int nodeIndex = 0; nodeIndex < removedNodeCount; ++nodeIndex)
377 {
379 for (const ICFGNode* successor : successors)
380 {
382 keptSuccessors[nodeIndex].push_back(successor);
383 else
384 {
385 const auto found = removedNodeIndex.find(successor);
386 if (found != removedNodeIndex.end())
387 removedSuccessors[nodeIndex].push_back(found->second);
388 }
389 }
390 }
391
392
393
394 std::vector<int> discoveryIndex(removedNodeCount, -1);
395 std::vector<int> lowLink(removedNodeCount, 0);
396 std::vector<int> component(removedNodeCount, -1);
397 std::vector<char> onStack(removedNodeCount, 0);
398 std::vector<int> tarjanStack;
399 int nextDiscoveryIndex = 0;
400 int componentCount = 0;
401 for (int root = 0; root < removedNodeCount; ++root)
402 {
403 if (discoveryIndex[root] != -1)
404 continue;
405 std::vector<std::pair<int, size_t>> work;
406 work.emplace_back(root, 0);
407 while (!work.empty())
408 {
409 const int nodeIndex = work.back().first;
410 size_t& successorPosition = work.back().second;
411 if (successorPosition == 0)
412 {
413 discoveryIndex[nodeIndex] =
414 lowLink[nodeIndex] = nextDiscoveryIndex++;
415 tarjanStack.push_back(nodeIndex);
416 onStack[nodeIndex] = 1;
417 }
418 bool descend = false;
419 while (successorPosition < removedSuccessors[nodeIndex].size())
420 {
421 const int successorIndex =
422 removedSuccessors[nodeIndex][successorPosition++];
423 if (discoveryIndex[successorIndex] == -1)
424 {
425 work.emplace_back(successorIndex, 0);
426 descend = true;
427 break;
428 }
429 if (onStack[successorIndex] &&
430 discoveryIndex[successorIndex] < lowLink[nodeIndex])
431 lowLink[nodeIndex] = discoveryIndex[successorIndex];
432 }
433 if (descend)
434 continue;
435 if (lowLink[nodeIndex] == discoveryIndex[nodeIndex])
436 {
437 while (true)
438 {
439 const int componentNode = tarjanStack.back();
440 tarjanStack.pop_back();
441 onStack[componentNode] = 0;
442 component[componentNode] = componentCount;
443 if (componentNode == nodeIndex)
444 break;
445 }
446 ++componentCount;
447 }
448 work.pop_back();
449 if (!work.empty())
450 {
451 const int parentIndex = work.back().first;
452 if (lowLink[nodeIndex] < lowLink[parentIndex])
453 lowLink[parentIndex] = lowLink[nodeIndex];
454 }
455 }
456 }
457
458
459 std::vector<OrderedSet<const ICFGNode*>> baseKept(componentCount);
460 std::vector<OrderedSet<int>> componentSuccessors(componentCount);
461 for (int nodeIndex = 0; nodeIndex < removedNodeCount; ++nodeIndex)
462 {
463 const int componentIndex = component[nodeIndex];
464 for (const ICFGNode* keptSuccessor : keptSuccessors[nodeIndex])
465 baseKept[componentIndex].insert(keptSuccessor);
466 for (int successorIndex : removedSuccessors[nodeIndex])
467 if (component[successorIndex] != componentIndex)
468 componentSuccessors[componentIndex].insert(
469 component[successorIndex]);
470 }
471
472
473 std::vector<OrderedSet<const ICFGNode*>>
474 reachableKeptNodes(componentCount);
475 for (int componentIndex = 0; componentIndex < componentCount;
476 ++componentIndex)
477 {
479 reachableKeptNodes[componentIndex];
480 reachable = baseKept[componentIndex];
481 for (int successorComponent : componentSuccessors[componentIndex])
482 reachable.insert(
483 reachableKeptNodes[successorComponent].begin(),
484 reachableKeptNodes[successorComponent].end());
485 }
486
487
488
490 {
492 const auto seedReturn = seedRet.find(source);
493 for (const ICFGNode* successor : successors)
494 {
496 {
497
498
499 if (seedReturn != seedRet.end() &&
500 seedReturn->second == successor)
501 {
504 }
505 continue;
506 }
507 const auto removedIndex = removedNodeIndex.find(successor);
508 if (removedIndex == removedNodeIndex.end())
509 {
511 << "[ERROR] Local ICFG successor is neither kept nor indexed\n";
512 std::abort();
513 }
514 for (const ICFGNode* target :
515 reachableKeptNodes[component[removedIndex->second]])
516 {
519 }
520 }
521 }
522
523 size_t totalBridgedEdges = 0;
525 totalBridgedEdges += pair.second.size();
526 SVFUtil::outs() <<
"[SlicedICFGView] Built " << totalBridgedEdges
528 << " source nodes\n";
529}
const RetICFGNode * getRetICFGNode() const
Return callsite.
const GEdgeSetTy & getOutEdges() const
ICFGNodeIDToNodeMapTy::iterator iterator
static void getLocalSuccessors(const ICFGNode *node, const Map< const ICFGNode *, const ICFGNode * > &callsiteReturnNodes, std::vector< const ICFGNode * > &successors)
Set< const ICFGNode * > keptNodesSet
LLVM_NODISCARD bool isa(const Y &Val)
std::ostream & errs()
Overwrite llvm::errs().
std::ostream & outs()
Overwrite llvm::outs().
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
std::set< Key, Compare, Allocator > OrderedSet
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map