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

daisytuner / sdfglib / 15715539019

17 Jun 2025 06:41PM UTC coverage: 64.669% (+0.09%) from 64.576%
15715539019

Pull #88

github

web-flow
Merge 939ecf007 into 64c5c1c6a
Pull Request #88: Generalizes For2Map Pass

75 of 92 new or added lines in 8 files covered. (81.52%)

6 existing lines in 3 files now uncovered.

7995 of 12363 relevant lines covered (64.67%)

142.4 hits per line

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

89.36
/src/passes/structured_control_flow/for2map.cpp
1
#include "sdfg/passes/structured_control_flow/for2map.h"
2

3
#include "sdfg/analysis/loop_analysis.h"
4
#include "sdfg/analysis/loop_dependency_analysis.h"
5
#include "sdfg/analysis/scope_analysis.h"
6

7
namespace sdfg {
8
namespace passes {
9

10
For2Map::For2Map(builder::StructuredSDFGBuilder& builder,
6✔
11
                 analysis::AnalysisManager& analysis_manager)
12
    : visitor::StructuredSDFGVisitor(builder, analysis_manager) {
6✔
13

14
      };
6✔
15

16
bool For2Map::can_be_applied(structured_control_flow::For& for_stmt,
6✔
17
                             analysis::AnalysisManager& analysis_manager) {
18
    // Criterion: loop must be contiguous
19
    // Simplification to reason about memory offsets and bounds
20
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
6✔
21
    if (!loop_analysis.is_contiguous(&for_stmt)) {
6✔
22
        return false;
1✔
23
    }
24
    std::cout << "Contiguous" << std::endl;
5✔
25

26
    // Criterion: loop condition can be written as a closed-form expression.
27
    // Closed-form: i < expression_no_i
28
    // Example: i < N && i < M -> i < min(N, M)
29
    auto bound = loop_analysis.canonical_bound(&for_stmt);
5✔
30
    if (bound == SymEngine::null) {
5✔
31
        return false;
1✔
32
    }
33
    std::cout << "Canonical bound" << std::endl;
4✔
34

35
    // Criterion: loop must be data-parallel w.r.t containers
36
    auto& loop_dependency_analysis = analysis_manager.get<analysis::LoopDependencyAnalysis>();
4✔
37
    auto dependencies = loop_dependency_analysis.get(for_stmt);
4✔
38
    std::cout << "Dependencies: " << dependencies.size() << std::endl;
4✔
39

40
    // a. No true dependencies (RAW) between iterations
41
    for (auto& dep : dependencies) {
4✔
NEW
42
        if (dep.second == analysis::LoopCarriedDependency::RAW) {
×
NEW
43
            return false;
×
44
        }
45
    }
46

47
    // b. False dependencies (WAW) are limited to loop-local variables
48
    auto& users = analysis_manager.get<analysis::Users>();
4✔
49
    auto locals = users.locals(for_stmt.root());
4✔
50
    for (auto& dep : dependencies) {
4✔
NEW
51
        auto& container = dep.first;
×
NEW
52
        if (locals.find(container) == locals.end()) {
×
NEW
53
            return false;
×
54
        }
55
    }
56

57
    return true;
4✔
58
}
6✔
59

60
void For2Map::apply(structured_control_flow::For& for_stmt, builder::StructuredSDFGBuilder& builder,
4✔
61
                    analysis::AnalysisManager& analysis_manager) {
62
    // Contiguous and canonical bound -> we can compute the number of iterations
63
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
4✔
64
    auto init = for_stmt.init();
4✔
65
    auto num_iterations = symbolic::sub(loop_analysis.canonical_bound(&for_stmt), init);
4✔
66

67
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
4✔
68
    auto parent =
4✔
69
        static_cast<structured_control_flow::Sequence*>(scope_analysis.parent_scope(&for_stmt));
4✔
70

71
    // convert for to map
72
    auto& map = builder.convert_for(*parent, for_stmt, num_iterations);
4✔
73
    auto& indvar = map.indvar();
4✔
74

75
    // Shift indvar by init in body
76
    auto shift = symbolic::add(indvar, init);
4✔
77
    map.root().replace(indvar, shift);
4✔
78

79
    // set indvar to last value of a sequential loop
80
    auto successor = builder.add_block_after(*parent, map);
4✔
81
    auto last_value = symbolic::add(init, num_iterations);
4✔
82
    successor.second.assignments().insert({indvar, last_value});
4✔
83
}
4✔
84

85
bool For2Map::accept(structured_control_flow::Sequence& parent,
6✔
86
                     structured_control_flow::For& node) {
87
    if (!this->can_be_applied(node, analysis_manager_)) {
6✔
88
        return false;
2✔
89
    }
90

91
    this->apply(node, builder_, analysis_manager_);
4✔
92
    return true;
4✔
93
}
6✔
94

95
}  // namespace passes
96
}  // 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