Skip to content

Commit 06e0215

Browse files
authored
Integrate IDESolverAPIMixin into IterativeIDESolver (#813)
* Add IDESolverAPIMixin to IterativeIDESolver + small API-change in IDESolverAPIMixin::initialize() * Testing the IDESolverAPIMixin on the IterativeIDESolver * Fix example with solver API * Fix ide-solver example
1 parent c4ca07a commit 06e0215

File tree

10 files changed

+488
-317
lines changed

10 files changed

+488
-317
lines changed

BreakingChanges.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## development HEAD
44

5+
- `IDESolver::initialize()` does no longer return a `bool`. Now, you are always allowed to call `next()` at least once.
56
- `IntraMonoProblem` and `InterMonoProblem`, and all reference-implementations of these problems do not receive a TypeHierarchy-pointer anymore in the ctor.
67
- Requiring C++20 instead of C++17
78
- Type-traits and other templates that are specialized now use `requires` instead of `enable_if`, wherever possible. This may reduce the number of (defaulted) template parameters in some cases.

examples/how-to/04-run-ifds-analysis/ifds-solver.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,29 @@ int main(int Argc, char *Argv[]) {
4444
psr::IFDSSolver Solver(&TaintProblem, &ICFG);
4545

4646
// The simple solution. You don't really need an explicit solver for this:
47-
// Solver.solve();
47+
// auto Results = Solver.solve();
4848

4949
// Have more control over the solving process:
50-
if (Solver.initialize()) {
51-
int i = 0;
50+
Solver.initialize();
51+
int i = 0;
5252

53-
// Perform the next 10 analysis steps, while we still have some
54-
while (Solver.nextN(10)) {
55-
// Perform some intermediate task *during* the solving process.
56-
// We could also interrupt the solver at any time and continue later.
57-
llvm::outs() << "\b\b" << Spinner[i] << ' ';
58-
i = (i + 1) % std::size(Spinner);
53+
// Perform the next 10 analysis steps, while we still have some work items
54+
while (Solver.nextN(10)) {
55+
// Perform some intermediate task *during* the solving process.
56+
// We could also interrupt the solver at any time and continue later.
57+
llvm::outs() << "\b\b" << Spinner[i] << ' ';
58+
i = (i + 1) % std::size(Spinner);
5959

60-
// Wait a bit, such that we have time to see the beautiful animation for
61-
// our tiny example target programs:
62-
using namespace std::chrono_literals;
63-
std::this_thread::sleep_for(100ms);
64-
}
65-
66-
Solver.finalize();
67-
llvm::outs() << "\nSolving finished\n";
60+
// Wait a bit, such that we have time to see the beautiful animation for
61+
// our tiny example target programs:
62+
using namespace std::chrono_literals;
63+
std::this_thread::sleep_for(100ms);
6864
}
6965

70-
// Here, we could loop over TaintProblem.Leaks. Instead, we will now use
71-
// the Solver to dump the whole raw IFDS results:
72-
Solver.dumpResults();
66+
auto Results = Solver.finalize();
67+
llvm::outs() << "\nSolving finished\n";
68+
69+
// Here, we could loop over TaintProblem.Leaks. Instead, we will now use dump
70+
// the whole raw IFDS results:
71+
Results.dumpResults(ICFG);
7372
}

examples/how-to/04-run-ifds-analysis/simple.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ int main(int Argc, char *Argv[]) {
5555

5656
// Solving the TaintProblem. This may take some time, depending on the size of
5757
// the ICFG
58+
// Note: solveIFDSProblem() returns the raw SolverResults, but we don't use
59+
// them here...
5860
psr::solveIFDSProblem(TaintProblem, ICFG);
5961

6062
// After we have solved the TaintProblem, we can now inspect the detected

examples/how-to/05-run-ide-analysis/ide-solver.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,33 +41,29 @@ int main(int Argc, char *Argv[]) {
4141
// Solver.solve();
4242

4343
// Have more control over the solving process:
44-
if (Solver.initialize()) {
45-
int i = 0;
44+
Solver.initialize();
45+
int i = 0;
4646

47-
// Perform the next 10 analysis steps, while we still have some
48-
while (Solver.nextN(10)) {
49-
// Perform some intermediate task *during* the solving process.
50-
// We could also interrupt the solver at any time and continue later.
51-
llvm::outs() << "\b\b" << Spinner[i] << ' ';
52-
i = (i + 1) % std::size(Spinner);
47+
// Perform the next 10 analysis steps, while we still have some
48+
while (Solver.nextN(10)) {
49+
// Perform some intermediate task *during* the solving process.
50+
// We could also interrupt the solver at any time and continue later.
51+
llvm::outs() << "\b\b" << Spinner[i] << ' ';
52+
i = (i + 1) % std::size(Spinner);
5353

54-
// Wait a bit, such that we have time to see the beautiful animation for
55-
// our tiny example target programs:
56-
using namespace std::chrono_literals;
57-
std::this_thread::sleep_for(100ms);
58-
}
59-
60-
// In contrast to the IFDSSolver, finalize may take some time with IDE.
61-
// It will still be significantly faster than the above loop.
62-
Solver.finalize();
63-
llvm::outs() << "\nSolving finished\n";
54+
// Wait a bit, such that we have time to see the beautiful animation for
55+
// our tiny example target programs:
56+
using namespace std::chrono_literals;
57+
std::this_thread::sleep_for(100ms);
6458
}
6559

66-
// Accessing the results:
67-
auto Results = Solver.getSolverResults();
60+
// In contrast to the IFDSSolver, finalize may take some time with IDE.
61+
// It will still be significantly faster than the above loop.
62+
auto Results = Solver.finalize();
63+
llvm::outs() << "\nSolving finished\n";
6864

6965
// After we have solved the LCAProblem, we can now inspect the detected
70-
// constants. Instead of manually looping, will now use
71-
// the Solver to dump the whole raw IDE results:
72-
Solver.dumpResults();
66+
// constants. Instead of manually looping, will now dump the whole raw IDE
67+
// results:
68+
Results.dumpResults(ICFG);
7369
}

include/phasar/DataFlow/IfdsIde/Solver/IDESolver.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,7 @@ class IDESolver
17911791

17921792
/// -- InteractiveIDESolverMixin implementation
17931793

1794-
bool doInitialize() {
1794+
void doInitialize() {
17951795
PAMM_GET_INSTANCE;
17961796
REG_COUNTER("Gen facts", 0, Core);
17971797
REG_COUNTER("Kill facts", 0, Core);
@@ -1820,19 +1820,21 @@ class IDESolver
18201820

18211821
// We start our analysis and construct exploded supergraph
18221822
submitInitialSeeds();
1823-
return !WorkList.empty();
18241823
}
18251824

18261825
bool doNext() {
1827-
assert(!WorkList.empty());
1826+
if (WorkList.empty()) {
1827+
return false;
1828+
}
1829+
18281830
auto [Edge, EF] = std::move(WorkList.back());
18291831
WorkList.pop_back();
18301832

18311833
auto [SourceVal, Target, TargetVal] = Edge.consume();
18321834
propagate(std::move(SourceVal), std::move(Target), std::move(TargetVal),
18331835
std::move(EF));
18341836

1835-
return !WorkList.empty();
1837+
return true;
18361838
}
18371839

18381840
void finalizeInternal() {

0 commit comments

Comments
 (0)