• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daisytuner / sdfglib / 15656007340

14 Jun 2025 08:51PM UTC coverage: 13.234% (-49.9%) from 63.144%
15656007340

Pull #76

github

web-flow
Merge 9586c8161 into 413c53212
Pull Request #76: New Loop Dependency Analysis

361 of 465 new or added lines in 7 files covered. (77.63%)

6215 existing lines in 110 files now uncovered.

1612 of 12181 relevant lines covered (13.23%)

13.64 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.88
/src/analysis/loop_analysis.cpp
1
#include "sdfg/analysis/loop_analysis.h"
2

3
#include "sdfg/analysis/assumptions_analysis.h"
4
#include "sdfg/structured_control_flow/structured_loop.h"
5
#include "sdfg/symbolic/series.h"
6

7
namespace sdfg {
8
namespace analysis {
9

10
LoopAnalysis::LoopAnalysis(StructuredSDFG& sdfg) : Analysis(sdfg) {}
17✔
11

12
void LoopAnalysis::run(structured_control_flow::ControlFlowNode& scope,
39✔
13
                       structured_control_flow::ControlFlowNode* parent_loop) {
14
    std::list<structured_control_flow::ControlFlowNode*> queue = {&scope};
39✔
15
    while (!queue.empty()) {
120✔
16
        auto current = queue.front();
81✔
17
        queue.pop_front();
81✔
18

19
        // Loop detected
20
        if (auto while_stmt = dynamic_cast<structured_control_flow::While*>(current)) {
81✔
21
            this->loops_.insert(while_stmt);
×
22
            this->loop_tree_[while_stmt] = parent_loop;
×
23
        } else if (auto loop_stmt =
81✔
24
                       dynamic_cast<structured_control_flow::StructuredLoop*>(current)) {
81✔
25
            this->loops_.insert(loop_stmt);
22✔
26
            this->loop_tree_[loop_stmt] = parent_loop;
22✔
27
        }
22✔
28

29
        if (dynamic_cast<structured_control_flow::Block*>(current)) {
81✔
30
            continue;
20✔
31
        } else if (auto sequence_stmt = dynamic_cast<structured_control_flow::Sequence*>(current)) {
61✔
32
            for (size_t i = 0; i < sequence_stmt->size(); i++) {
81✔
33
                queue.push_back(&sequence_stmt->at(i).first);
42✔
34
            }
42✔
35
        } else if (auto if_else_stmt = dynamic_cast<structured_control_flow::IfElse*>(current)) {
61✔
UNCOV
36
            for (size_t i = 0; i < if_else_stmt->size(); i++) {
×
UNCOV
37
                queue.push_back(&if_else_stmt->at(i).first);
×
UNCOV
38
            }
×
39
        } else if (auto while_stmt = dynamic_cast<structured_control_flow::While*>(current)) {
22✔
40
            this->run(while_stmt->root(), while_stmt);
×
41
        } else if (auto for_stmt =
22✔
42
                       dynamic_cast<structured_control_flow::StructuredLoop*>(current)) {
22✔
43
            this->run(for_stmt->root(), for_stmt);
22✔
44
        } else if (dynamic_cast<structured_control_flow::Break*>(current)) {
22✔
45
            continue;
×
46
        } else if (dynamic_cast<structured_control_flow::Continue*>(current)) {
×
47
            continue;
×
48
        } else if (dynamic_cast<structured_control_flow::Return*>(current)) {
×
49
            continue;
×
50
        } else {
51
            throw std::runtime_error("Unsupported control flow node type");
×
52
        }
53
    }
54
}
39✔
55

56
void LoopAnalysis::run(AnalysisManager& analysis_manager) {
17✔
57
    this->loops_.clear();
17✔
58
    this->loop_tree_.clear();
17✔
59
    this->run(this->sdfg_.root(), nullptr);
17✔
60
}
17✔
61

62
const std::unordered_set<structured_control_flow::ControlFlowNode*> LoopAnalysis::loops() const {
17✔
63
    return this->loops_;
17✔
64
}
65

66
bool LoopAnalysis::is_monotonic(structured_control_flow::StructuredLoop* loop) const {
22✔
67
    AnalysisManager manager(this->sdfg_);
22✔
68
    auto& assums_analysis = manager.get<AssumptionsAnalysis>();
22✔
69
    auto assums = assums_analysis.get(*loop);
22✔
70

71
    return symbolic::is_monotonic(loop->update(), loop->indvar(), assums);
22✔
72
}
22✔
73

UNCOV
74
bool LoopAnalysis::is_contiguous(structured_control_flow::StructuredLoop* loop) const {
×
UNCOV
75
    AnalysisManager manager(this->sdfg_);
×
UNCOV
76
    auto& assums_analysis = manager.get<AssumptionsAnalysis>();
×
UNCOV
77
    auto assums = assums_analysis.get(*loop);
×
78

UNCOV
79
    return symbolic::is_contiguous(loop->update(), loop->indvar(), assums);
×
UNCOV
80
}
×
81

82
const std::unordered_map<structured_control_flow::ControlFlowNode*,
83
                         structured_control_flow::ControlFlowNode*>&
84
LoopAnalysis::loop_tree() const {
×
85
    return this->loop_tree_;
×
86
}
87

88
structured_control_flow::ControlFlowNode* LoopAnalysis::parent_loop(
×
89
    structured_control_flow::ControlFlowNode* loop) const {
90
    return this->loop_tree_.at(loop);
×
91
}
92

93
const std::vector<structured_control_flow::ControlFlowNode*> LoopAnalysis::outermost_loops() const {
×
94
    std::vector<structured_control_flow::ControlFlowNode*> outermost_loops_;
×
95
    for (const auto& [loop, parent] : this->loop_tree_) {
×
96
        if (parent == nullptr) {
×
97
            outermost_loops_.push_back(loop);
×
98
        }
×
99
    }
100
    return outermost_loops_;
×
101
}
×
102

103
}  // namespace analysis
104
}  // namespace sdfg
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc