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

daisytuner / sdfglib / 15518226219

08 Jun 2025 12:03PM UTC coverage: 61.652% (-0.8%) from 62.447%
15518226219

push

github

web-flow
Merge pull request #65 from daisytuner/lib-nodes-plugins

Adds registry for library node dispatchers

41 of 77 new or added lines in 5 files covered. (53.25%)

124 existing lines in 10 files now uncovered.

7249 of 11758 relevant lines covered (61.65%)

125.57 hits per line

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

59.22
/src/passes/dataflow/view_propagation.cpp
1
#include "sdfg/passes/dataflow/view_propagation.h"
2

3
namespace sdfg {
4
namespace passes {
5

6
ViewPropagation::ViewPropagation()
1✔
7
    : Pass() {
1✔
8

9
      };
1✔
10

11
std::string ViewPropagation::name() { return "ViewPropagation"; };
×
12

13
bool ViewPropagation::run_pass(builder::StructuredSDFGBuilder& builder,
1✔
14
                               analysis::AnalysisManager& analysis_manager) {
15
    bool applied = false;
1✔
16

17
    auto& sdfg = builder.subject();
1✔
18

19
    // Replaces all views by their original pointers
20
    auto& users = analysis_manager.get<analysis::Users>();
1✔
21
    std::unordered_set<std::string> reduced;
1✔
22
    for (auto& container : sdfg.containers()) {
3✔
23
        if (reduced.find(container) != reduced.end()) {
2✔
24
            continue;
1✔
25
        }
26
        auto& type = sdfg.type(container);
1✔
27
        if (!dynamic_cast<const types::Pointer*>(&type)) {
1✔
UNCOV
28
            continue;
×
29
        }
30
        if (sdfg.is_external(container)) {
1✔
31
            continue;
×
32
        }
33

34
        // Collect all moves of the pointer
35
        auto moves = users.moves(container);
1✔
36
        if (moves.empty() || !users.views(container).empty()) {
1✔
UNCOV
37
            continue;
×
38
        }
39
        auto uses = users.uses(container);
1✔
40
        for (auto& move : moves) {
2✔
41
            // Location of where the view is created
42
            auto& access_node = dynamic_cast<data_flow::AccessNode&>(*move->element());
1✔
43
            auto& graph = *move->parent();
1✔
44
            auto& edge = *graph.in_edges(access_node).begin();
1✔
45

46
            // The original pointer
47
            auto& viewed_node = dynamic_cast<const data_flow::AccessNode&>(edge.src());
1✔
48
            auto& viewed_container = viewed_node.data();
1✔
49
            auto& viewed_subset = edge.subset();
1✔
50
            if (viewed_subset.empty()) {
1✔
51
                continue;
×
52
            }
53
            if (edge.src_conn() != "void") {
1✔
54
                continue;
×
55
            }
56
            if (symbolic::is_pointer(symbolic::symbol(viewed_container))) {
1✔
57
                continue;
×
58
            }
59
            types::Pointer viewed_type(
1✔
60
                types::infer_type(sdfg, sdfg.type(viewed_container), viewed_subset));
1✔
61
            if (viewed_type != type) {
1✔
62
                continue;
×
63
            }
64

65
            // Iterate over all uses of the viewing container
66
            // Replace the view by the original pointer if possible
67
            for (auto& user : uses) {
3✔
68
                if (user->use() == analysis::Use::MOVE || user->use() == analysis::Use::VIEW) {
2✔
69
                    continue;
1✔
70
                }
71
                // Criterion: The assignment of the view must dominate the use of the view
72
                if (!users.dominates(*move, *user)) {
1✔
73
                    continue;
×
74
                }
75
                // Criterion: No pointer operations between the assignment and the use
76
                auto uses_between = users.all_uses_between(*move, *user);
1✔
77
                bool moving_pointers = false;
1✔
78
                for (auto& use : uses_between) {
1✔
79
                    if (use->use() != analysis::Use::MOVE) {
×
80
                        continue;
×
81
                    }
82
                    // Viewed container is not constant
83
                    if (use->container() == viewed_container) {
×
84
                        moving_pointers = true;
×
85
                        break;
×
86
                    }
87
                    // Moved container is not constant
88
                    if (use->container() == container) {
×
89
                        moving_pointers = true;
×
90
                        break;
×
91
                    }
92

93
                    // Unsafe pointer operations
94
                    auto& move_node = dynamic_cast<data_flow::AccessNode&>(*use->element());
×
95
                    auto& move_graph = *use->parent();
×
96
                    auto& move_edge = *move_graph.in_edges(move_node).begin();
×
97
                    auto& view_node = dynamic_cast<data_flow::AccessNode&>(move_edge.src());
×
98
                    if (move_edge.dst_conn() == "void" ||
×
99
                        symbolic::is_pointer(symbolic::symbol(view_node.data()))) {
×
100
                        moving_pointers = true;
×
101
                        break;
×
102
                    }
103
                }
104
                if (moving_pointers) {
1✔
105
                    continue;
×
106
                }
107

108
                // Replace the view by the original pointer
109
                if (auto use_node = dynamic_cast<data_flow::AccessNode*>(user->element())) {
1✔
110
                    auto use_graph = user->parent();
1✔
111
                    use_node->data() = viewed_container;
1✔
112

113
                    // Update subsets
114
                    for (auto& oedge : use_graph->out_edges(*use_node)) {
1✔
115
                        auto& old_subset = oedge.subset();
×
116

117
                        // Add leading dimensions
118
                        data_flow::Subset new_subset(viewed_subset.begin(),
×
119
                                                     viewed_subset.end() - 1);
×
120

121
                        // Accumulate overlapping dimension
122
                        auto& dim = old_subset[0];
×
123
                        auto& alias_dim = viewed_subset.back();
×
124
                        auto new_dim = symbolic::add(alias_dim, dim);
×
125
                        new_subset.push_back(new_dim);
×
126

127
                        // Add trailing dimensions
128
                        for (size_t i = 1; i < old_subset.size(); i++) {
×
129
                            auto& old_dim = old_subset[i];
×
130
                            new_subset.push_back(old_dim);
×
131
                        }
×
132

133
                        oedge.subset() = new_subset;
×
134
                    }
×
135
                    for (auto& iedge : use_graph->in_edges(*use_node)) {
2✔
136
                        auto& old_subset = iedge.subset();
1✔
137

138
                        // Add leading dimensions
139
                        data_flow::Subset new_subset(viewed_subset.begin(),
2✔
140
                                                     viewed_subset.end() - 1);
1✔
141

142
                        // Accumulate overlapping dimension
143
                        auto& dim = old_subset[0];
1✔
144
                        auto& alias_dim = viewed_subset.back();
1✔
145
                        auto new_dim = symbolic::add(alias_dim, dim);
1✔
146
                        new_subset.push_back(new_dim);
1✔
147

148
                        // Add trailing dimensions
149
                        for (size_t i = 1; i < old_subset.size(); i++) {
1✔
150
                            auto& old_dim = old_subset[i];
×
151
                            new_subset.push_back(old_dim);
×
152
                        }
×
153

154
                        iedge.subset() = new_subset;
1✔
155
                    }
1✔
156

157
                    applied = true;
1✔
158
                    reduced.insert(viewed_container);
1✔
159
                }
1✔
160
            }
1✔
161
        }
1✔
162
    }
1✔
163

164
    return applied;
1✔
165
};
1✔
166

167
}  // namespace passes
168
}  // 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