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

daisytuner / docc / 25342203931

04 May 2026 08:37PM UTC coverage: 64.937% (+0.09%) from 64.852%
25342203931

Pull #703

github

web-flow
Merge 07aad5b71 into af7ed26f3
Pull Request #703: adds LoopSplit transformation

52 of 69 new or added lines in 2 files covered. (75.36%)

2 existing lines in 1 file now uncovered.

31697 of 48812 relevant lines covered (64.94%)

2336.06 hits per line

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

77.61
/opt/src/transformations/loop_split.cpp
1
#include "sdfg/transformations/loop_split.h"
2

3
#include "sdfg/analysis/scope_analysis.h"
4
#include "sdfg/builder/structured_sdfg_builder.h"
5
#include "sdfg/deepcopy/structured_sdfg_deep_copy.h"
6
#include "sdfg/structured_control_flow/for.h"
7
#include "sdfg/structured_control_flow/map.h"
8
#include "sdfg/structured_control_flow/sequence.h"
9
#include "sdfg/symbolic/symbolic.h"
10

11
namespace sdfg {
12
namespace transformations {
13

14
LoopSplit::LoopSplit(structured_control_flow::StructuredLoop& loop, const symbolic::Expression& split_point)
15
    : loop_(loop), split_point_(split_point) {};
7✔
16

17
std::string LoopSplit::name() const { return "LoopSplit"; };
2✔
18

19
bool LoopSplit::can_be_applied(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
5✔
20
    // Loop must be contiguous (unit stride)
21
    if (!loop_.is_contiguous()) {
5✔
22
        return false;
1✔
23
    }
1✔
24

25
    // Loop must have a canonical bound (well-formed upper bound)
26
    auto bound = loop_.canonical_bound();
4✔
27
    if (bound == SymEngine::null) {
4✔
NEW
28
        return false;
×
NEW
29
    }
×
30

31
    // split_point must not be null
32
    if (split_point_ == SymEngine::null) {
4✔
NEW
33
        return false;
×
NEW
34
    }
×
35

36
    return true;
4✔
37
};
4✔
38

39
void LoopSplit::apply(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
4✔
40
    auto& sdfg = builder.subject();
4✔
41

42
    auto indvar = loop_.indvar();
4✔
43
    auto condition = loop_.condition();
4✔
44
    auto init = loop_.init();
4✔
45
    auto update = loop_.update();
4✔
46
    auto bound = loop_.canonical_bound();
4✔
47

48
    // Get parent scope
49
    auto& scope_analysis = analysis_manager.get<analysis::ScopeAnalysis>();
4✔
50
    auto parent = static_cast<structured_control_flow::Sequence*>(scope_analysis.parent_scope(&loop_));
4✔
51

52
    // Create the first loop (before the original): for (i = init; i < split_point; i++)
53
    auto first_condition = symbolic::Lt(indvar, split_point_);
4✔
54

55
    structured_control_flow::StructuredLoop* first_loop = nullptr;
4✔
56
    if (auto map = dynamic_cast<structured_control_flow::Map*>(&loop_)) {
4✔
NEW
57
        first_loop = &builder.add_map_before(
×
NEW
58
            *parent, loop_, indvar, first_condition, init, update, map->schedule_type(), {}, loop_.debug_info()
×
NEW
59
        );
×
60
    } else {
4✔
61
        first_loop =
4✔
62
            &builder.add_for_before(*parent, loop_, indvar, first_condition, init, update, {}, loop_.debug_info());
4✔
63
    }
4✔
64

65
    // Deep copy the original loop body into the first loop
66
    deepcopy::StructuredSDFGDeepCopy deep_copy(builder, first_loop->root(), loop_.root());
4✔
67
    deep_copy.insert();
4✔
68

69
    // Give the first loop a fresh induction variable (to avoid name collision)
70
    std::string new_indvar_name = builder.find_new_name(indvar->get_name());
4✔
71
    builder.add_container(new_indvar_name, sdfg.type(indvar->get_name()));
4✔
72
    first_loop->replace(indvar, symbolic::symbol(new_indvar_name));
4✔
73

74
    // Update the original loop to start at split_point: for (i = split_point; i < bound; i++)
75
    builder.update_loop(loop_, indvar, condition, split_point_, update);
4✔
76

77
    analysis_manager.invalidate_all();
4✔
78
};
4✔
79

80
void LoopSplit::to_json(nlohmann::json& j) const {
1✔
81
    std::string loop_type = "for";
1✔
82
    if (dynamic_cast<const structured_control_flow::Map*>(&loop_)) {
1✔
NEW
83
        loop_type = "map";
×
NEW
84
    }
×
85

86
    j["transformation_type"] = this->name();
1✔
87
    j["subgraph"] = {{"0", {{"element_id", loop_.element_id()}, {"type", loop_type}}}};
1✔
88
    j["parameters"] = {{"split_point", split_point_->__str__()}};
1✔
89
};
1✔
90

91
LoopSplit LoopSplit::from_json(builder::StructuredSDFGBuilder& builder, const nlohmann::json& desc) {
1✔
92
    auto loop_id = desc["subgraph"]["0"]["element_id"].get<size_t>();
1✔
93
    auto split_point_str = desc["parameters"]["split_point"].get<std::string>();
1✔
94

95
    auto element = builder.find_element_by_id(loop_id);
1✔
96
    if (element == nullptr) {
1✔
NEW
97
        throw InvalidTransformationDescriptionException("Element with ID " + std::to_string(loop_id) + " not found.");
×
NEW
98
    }
×
99

100
    auto loop = dynamic_cast<structured_control_flow::StructuredLoop*>(element);
1✔
101
    if (loop == nullptr) {
1✔
NEW
102
        throw InvalidTransformationDescriptionException(
×
NEW
103
            "Element with ID " + std::to_string(loop_id) + " is not a StructuredLoop."
×
NEW
104
        );
×
NEW
105
    }
×
106

107
    auto split_point = symbolic::parse(split_point_str);
1✔
108
    return LoopSplit(*loop, split_point);
1✔
109
};
1✔
110

111
} // namespace transformations
112
} // 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