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

daisytuner / sdfglib / 15796425724

21 Jun 2025 02:00PM UTC coverage: 64.059% (-0.5%) from 64.591%
15796425724

push

github

web-flow
Merge pull request #95 from daisytuner/data-dependencies

Extends Data Dependency Analysis

993 of 1197 new or added lines in 19 files covered. (82.96%)

55 existing lines in 5 files now uncovered.

8058 of 12579 relevant lines covered (64.06%)

150.28 hits per line

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

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

3
#include "sdfg/analysis/assumptions_analysis.h"
4
#include "sdfg/analysis/data_dependency_analysis.h"
5
#include "sdfg/analysis/loop_analysis.h"
6
#include "sdfg/analysis/scope_analysis.h"
7
#include "sdfg/analysis/users.h"
8

9
namespace sdfg {
10
namespace passes {
11

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

16
      };
6✔
17

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

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

35
    // Criterion: loop must be data-parallel w.r.t containers
36
    auto& data_dependency_analysis = analysis_manager.get<analysis::DataDependencyAnalysis>();
4✔
37
    auto dependencies = data_dependency_analysis.dependencies(for_stmt);
4✔
38

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

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

56
    return true;
4✔
57
}
6✔
58

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