Static Value-Flow Analysis
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
SVF::SlicedMTA Class Reference

#include <MTA.h>

Classes

struct  RaceDigests
 

Public Types

using RacePair = MTA::RacePair
 The shared race detector lives in MTA; reuse its race-pair type.
 

Public Member Functions

 SlicedMTA ()
 
 ~SlicedMTA ()
 
 SlicedMTA (const SlicedMTA &)=delete
 
SlicedMTAoperator= (const SlicedMTA &)=delete
 
bool runOnModule (SVFIR *pag, AndersenWaveDiff &preAnalysis)
 Run the slicing pipeline with its prepared Andersen pre-analysis.
 

Private Member Functions

bool runPreAnalysis ()
 
bool runMTASlicingAndAnalysis ()
 
bool runPTASlicingAndAnalysis ()
 
bool runFinalRaceDetection ()
 
void buildPreAnalysisSVFG ()
 
bool runWholeProgramDetection ()
 
BVDataPTAImplgetMainPTA () const
 
std::set< const SVFStmt * > getVulnerableStmts () const
 Union of both statements of every candidate race pair (the slice targets).
 
std::set< RacePairdetectRacePairsOnSlicedGraph (const std::set< RacePair > &preAnalysisRacePairs, BVDataPTAImpl *slicedPTA, MHP *slicedMHP, LockAnalysis *slicedLockAnalysis)
 Refine the pre-analysis candidate pairs with main-phase ILA and FSAM.
 

Static Private Member Functions

static void reportOriginalStatistics (SVFIR *svfir)
 Pipeline utilities shared by the sliced and whole-program paths.
 
static std::set< const ICFGNode * > collectICFGNodes (SVFG *svfg, const NodeBS &svfgNodeIds)
 
static void reportPTASliceStatistics (const std::set< const ICFGNode * > &icfgNodes)
 
static std::string raceStatementKey (const SVFStmt *statement)
 
static void updateDigest (u64_t &digest, const std::string &value)
 
static RaceDigests computeRaceDigests (const std::set< RacePair > &pairs)
 

Private Attributes

SVFIRsvfir = nullptr
 
u32_t mainContextDepth
 
std::unique_ptr< TCTtct
 
std::unique_ptr< MHPmhp
 
std::unique_ptr< LockAnalysislockAnalysis
 
AndersenWaveDiffpreAndersen = nullptr
 
ThreadCallGraphthreadCallGraph = nullptr
 
std::unique_ptr< MTASVFGBuilderpreSVFGBuilder
 
SVFGpreSVFG = nullptr
 
std::unique_ptr< MultiStageSlicermultiStageSlicer
 
NodeBS preCandidateSolveNodeIds
 
std::unique_ptr< SingleSlicersingleSlicer
 
MTASVFGBuilder::ThreadVFCandidateList selectedThreadVFCandidates
 
std::set< const ICFGNode * > singleSlicedNodes
 
NodeBS singleSlicedSVFGNodeIds
 
std::unique_ptr< SlicedSVFIRViewmtaSlicedView
 
std::unique_ptr< SlicedSVFIRViewptaSlicedView
 
std::unique_ptr< SlicedSVFGViewslicedSVFGView
 
std::unique_ptr< FlowSensitivemainFSMPTA
 
std::unique_ptr< SlicedTCTslicedTCT
 
std::unique_ptr< MHPslicedMHP
 
std::unique_ptr< LockAnalysisslicedLockAnalysis
 
bool hasThreadFunctions = false
 
std::set< RacePairracePairs
 

Detailed Description

Multi-stage on-demand slicing race detection pipeline (MSli).

runOnModule drives five stages on a pre-built SVFIR:

  1. (caller) build SVFIR + resolve indirect calls into the PAG
  2. pre-analysis: Andersen, TCT, MHP, lock, candidate race pairs, VFG_pre
  3. MTA slicing: slice the thread-aware graph, build the sliced MHP/lock
  4. PTA slicing + main flow-sensitive FSAM (FSMPTA) on the slice
  5. final race detection on the sliced graph using FSAM points-to

It operates entirely on the SVFIR (LLVM-free). The LLVM-aware caller runs the Andersen pre-analysis and materialises its resolved indirect calls into the PAG before invoking runOnModule.

Behaviour is controlled by Options (MTFlowSensitive, MTAEnableSlicing, MTASingleStageSlicing, DumpMTAGraphs).

Definition at line 226 of file MTA.h.

Member Typedef Documentation

◆ RacePair

The shared race detector lives in MTA; reuse its race-pair type.

Definition at line 230 of file MTA.h.

Constructor & Destructor Documentation

◆ SlicedMTA() [1/2]

SlicedMTA::SlicedMTA ( )

Definition at line 581 of file MTA.cpp.

582{
583}
static Option< u32_t > MaxContextLen
Definition Options.h:81
u32_t mainContextDepth
Definition MTA.h:290

◆ ~SlicedMTA()

SlicedMTA::~SlicedMTA ( )
default

◆ SlicedMTA() [2/2]

SVF::SlicedMTA::SlicedMTA ( const SlicedMTA )
delete

Member Function Documentation

◆ buildPreAnalysisSVFG()

void SlicedMTA::buildPreAnalysisSVFG ( )
private

Definition at line 608 of file MTA.cpp.

609{
610 ScopedPhaseTimer timer("Build thread-aware VFG_pre");
611 // Treat fork/join as calls so the SVFG carries the thread-oblivious
612 // (fork/join-ordered) value flow.
613 if (ThreadCallGraph* tcg = SVFUtil::dyn_cast<ThreadCallGraph>(preAndersen->getCallGraph()))
614 {
615 tcg->updateCallGraph(preAndersen);
616 tcg->updateJoinEdge(preAndersen);
617 }
618 preSVFGBuilder = std::make_unique<MTASVFGBuilder>(
619 mhp.get(), lockAnalysis.get(),
621 // The Pre-TVF overlay is sliced, never solved: omit its interference-edge
622 // labels. Main-TVF labels are added after the pre overlay is removed.
623 preSVFG = preSVFGBuilder->buildPTROnlySVFG(preAndersen);
624 if (isMTAStatEnabled())
625 SVFUtil::outs() << "[BaseSVFG] built once: " << preSVFG->getSVFGNodeNum()
626 << " nodes; [Pre-TVF] "
627 << preSVFGBuilder->getThreadAwareEdgeCount()
628 << " interference edges\n";
629}
@ SlicingOnly
Build unlabelled connectivity for VFG_pre slicing.
CallGraph * getCallGraph() const
Return call graph.
u32_t getSVFGNodeNum() const
Return total SVFG node number.
Definition SVFG.h:271
std::unique_ptr< LockAnalysis > lockAnalysis
Definition MTA.h:293
AndersenWaveDiff * preAndersen
Definition MTA.h:297
std::unique_ptr< MTASVFGBuilder > preSVFGBuilder
Definition MTA.h:299
std::unique_ptr< MHP > mhp
Definition MTA.h:292
SVFG * preSVFG
Definition MTA.h:300
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
bool isMTAStatEnabled()
Definition MTAStat.h:46
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76

◆ collectICFGNodes()

std::set< const ICFGNode * > SlicedMTA::collectICFGNodes ( SVFG svfg,
const NodeBS svfgNodeIds 
)
staticprivate

Definition at line 470 of file MTA.cpp.

472{
473 std::set<const ICFGNode*> nodes;
474 for (NodeID id : svfgNodeIds)
475 {
476 if (!svfg->hasSVFGNode(id))
477 continue;
478 if (const StmtVFGNode* stmtNode =
479 SVFUtil::dyn_cast<StmtVFGNode>(svfg->getSVFGNode(id)))
480 if (stmtNode->getICFGNode() != nullptr)
481 nodes.insert(stmtNode->getICFGNode());
482 }
483 return nodes;
484}
bool hasSVFGNode(NodeID id) const
Whether has the SVFGNode.
Definition SVFG.h:156
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
u32_t NodeID
Definition GeneralType.h:76
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)

◆ computeRaceDigests()

SlicedMTA::RaceDigests SlicedMTA::computeRaceDigests ( const std::set< RacePair > &  pairs)
staticprivate

Definition at line 543 of file MTA.cpp.

545{
547 std::set<std::string> statementKeys;
548 for (const RacePair& pair : pairs)
549 {
550 statementToKey.emplace(pair.stmt1, std::string());
551 statementToKey.emplace(pair.stmt2, std::string());
552 }
553 for (auto& statementAndKey : statementToKey)
554 {
556 statementKeys.insert(statementAndKey.second);
557 }
558
559 RaceDigests digests{1469598103934665603ULL, 1469598103934665603ULL};
560 for (const std::string& key : statementKeys)
561 updateDigest(digests.alarm, key);
562
563 std::set<std::pair<std::string, std::string>> pairKeys;
564 for (const RacePair& pair : pairs)
565 {
566 std::string first = statementToKey.at(pair.stmt1);
567 std::string second = statementToKey.at(pair.stmt2);
568 if (second < first)
569 std::swap(first, second);
570 pairKeys.emplace(std::move(first), std::move(second));
571 }
572
573 for (const auto& pair : pairKeys)
574 {
575 updateDigest(digests.pair, pair.first);
576 updateDigest(digests.pair, pair.second);
577 }
578 return digests;
579}
MTA::RacePair RacePair
The shared race detector lives in MTA; reuse its race-pair type.
Definition MTA.h:230
static std::string raceStatementKey(const SVFStmt *statement)
Definition MTA.cpp:504
static void updateDigest(u64_t &digest, const std::string &value)
Definition MTA.cpp:532

◆ detectRacePairsOnSlicedGraph()

std::set< SlicedMTA::RacePair > SlicedMTA::detectRacePairsOnSlicedGraph ( const std::set< RacePair > &  preAnalysisRacePairs,
BVDataPTAImpl slicedPTA,
MHP slicedMHP,
LockAnalysis slicedLockAnalysis 
)
private

Refine the pre-analysis candidate pairs with main-phase ILA and FSAM.

Definition at line 1345 of file MTA.cpp.

1350{
1351
1352 std::set<RacePair> filteredRacePairs;
1353
1354 // MSli's main phase refines the alarms produced by the conservative
1355 // pre-analysis. Main ILA and FSMPTA are recomputed independently on their
1356 // slices; only the candidate universe comes from pre-analysis.
1357 for (const RacePair& pair : preAnalysisRacePairs)
1358 {
1359 const ICFGNode* node1 = pair.stmt1->getICFGNode();
1360 const ICFGNode* node2 = pair.stmt2->getICFGNode();
1361
1362 if (!slicedMHP->mayHappenInParallelCache(node1, node2))
1363 continue;
1364
1365 if (slicedLockAnalysis->isProtectedByCommonLock(node1, node2))
1366 continue;
1367
1369 if (const LoadStmt* ldStmt1 =
1370 SVFUtil::dyn_cast<LoadStmt>(pair.stmt1))
1371 {
1372 pts1 = slicedPTA->getPts(ldStmt1->getRHSVarID());
1373 }
1374 else if (const StoreStmt* stStmt1 =
1375 SVFUtil::dyn_cast<StoreStmt>(pair.stmt1))
1376 {
1377 pts1 = slicedPTA->getPts(stStmt1->getLHSVarID());
1378 }
1379 else
1380 {
1381 continue;
1382 }
1383
1384 if (const LoadStmt* ldStmt2 =
1385 SVFUtil::dyn_cast<LoadStmt>(pair.stmt2))
1386 {
1387 pts2 = slicedPTA->getPts(ldStmt2->getRHSVarID());
1388 }
1389 else if (const StoreStmt* stStmt2 =
1390 SVFUtil::dyn_cast<StoreStmt>(pair.stmt2))
1391 {
1392 pts2 = slicedPTA->getPts(stStmt2->getLHSVarID());
1393 }
1394 else
1395 {
1396 continue;
1397 }
1398
1399 // Check if points-to sets still intersect
1400 if (pts1.intersects(pts2))
1401 filteredRacePairs.insert(pair);
1402 }
1403
1404 return filteredRacePairs;
1405}
std::unique_ptr< LockAnalysis > slicedLockAnalysis
Definition MTA.h:318
std::unique_ptr< MHP > slicedMHP
Definition MTA.h:317

◆ getMainPTA()

BVDataPTAImpl * SlicedMTA::getMainPTA ( ) const
private

Main pointer-analysis instance feeding final race detection (the flow-sensitive FSAM, a BVDataPTAImpl queried polymorphically).

Definition at line 587 of file MTA.cpp.

588{
589 // The main FSMPTA phase is the flow-sensitive FSAM (FSMPTA), a
590 // BVDataPTAImpl, so the downstream race detector queries it polymorphically.
591 return mainFSMPTA.get();
592}
std::unique_ptr< FlowSensitive > mainFSMPTA
Definition MTA.h:315

◆ getVulnerableStmts()

std::set< const SVFStmt * > SlicedMTA::getVulnerableStmts ( ) const
private

Union of both statements of every candidate race pair (the slice targets).

Definition at line 594 of file MTA.cpp.

595{
596 std::set<const SVFStmt*> vulnerableStatements;
597 for (const RacePair& pair : racePairs)
598 {
599 vulnerableStatements.insert(pair.stmt1);
600 vulnerableStatements.insert(pair.stmt2);
601 }
603}
std::set< RacePair > racePairs
Definition MTA.h:320

◆ operator=()

SlicedMTA & SVF::SlicedMTA::operator= ( const SlicedMTA )
delete

◆ raceStatementKey()

std::string SlicedMTA::raceStatementKey ( const SVFStmt statement)
staticprivate

Definition at line 504 of file MTA.cpp.

505{
506 std::string key;
507 const ICFGNode* node = statement->getICFGNode();
508 const FunObjVar* function = node == nullptr ? nullptr : node->getFun();
509 const SVFBasicBlock* block = statement->getBB();
510 const SVFVar* value = statement->getValue();
511
512 const std::string fields[] =
513 {
514 std::to_string(statement->getEdgeKind()),
515 function == nullptr ? std::string() : function->getName(),
516 block == nullptr ? std::string() : block->getName(),
517 node == nullptr ? std::string() : node->getSourceLoc(),
518 value == nullptr ? std::string() : value->getName(),
519 value == nullptr ? std::string() : value->getSourceLoc(),
520 value != nullptr && value->hasLLVMValue()
521 ? value->valueOnlyToString() : std::string()
522 };
523 for (const std::string& field : fields)
524 {
525 key += std::to_string(field.size());
526 key += ':';
527 key += field;
528 }
529 return key;
530}
const char *const string
Definition cJSON.h:172
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
Definition ICFGNode.h:75
const std::string getSourceLoc(const Value *val)
Definition LLVMUtil.cpp:454

◆ reportOriginalStatistics()

void SlicedMTA::reportOriginalStatistics ( SVFIR svfir)
staticprivate

Pipeline utilities shared by the sliced and whole-program paths.

Definition at line 445 of file MTA.cpp.

446{
447 size_t icfgNodeCount = 0;
448 for (ICFG::iterator it = svfir->getICFG()->begin(), eit = svfir->getICFG()->end(); it != eit; ++it)
450
451 size_t functionCount = 0;
452 for (auto it = svfir->getCallGraph()->begin(), eit = svfir->getCallGraph()->end(); it != eit; ++it)
454
455 size_t pagStmtCount = 0;
456 for (ICFG::iterator it = svfir->getICFG()->begin(),
457 eit = svfir->getICFG()->end(); it != eit; ++it)
458 {
459 const ICFGNode* node = it->second;
460 if (svfir->hasSVFStmtList(node))
461 pagStmtCount += svfir->getSVFStmtList(node).size();
462 }
463
464 SVFUtil::outs() << "\n[Original SVFIR] Statistics:\n";
465 SVFUtil::outs() << " ICFG nodes: " << icfgNodeCount << "\n";
466 SVFUtil::outs() << " Functions: " << functionCount << "\n";
467 SVFUtil::outs() << " PAG statements: " << pagStmtCount << "\n";
468}
iterator begin()
Iterators.
ICFGNodeIDToNodeMapTy::iterator iterator
Definition ICFG.h:58
SVFStmtList & getSVFStmtList(const ICFGNode *inst)
Given an instruction, get all its PAGEdges.
Definition SVFIR.h:318
bool hasSVFStmtList(const ICFGNode *inst) const
Whether this instruction has SVFIR Edge.
Definition SVFIR.h:308
const CallGraph * getCallGraph()
Get CG.
Definition SVFIR.h:248
ICFG * getICFG() const
Definition SVFIR.h:231
SVFIR * svfir
Definition MTA.h:287

◆ reportPTASliceStatistics()

void SlicedMTA::reportPTASliceStatistics ( const std::set< const ICFGNode * > &  icfgNodes)
staticprivate

Definition at line 486 of file MTA.cpp.

488{
489 std::set<const FunObjVar*> functions;
490 std::set<const SVFStmt*> statements;
491 for (const ICFGNode* node : icfgNodes)
492 {
493 if (node->getFun() != nullptr)
494 functions.insert(node->getFun());
495 statements.insert(node->getSVFStmts().begin(), node->getSVFStmts().end());
496 }
497
498 SVFUtil::outs() << "[PTA Sliced] Statistics:\n";
499 SVFUtil::outs() << " ICFG nodes: " << icfgNodes.size() << "\n";
500 SVFUtil::outs() << " Functions: " << functions.size() << "\n";
501 SVFUtil::outs() << " PAG statements: " << statements.size() << "\n";
502}

◆ runFinalRaceDetection()

bool SlicedMTA::runFinalRaceDetection ( )
private

Definition at line 1087 of file MTA.cpp.

1088{
1089 SVFUtil::outs() << "\n=== Final Race Detection ===\n";
1090
1091 if (!hasThreadFunctions)
1092 {
1093 SVFUtil::outs() << "[SKIP] No thread functions found\n";
1094 return true;
1095 }
1096 if (racePairs.empty())
1097 {
1098 SVFUtil::outs() << "\n=== Race Detection Summary ===\n";
1099 SVFUtil::outs() << "Race pairs (pre-analysis): 0\n";
1100 SVFUtil::outs() << "Race pairs (sliced graph): 0\n";
1101 SVFUtil::outs() << "Race statements (sliced graph): 0\n";
1102 if (isMTAStatEnabled())
1103 {
1104 const RaceDigests digests = computeRaceDigests(racePairs);
1105 SVFUtil::outs() << "[MSLI-RQ] mode=MSli alarms=0 pairs=0"
1106 << " alarm-digest=" << digests.alarm
1107 << " pair-digest=" << digests.pair << "\n";
1108 }
1109 SVFUtil::outs() << "\nNo race pairs detected in sliced graph.\n";
1110 return true;
1111 }
1112 if (mtaSlicedView == nullptr)
1113 {
1114 SVFUtil::errs() << "[ERROR] MTA sliced view not available\n";
1115 return false;
1116 }
1117 if (slicedMHP == nullptr || slicedLockAnalysis == nullptr)
1118 {
1119 SVFUtil::errs() << "[ERROR] Sliced MHP or LockAnalysis not available\n";
1120 return false;
1121 }
1122 if (getMainPTA() == nullptr)
1123 {
1124 SVFUtil::errs() << "[ERROR] Main flow-sensitive pointer analysis not available\n";
1125 return false;
1126 }
1127
1128 std::set<RacePair> detectedPairs;
1129 {
1130 ScopedPhaseTimer timer("Final Race Detection");
1132 racePairs, // Refine only pre-analysis candidates
1133 getMainPTA(), // Use flow-sensitive FSAM points-to
1134 slicedMHP.get(), slicedLockAnalysis.get());
1135 }
1136
1137 // Distinct racy statements (the endpoints of the race pairs) -- a stabler,
1138 // smaller-to-report metric than the pair count.
1139 std::set<const SVFStmt*> racyStmts;
1140 for (const RacePair& pair : detectedPairs)
1141 {
1142 racyStmts.insert(pair.stmt1);
1143 racyStmts.insert(pair.stmt2);
1144 }
1145
1146 SVFUtil::outs() << "\n=== Race Detection Summary ===\n";
1147 SVFUtil::outs() << "Race pairs (pre-analysis): " << racePairs.size() << "\n";
1148 SVFUtil::outs() << "Race pairs (sliced graph): " << detectedPairs.size() << "\n";
1149 SVFUtil::outs() << "Race statements (sliced graph): " << racyStmts.size() << "\n";
1150 // Machine-readable line for the artifact's `msli` table generator: the race
1151 // statements reported after slicing (the preservation metric).
1152 if (isMTAStatEnabled())
1153 {
1154 const RaceDigests digests = computeRaceDigests(detectedPairs);
1155 SVFUtil::outs() << "[MSLI-RQ] mode=MSli alarms=" << racyStmts.size()
1156 << " pairs=" << detectedPairs.size()
1157 << " alarm-digest=" << digests.alarm
1158 << " pair-digest=" << digests.pair << "\n";
1159 }
1160
1161 if (!detectedPairs.empty())
1162 {
1163 SVFUtil::outs() << "\n=== Bug Report ===\n";
1164 SVFUtil::outs() << "Found " << detectedPairs.size() << " race pair(s) in sliced graph\n";
1165 }
1166 else
1167 {
1168 SVFUtil::outs() << "\nNo race pairs detected in sliced graph.\n";
1169 }
1170
1171 return true;
1172}
static RaceDigests computeRaceDigests(const std::set< RacePair > &pairs)
Definition MTA.cpp:543
bool hasThreadFunctions
Definition MTA.h:319
std::unique_ptr< SlicedSVFIRView > mtaSlicedView
Definition MTA.h:312
std::set< RacePair > detectRacePairsOnSlicedGraph(const std::set< RacePair > &preAnalysisRacePairs, BVDataPTAImpl *slicedPTA, MHP *slicedMHP, LockAnalysis *slicedLockAnalysis)
Refine the pre-analysis candidate pairs with main-phase ILA and FSAM.
Definition MTA.cpp:1345
BVDataPTAImpl * getMainPTA() const
Definition MTA.cpp:587
std::ostream & errs()
Overwrite llvm::errs()
Definition SVFUtil.h:58

◆ runMTASlicingAndAnalysis()

bool SlicedMTA::runMTASlicingAndAnalysis ( )
private

Definition at line 738 of file MTA.cpp.

739{
740 SVFUtil::outs() << "\n=== MTA Slicing and Analysis ===\n";
741
742 if (racePairs.empty())
743 {
744 SVFUtil::outs() << "[SKIP] No race pairs found in pre-analysis\n";
745 return true;
746 }
747
748 const bool dumpDot = Options::DumpMTAGraphs();
749
750 // Step 1: Get vulnerable statements from race pairs
751 std::set<const SVFStmt*> vulnerableStatements = getVulnerableStmts();
752
753 std::set<const ICFGNode*> mtaSlicedNodes;
754
756 {
757 // Single-pass baseline (MSli §3/§5.4): one unified slice (V_Single)
758 // combining synchronization + data + call dependence, shared by both the
759 // ILA and the FSPTA stages. Computed once here; reused in PTA slicing.
760 SVFUtil::outs() << "[Slicing Mode] Single unified slice (V_Single) for ILA + FSPTA\n";
761 singleSlicer = std::make_unique<SingleSlicer>(
762 svfir, preAndersen, mhp.get(), lockAnalysis.get(),
763 preSVFG /* data dependence over the thread-aware VFG_pre */);
764 {
765 ScopedPhaseTimer timer("Unified Slicing");
768 singleSlicedNodes = std::move(singleSlice.icfgNodes);
770 }
772 if (isMTAStatEnabled())
773 SVFUtil::outs() << "Unified sliced to " << mtaSlicedNodes.size()
774 << " nodes\n";
775 }
776 else
777 {
778 SVFUtil::outs() << "[Slicing Mode] Differential slices (separate ILA + FSPTA)\n";
779 multiStageSlicer = std::make_unique<MultiStageSlicer>(
780 svfir, preAndersen, mhp.get(), lockAnalysis.get(), preSVFG);
781
782 // ILA slicing sources = [INIT] race statements + [THREAD-VF] sources. Keep
783 // a candidate edge's query (see MTASVFGBuilder::getThreadVFQueryMap) only if
784 // both endpoints survive the FSPTA slice -- i.e. the edge is in
785 // ThreadVF(VFG'_pre). Closure computed here (pre<->pre) and reused by PTA slicing.
786 std::set<const ICFGNode*> threadVFSources;
788 {
789 ScopedPhaseTimer timer("Select THREAD-VF slicing sources");
790 if (preSVFGBuilder)
791 {
792 multiStageSlicer->computePreCandidateSlice(vulnerableStatements);
794 multiStageSlicer->getPreCandidateSlice();
797 preSVFG, preAndersen, preCandidate.nodeIds());
799 !preCandidate.svfgNodes.empty())
800 {
801 SVFUtil::errs() << "[ERROR] Failed to execution-close VFG'_pre\n";
802 return false;
803 }
804 if (isMTAStatEnabled())
806 << "[VFG'_pre] " << preCandidate.svfgNodes.size()
807 << " dependency nodes, "
809 << " execution-closure nodes\n";
810
811 // The query map can be large; use node-ID membership rather than
812 // two ordered-set lookups for every candidate edge.
813 for (const auto& entry : preSVFGBuilder->getThreadVFQueryMap())
814 {
815 const MTASVFGBuilder::ThreadVFEdge& edge = entry.first;
816 if (preCandidateSolveNodeIds.test(edge.first->getId()) &&
817 preCandidateSolveNodeIds.test(edge.second->getId()))
818 {
819 selectedThreadVFCandidates.emplace_back(
820 edge.first->getId(), edge.second->getId());
821 // The query value holds only the lock-span witnesses; the
822 // endpoints are implicit in the edge key.
823 threadVFSources.insert(edge.first->getICFGNode());
824 threadVFSources.insert(edge.second->getICFGNode());
825 threadVFSources.insert(entry.second.begin(), entry.second.end());
826 }
827 }
828 }
829 }
830 std::sort(selectedThreadVFCandidates.begin(),
833 std::unique(selectedThreadVFCandidates.begin(),
836 {
837 ScopedPhaseTimer timer("MTA Slicing");
839 }
840 if (isMTAStatEnabled())
841 SVFUtil::outs() << "MTA sliced to " << mtaSlicedNodes.size()
842 << " nodes\n";
843 } // end differential MTA slice
844
845 // Step 4: Build MTA SlicedSVFIRView (using pre-analysis pointer analysis)
846 {
847 ScopedPhaseTimer timer("Build MTA Sliced View");
848 mtaSlicedView = std::make_unique<SlicedSVFIRView>(
851 }
852 if (isMTAStatEnabled())
853 mtaSlicedView->dumpStats("MTA Sliced");
854
856
857 if (dumpDot)
858 {
859 SVFUtil::outs() << "\n[Dump] MTA Sliced views:\n";
860 slicedView->getICFG()->dump("sliced_icfg");
861 if (slicedView->getThreadCallGraph() != nullptr)
862 slicedView->getThreadCallGraph()->dump("sliced_tcg");
863 slicedView->getPAG()->dump("sliced_pag");
864 }
865
866 // Step 5: Build Sliced TCT (using pre-analysis pointer analysis)
867 {
868 ScopedPhaseTimer timer("Sliced Thread Create Tree");
869 if (isMTAStatEnabled())
870 SVFUtil::outs() << "[SlicedTCT] Using max context length: "
871 << mainContextDepth << " (from -max-cxt)\n";
872 // Reuse the shared pre-analysis (Andersen) for the sliced TCT.
875 if (dumpDot)
876 slicedTCT->dump("sliced_tct");
877 }
878
879 // Step 6: Sliced MHP and Lock Analysis
880 {
881 ScopedPhaseTimer ilaTimer("Sliced Interleaving and Lock Analysis");
882 {
883 ScopedPhaseTimer timer("Sliced ILA: construct MHP/ForkJoin");
885 slicedTCT.get(), slicedView->getICFG(),
886 slicedView->getThreadCallGraph(),
888 }
889 {
890 ScopedPhaseTimer timer("Sliced ILA: MHP propagation");
891 slicedMHP->analyze(slicedView->getICFG(), slicedView->getThreadCallGraph());
892 }
893 {
894 ScopedPhaseTimer timer("Sliced ILA: Lock analysis");
895 slicedLockAnalysis = std::make_unique<LockAnalysis>(slicedTCT.get());
896 slicedLockAnalysis->analyze(slicedView->getICFG(), slicedView->getThreadCallGraph());
897 }
898 }
899
900 return true;
901}
static NodeBS buildExecutionDependencyClosure(SVFG *graph, AndersenBase *preAnalysis, NodeBS dependencyNodes)
Definition FSMPTA.cpp:121
static std::unique_ptr< MHP > create(TCT *t, ICFGGraph icfg, CGGraph cg, StateRepresentation representation=StateRepresentation::MaterializedContexts)
Construct MHP and initialize its graph-dependent ForkJoinAnalysis.
Definition MHP.h:646
std::pair< const StmtSVFGNode *, const StmtSVFGNode * > ThreadVFEdge
static const Option< bool > DumpMTAGraphs
MTA: dump the pointer-analysis and thread call graphs (ptacg/tcg.dot), Default: false.
Definition Options.h:258
static const Option< bool > MTASingleStageSlicing
MTA slicing: one unified slice for ILA + FSPTA (single-pass baseline), Default: false.
Definition Options.h:263
void dump(const std::string &filename) const
Dump sliced ICFG to dot file.
NodeBS preCandidateSolveNodeIds
Definition MTA.h:302
MTASVFGBuilder::ThreadVFCandidateList selectedThreadVFCandidates
Definition MTA.h:307
std::set< const SVFStmt * > getVulnerableStmts() const
Union of both statements of every candidate race pair (the slice targets).
Definition MTA.cpp:594
ThreadCallGraph * threadCallGraph
Definition MTA.h:298
std::unique_ptr< MultiStageSlicer > multiStageSlicer
Definition MTA.h:301
std::set< const ICFGNode * > singleSlicedNodes
Definition MTA.h:310
std::unique_ptr< SingleSlicer > singleSlicer
Definition MTA.h:303
NodeBS singleSlicedSVFGNodeIds
Definition MTA.h:311
std::unique_ptr< SlicedTCT > slicedTCT
Definition MTA.h:316
const SlicedICFGView * getICFG() const
Get SlicedICFGView.
static std::unique_ptr< SlicedTCT > create(PointerAnalysis &pointerAnalysis, const SlicedSVFIRView &slicedView, u32_t contextLimit)
Definition MTASlicer.cpp:56
bool test(unsigned Idx) const
unsigned count() const

◆ runOnModule()

bool SlicedMTA::runOnModule ( SVFIR pag,
AndersenWaveDiff preAnalysis 
)

Run the slicing pipeline with its prepared Andersen pre-analysis.

Definition at line 1276 of file MTA.cpp.

1277{
1278 if (svfir != nullptr || pag == nullptr || preAnalysis.getPAG() != pag)
1279 {
1280 SVFUtil::errs() << "[ERROR] SlicedMTA is single-use and requires a "
1281 << "matching SVFIR and Andersen pre-analysis\n";
1282 return false;
1283 }
1284 svfir = pag;
1285 preAndersen = &preAnalysis;
1286
1287 SVFUtil::outs() << "[Config] Slicing: "
1288 << (Options::MTAEnableSlicing() ? "enabled" : "disabled")
1289 << "\n";
1290
1291 if (isMTAStatEnabled())
1293
1294 // The pre-analysis is context-insensitive in BOTH modes (the sliced run and
1295 // the FSAM baseline must share an identical pre-analysis substrate); the
1296 // main phase then runs at the configured context depth.
1297 // TCT context bounds are explicit constructor inputs; no process-global
1298 // option is mutated while the pipeline is running.
1299 const bool preOk = runPreAnalysis();
1300 if (!preOk)
1301 return false;
1302
1304 {
1305 if (!runMTASlicingAndAnalysis()) return false;
1306 if (!runPTASlicingAndAnalysis()) return false;
1307 if (!runFinalRaceDetection()) return false;
1308 }
1309 else
1310 {
1311 if (!runWholeProgramDetection()) return false;
1312 }
1313
1314 SVFUtil::outs() << "\n=== Analysis Complete ===\n";
1315 return true;
1316}
static const Option< bool > MTAEnableSlicing
MTA slicing: slice before the FSAM main analysis (false = whole-program baseline),...
Definition Options.h:261
SVFIR * getPAG() const
bool runWholeProgramDetection()
Definition MTA.cpp:1177
bool runPreAnalysis()
Definition MTA.cpp:631
bool runPTASlicingAndAnalysis()
Definition MTA.cpp:904
bool runFinalRaceDetection()
Definition MTA.cpp:1087
bool runMTASlicingAndAnalysis()
Definition MTA.cpp:738
static void reportOriginalStatistics(SVFIR *svfir)
Pipeline utilities shared by the sliced and whole-program paths.
Definition MTA.cpp:445

◆ runPreAnalysis()

bool SlicedMTA::runPreAnalysis ( )
private

Definition at line 631 of file MTA.cpp.

632{
633 SVFUtil::outs() << "\n=== Pre-Analysis ===\n";
634
635 const bool dumpDot = Options::DumpMTAGraphs();
636
637 // The LLVM-aware tool has already run Andersen and materialised its resolved
638 // indirect calls into the PAG. Reuse that same analysis throughout MSli.
640 SVFUtil::dyn_cast<ThreadCallGraph>(preAndersen->getCallGraph());
641 if (threadCallGraph == nullptr)
642 {
643 SVFUtil::errs() << "[ERROR] Thread call graph failed\n";
644 return false;
645 }
646
647 // Step 2: Build the context-insensitive pre-analysis Thread Creation Tree.
648 {
649 ScopedPhaseTimer timer("Create Thread Create Tree");
651 }
652 if (dumpDot)
653 tct->dump("original_tct");
654
655 // A thread with several instances at the main depth must be multiforked in
656 // this depth-0 TCT, or the pre-analysis under-approximates the main phase.
657 {
658 ScopedPhaseTimer timer("Mark truncation-merged multiforked threads");
659 std::unique_ptr<TCT> deepTct =
661
662 // >1 instance at the main depth, or a single instance that is itself
663 // multiforked (merged just beyond the main depth), marks the fork site.
665 for (const auto& deepPair : *deepTct)
666 if (const ICFGNode* forkSite = deepPair.second->getCxtThread().getThread())
667 {
669 if (deepPair.second->isMultiforked())
671 }
672
673 for (const auto& prePair : *tct)
674 {
675 const ICFGNode* forkSite = prePair.second->getCxtThread().getThread();
676 if (forkSite == nullptr)
677 continue;
679 if (fIt != forkSiteInstances.end() && fIt->second > 1)
680 prePair.second->setMultiforked(true);
681 }
682 }
683
684 // Step 3: Interleaving and Lock Analysis
685 {
686 ScopedPhaseTimer ilaTimer("Run Interleaving and Lock Analysis");
687 {
688 ScopedPhaseTimer timer("ILA: construct MHP/ForkJoin");
690 tct.get(), svfir->getICFG(),
691 const_cast<CallGraph*>(svfir->getCallGraph()));
692 }
693 {
694 ScopedPhaseTimer timer("ILA: MHP propagation");
695 mhp->analyze(svfir->getICFG(), const_cast<CallGraph*>(svfir->getCallGraph()));
696 }
697 {
698 ScopedPhaseTimer timer("ILA: Lock analysis");
699 lockAnalysis = std::make_unique<LockAnalysis>(tct.get());
700 lockAnalysis->analyze(svfir->getICFG(), const_cast<CallGraph*>(svfir->getCallGraph()));
701 }
702 }
703
704 // Step 4: Detect thread functions
705 {
706 ScopedPhaseTimer timer("Detect Thread Functions");
708 }
710 {
711 SVFUtil::outs() << "[WARNING] No thread functions found\n";
712 return true; // Not an error, just no threads to analyze
713 }
714
715 // Step 5: Detect race statements
716 std::set<const SVFStmt*> vulnerableStatements;
717 {
718 ScopedPhaseTimer timer("Detect Race Statements");
719 // Shared equivalence-class detector (the same one MTA::reportRaces uses).
721 svfir, preAndersen, mhp.get(), lockAnalysis.get(),
723 }
724 SVFUtil::outs() << "Found " << vulnerableStatements.size() << " vulnerable statements\n";
725 SVFUtil::outs() << "Found " << racePairs.size() << " race pairs\n";
726
727 // Step 6: build the thread-aware VFG only when a downstream slice/solve
728 // exists. No-race programs end after the pre-detector.
729 if (!racePairs.empty())
731 else
732 SVFUtil::outs() << "[SKIP] No race candidates; VFG_pre is unnecessary\n";
733
734 return true;
735}
if(prebuffer< 0)
Definition cJSON.cpp:1269
static std::set< const SVFStmt * > detectRace(SVFIR *svfir, AndersenBase *pta, MHP *mhp, LockAnalysis *lockAnalysis, CallGraph *callGraph, std::set< RacePair > &outRacePairs)
Definition MTA.cpp:372
static bool hasThreadFunctions(CallGraph *callGraph)
Definition MTA.cpp:1326
void buildPreAnalysisSVFG()
Definition MTA.cpp:608
std::unique_ptr< TCT > tct
Definition MTA.h:291
static std::unique_ptr< TCT > create(PointerAnalysis *p)
Construct and build a TCT with the command-line context bound.
Definition TCT.cpp:41
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition GeneralType.h:56

◆ runPTASlicingAndAnalysis()

bool SlicedMTA::runPTASlicingAndAnalysis ( )
private

Definition at line 904 of file MTA.cpp.

905{
906 SVFUtil::outs() << "\n=== PTA Slicing and Sliced Pointer Analysis ===\n";
907
909 {
910 SVFUtil::outs() << "[SKIP] No thread functions found in pre-analysis, skipping PTA slicing\n";
911 return true;
912 }
913 if (racePairs.empty())
914 {
915 SVFUtil::outs() << "[SKIP] No race pairs found in pre-analysis, skipping PTA slicing\n";
916 return true;
917 }
918
919 const bool dumpDot = Options::DumpMTAGraphs();
920
921 std::set<const SVFStmt*> vulnerableStatements = getVulnerableStmts();
922
923 std::set<const ICFGNode*> ptaSlicedNodes;
925
926 if (slicedMHP == nullptr || slicedLockAnalysis == nullptr ||
927 preSVFGBuilder == nullptr || preSVFG == nullptr)
928 {
929 SVFUtil::outs() << "[Main FSMPTA] Base SVFG or sliced ILA unavailable\n";
930 return false;
931 }
932
934 {
935 // Single-pass baseline: reuse the unified V_Single computed in MTA slicing
936 // (no separate data-dependence slice); FSPTA runs on the same slice as ILA.
937 SVFUtil::outs() << "[Slicing Mode] Reusing unified slice (V_Single) for FSPTA\n";
943 {
944 SVFUtil::errs() << "[ERROR] Single-slice FSMPTA execution closure failed\n";
945 return false;
946 }
948 if (isMTAStatEnabled())
949 SVFUtil::outs() << "PTA reuses unified slice: "
950 << ptaSlicedNodes.size() << " ICFG nodes, "
951 << finalSVFGNodeIds.count()
952 << " execution-closure SVFG nodes\n";
953
955
958 mainScope);
959 {
960 ScopedPhaseTimer timer("Replace Pre-TVF with Main-TVF overlay");
961 preSVFGBuilder->replaceThreadAwareOverlay(
963 }
964 }
965 else
966 {
967 SVFUtil::outs() << "Using " << vulnerableStatements.size() << " vulnerable statements from pre-analysis\n";
968 SVFUtil::outs() << "Using " << racePairs.size() << " race pairs from pre-analysis\n";
969
970 // Differential stage 1 always constructs this slicer and its conservative
971 // pre-candidate closure before stage 2 starts.
972 if (multiStageSlicer == nullptr)
973 {
974 SVFUtil::errs() << "[ERROR] Differential PTA slicing requires the ILA slicer\n";
975 return false;
976 }
977
979 multiStageSlicer->getPreCandidateSlice();
980 if (preCandidateSolveNodeIds.empty() && !preCandidate.svfgNodes.empty())
981 {
982 SVFUtil::errs() << "[ERROR] Execution-closed VFG'_pre is unavailable\n";
983 return false;
984 }
987
988 // The base SVFG is stable. Replace only the pre-analysis TVF overlay
989 // with edges derived from the context-sensitive sliced main ILA.
993 {
994 ScopedPhaseTimer timer("Replace Pre-TVF with Main-TVF overlay");
995 preSVFGBuilder->replaceThreadAwareOverlay(
997 }
998 if (isMTAStatEnabled())
999 SVFUtil::outs() << "[Main-TVF] "
1000 << preSVFGBuilder->getThreadAwareEdgeCount()
1001 << " interference edges over VFG'_pre\n";
1002
1004 {
1005 ScopedPhaseTimer timer("PTA Slicing over refined main VFG");
1007 }
1008 ptaSlicedNodes = finalSlice.icfgNodes;
1009 finalSVFGNodeIds = finalSlice.nodeIds();
1010
1013 if (!outsideCandidate.empty())
1014 {
1015 SVFUtil::errs() << "[ERROR] Initial FSPTA slice escapes VFG'_pre by "
1016 << outsideCandidate.count() << " SVFG nodes\n";
1017 return false;
1018 }
1019
1020 {
1021 ScopedPhaseTimer timer("Build FSMPTA execution dependency closure");
1025 }
1026
1028 outsideCandidate.intersectWithComplement(preCandidateIds);
1029 if (!outsideCandidate.empty())
1030 {
1031 SVFUtil::errs() << "[ERROR] FSMPTA execution closure escapes VFG'_pre by "
1032 << outsideCandidate.count() << " SVFG nodes\n";
1033 return false;
1034 }
1035
1036 // Report the exact execution-closed solve set, rather than the smaller
1037 // pre-closure dependency seed shown by the old implementation.
1039
1040 if (isMTAStatEnabled())
1041 {
1042 SVFUtil::outs() << "[FSPTA Slice] " << finalSlice.svfgNodes.size()
1043 << " / " << preCandidate.svfgNodes.size() << " / "
1044 << preCandidateIds.count()
1045 << " SVFG nodes (final / pre-candidate / execution-closed), "
1046 << finalSVFGNodeIds.count()
1047 << " execution-closure solve nodes\n";
1048 SVFUtil::outs() << "PTA sliced to " << ptaSlicedNodes.size()
1049 << " nodes\n";
1050 }
1051 }
1052
1053 if (isMTAStatEnabled())
1055
1056 // Slicers are no longer needed. The builder and its one stable base SVFG
1057 // remain alive because FSMPTA solves that graph directly.
1058 multiStageSlicer.reset();
1059 singleSlicer.reset();
1060
1061 // Step 5: solve the exact final slice on the stable base SVFG plus Main-TVF.
1062 SVFUtil::outs() << "[Main FSMPTA] Reusing BaseSVFG; Main-TVF comes from the sliced main ILA\n";
1064 {
1065 SVFUtil::errs() << "[ERROR] Unsupported FSMPTA mapping/clustering configuration\n";
1066 return false;
1067 }
1068 {
1069 ScopedPhaseTimer timer("Flow-Sensitive FSAM Analysis");
1070 slicedSVFGView = std::make_unique<SlicedSVFGView>(
1072 auto solver = std::make_unique<FSMPTA<const SlicedSVFGView*>>(
1074 solver->analyze();
1075 if (dumpDot)
1076 {
1077 solver->getSVFG()->dump("mta_svfg");
1078 slicedSVFGView->dump("sliced_svfg");
1079 }
1080 mainFSMPTA = std::move(solver);
1081 }
1082
1083 return true;
1084}
static ThreadVFBuildConfig mainPhase(const SlicedSVFGView &scope, const ThreadVFCandidateList *candidates=nullptr)
static std::set< const ICFGNode * > collectICFGNodes(SVFG *svfg, const NodeBS &svfgNodeIds)
Definition MTA.cpp:470
static void reportPTASliceStatistics(const std::set< const ICFGNode * > &icfgNodes)
Definition MTA.cpp:486
std::unique_ptr< SlicedSVFGView > slicedSVFGView
Definition MTA.h:314
bool intersectWithComplement(const SparseBitVector &RHS)

◆ runWholeProgramDetection()

bool SlicedMTA::runWholeProgramDetection ( )
private

No-slice A/B baseline: run the FSAM detection on the whole program (no slicing), so its time and race set can be compared against the sliced run.

Definition at line 1177 of file MTA.cpp.

1178{
1179 SVFUtil::outs() << "\n=== Whole-program FSAM Race Detection (no slicing) ===\n";
1180 if (!hasThreadFunctions || racePairs.empty())
1181 {
1182 SVFUtil::outs() << "[SKIP] No thread functions / race pairs in pre-analysis\n";
1183 return true;
1184 }
1185
1186 // SlicedTCT currently consumes the sliced-view representation even for the
1187 // full baseline. Time that construction explicitly so the A/B phase table
1188 // accounts for it instead of leaving it in unattributed wall time.
1189 {
1190 ScopedPhaseTimer timer("Build Whole-program View");
1191 std::set<const ICFGNode*> allNodes;
1192 for (ICFG::iterator it = svfir->getICFG()->begin(),
1193 eit = svfir->getICFG()->end(); it != eit; ++it)
1194 allNodes.insert(it->second);
1195 ptaSlicedView = std::make_unique<SlicedSVFIRView>(
1197 }
1198
1199 {
1200 ScopedPhaseTimer timer("Whole-program TCT/MHP/Lock");
1201 {
1202 ScopedPhaseTimer phaseTimer("Whole-program Thread Create Tree");
1205 }
1207 {
1209 "Whole-program ILA: construct MHP/ForkJoin");
1213 }
1214 {
1215 ScopedPhaseTimer phaseTimer("Whole-program ILA: MHP propagation");
1216 slicedMHP->analyze(svfir->getICFG(), fullCallGraph);
1217 }
1218 {
1219 ScopedPhaseTimer phaseTimer("Whole-program ILA: Lock analysis");
1221 std::make_unique<LockAnalysis>(slicedTCT.get());
1223 }
1224 }
1225
1228 {
1229 ScopedPhaseTimer timer("Whole-program Replace Pre-TVF with Main-TVF overlay");
1230 preSVFGBuilder->replaceThreadAwareOverlay(
1232 }
1233 if (isMTAStatEnabled())
1234 SVFUtil::outs() << "[Main-TVF] "
1235 << preSVFGBuilder->getThreadAwareEdgeCount()
1236 << " interference edges over the whole BaseSVFG\n";
1237
1238 {
1239 ScopedPhaseTimer timer("Whole-program Flow-Sensitive FSMPTA Solve");
1240 auto solver = std::make_unique<FSMPTA<SVFG*>>(
1242 solver->analyze();
1243 mainFSMPTA = std::move(solver);
1244 }
1245
1246 std::set<RacePair> detectedPairs;
1247 {
1248 ScopedPhaseTimer timer("Final Race Detection (whole program)");
1250 racePairs, getMainPTA(), slicedMHP.get(),
1251 slicedLockAnalysis.get());
1252 }
1253
1254 std::set<const SVFStmt*> racyStmts;
1255 for (const RacePair& pair : detectedPairs)
1256 {
1257 racyStmts.insert(pair.stmt1);
1258 racyStmts.insert(pair.stmt2);
1259 }
1260
1261 SVFUtil::outs() << "\n=== Race Detection Summary ===\n";
1262 SVFUtil::outs() << "Race pairs (pre-analysis): " << racePairs.size() << "\n";
1263 SVFUtil::outs() << "Race pairs (whole program): " << detectedPairs.size() << "\n";
1264 SVFUtil::outs() << "Race statements (whole program): " << racyStmts.size() << "\n";
1265 if (isMTAStatEnabled())
1266 {
1267 const RaceDigests digests = computeRaceDigests(detectedPairs);
1268 SVFUtil::outs() << "[MSLI-RQ] mode=FSAM alarms=" << racyStmts.size()
1269 << " pairs=" << detectedPairs.size()
1270 << " alarm-digest=" << digests.alarm
1271 << " pair-digest=" << digests.pair << "\n";
1272 }
1273 return true;
1274}
static ThreadVFBuildConfig wholeProgram()
std::unique_ptr< SlicedSVFIRView > ptaSlicedView
Definition MTA.h:313

◆ updateDigest()

void SlicedMTA::updateDigest ( u64_t digest,
const std::string &  value 
)
staticprivate

Definition at line 532 of file MTA.cpp.

533{
534 for (unsigned char byte : value)
535 {
536 digest ^= static_cast<u64_t>(byte);
537 digest *= 1099511628211ULL;
538 }
539 digest ^= 0xffULL;
540 digest *= 1099511628211ULL;
541}
unsigned long long u64_t
Definition GeneralType.h:69

Member Data Documentation

◆ hasThreadFunctions

bool SVF::SlicedMTA::hasThreadFunctions = false
private

Definition at line 319 of file MTA.h.

◆ lockAnalysis

std::unique_ptr<LockAnalysis> SVF::SlicedMTA::lockAnalysis
private

Definition at line 293 of file MTA.h.

◆ mainContextDepth

u32_t SVF::SlicedMTA::mainContextDepth
private

Definition at line 290 of file MTA.h.

◆ mainFSMPTA

std::unique_ptr<FlowSensitive> SVF::SlicedMTA::mainFSMPTA
private

Definition at line 315 of file MTA.h.

◆ mhp

std::unique_ptr<MHP> SVF::SlicedMTA::mhp
private

Definition at line 292 of file MTA.h.

◆ mtaSlicedView

std::unique_ptr<SlicedSVFIRView> SVF::SlicedMTA::mtaSlicedView
private

Definition at line 312 of file MTA.h.

◆ multiStageSlicer

std::unique_ptr<MultiStageSlicer> SVF::SlicedMTA::multiStageSlicer
private

Definition at line 301 of file MTA.h.

◆ preAndersen

AndersenWaveDiff* SVF::SlicedMTA::preAndersen = nullptr
private

Definition at line 297 of file MTA.h.

◆ preCandidateSolveNodeIds

NodeBS SVF::SlicedMTA::preCandidateSolveNodeIds
private

Definition at line 302 of file MTA.h.

◆ preSVFG

SVFG* SVF::SlicedMTA::preSVFG = nullptr
private

Definition at line 300 of file MTA.h.

◆ preSVFGBuilder

std::unique_ptr<MTASVFGBuilder> SVF::SlicedMTA::preSVFGBuilder
private

Definition at line 299 of file MTA.h.

◆ ptaSlicedView

std::unique_ptr<SlicedSVFIRView> SVF::SlicedMTA::ptaSlicedView
private

Definition at line 313 of file MTA.h.

◆ racePairs

std::set<RacePair> SVF::SlicedMTA::racePairs
private

Definition at line 320 of file MTA.h.

◆ selectedThreadVFCandidates

MTASVFGBuilder::ThreadVFCandidateList SVF::SlicedMTA::selectedThreadVFCandidates
private

VFG'_pre endpoint-filtered, context-insensitive pre-MHP candidates. This is only a conservative worklist for rebuilding Main-TVF; the main phase independently re-decides every edge with main MHP and lock facts.

Definition at line 307 of file MTA.h.

◆ singleSlicedNodes

std::set<const ICFGNode*> SVF::SlicedMTA::singleSlicedNodes
private

Definition at line 310 of file MTA.h.

◆ singleSlicedSVFGNodeIds

NodeBS SVF::SlicedMTA::singleSlicedSVFGNodeIds
private

Definition at line 311 of file MTA.h.

◆ singleSlicer

std::unique_ptr<SingleSlicer> SVF::SlicedMTA::singleSlicer
private

Definition at line 303 of file MTA.h.

◆ slicedLockAnalysis

std::unique_ptr<LockAnalysis> SVF::SlicedMTA::slicedLockAnalysis
private

Definition at line 318 of file MTA.h.

◆ slicedMHP

std::unique_ptr<MHP> SVF::SlicedMTA::slicedMHP
private

Definition at line 317 of file MTA.h.

◆ slicedSVFGView

std::unique_ptr<SlicedSVFGView> SVF::SlicedMTA::slicedSVFGView
private

Definition at line 314 of file MTA.h.

◆ slicedTCT

std::unique_ptr<SlicedTCT> SVF::SlicedMTA::slicedTCT
private

Definition at line 316 of file MTA.h.

◆ svfir

SVFIR* SVF::SlicedMTA::svfir = nullptr
private

Definition at line 287 of file MTA.h.

◆ tct

std::unique_ptr<TCT> SVF::SlicedMTA::tct
private

Definition at line 291 of file MTA.h.

◆ threadCallGraph

ThreadCallGraph* SVF::SlicedMTA::threadCallGraph = nullptr
private

Definition at line 298 of file MTA.h.


The documentation for this class was generated from the following files: