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

daisytuner / docc / 26556322966

27 May 2026 03:45PM UTC coverage: 60.869% (-0.02%) from 60.886%
26556322966

push

github

web-flow
Libnode ptr edges (#719)

Migrating SDFGs to treat pointers as inputs to libNodes / Calls as scalars.
A pointer will only appear in an output edge if its actually returned from the function (like malloc).

* Stdlib, Blas and Tensor Matmul nodes were migrated to this new format. Other, currently transitory Tensor Nodes are not yet migrated.
* DOCC version was bumped to incorporate previous docc-llvm versions (up to 0.4.0) that had been counted separately.
! Until all passes consider the use / leak of pointers as uncertainty / hiding potential writes, TensorNodes are declared as general side-effect.
* Lots of utility functions to centralize the creation (and edges) of various libNodes that needed to be changed.
* Fixed & unified docc paths across python and llvm front-ends.
* Skip BlockFusion test that fails to its libNodes currently having side effects
~ Prevent a crash in DotViz when using symbolic offsets into structs
* Removing old ConstProp pass, it is not safe for the new pointer representation and should not be all too critical

961 of 1749 new or added lines in 52 files covered. (54.95%)

87 existing lines in 28 files now uncovered.

35225 of 57870 relevant lines covered (60.87%)

11046.32 hits per line

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

78.17
/sdfg/src/data_flow/pointer_metadata.cpp
1
#include "sdfg/data_flow/pointer_metadata.h"
2

3
#include "cereal/types/utility.hpp"
4
#include "sdfg/serializer/json_serializer.h"
5

6
namespace sdfg::data_flow {
7

8
MemoryAccessPatternType MemoryAccessPattern::ref() const {
8✔
9
    return std::unique_ptr<
8✔
10
        MemoryAccessPattern,
8✔
11
        AccessPatternsDeleter>(const_cast<MemoryAccessPattern*>(this), AccessPatternsDeleter(false));
8✔
12
}
8✔
13

NEW
14
MemoryAccessPatternType ConvexAccessPattern::clone() const {
×
NEW
15
    return std::unique_ptr<MemoryAccessPattern, AccessPatternsDeleter>(new ConvexAccessPattern(size_));
×
NEW
16
}
×
17

18
void ConvexAccessPattern::serialize_to_json(nlohmann::json& entry) {
1✔
19
    entry["type"] = "ConvexAccessPattern";
1✔
20
    serializer::JSONSerializer serializer;
1✔
21
    entry["size"] = serializer.expression(size_);
1✔
22
    entry["not_sparse"] = not_sparse_;
1✔
23
}
1✔
24

25
MemoryAccessPatternType ConvexAccessPattern::create(symbolic::Expression size, bool not_sparse) {
8✔
26
    return std::unique_ptr<MemoryAccessPattern, AccessPatternsDeleter>(new ConvexAccessPattern(size, not_sparse));
8✔
27
}
8✔
28

29
MemoryAccessPatternType NoAccessPattern::instance() {
6✔
30
    static std::unique_ptr<MemoryAccessPattern, AccessPatternsDeleter> instance(new NoAccessPattern());
6✔
31
    return instance->ref();
6✔
32
}
6✔
33

34
void NoAccessPattern::serialize_to_json(nlohmann::json& entry) { entry["type"] = "NoAccessPattern"; }
1✔
35

NEW
36
MemoryAccessPatternType NoAccessPattern::clone() const { return this->ref(); }
×
37

NEW
38
PointerAccessType PointerAccessMeta::ref() const {
×
NEW
39
    return std::unique_ptr<
×
NEW
40
        PointerAccessMeta,
×
NEW
41
        PtrAccessDeleter>(const_cast<PointerAccessMeta*>(this), PtrAccessDeleter(false));
×
NEW
42
}
×
43

44
PointerAccessType PointerAccessMeta::create_read_only(const symbolic::Expression& size, bool no_capture) {
6✔
45
    return std::unique_ptr<PointerAccessMeta, PtrAccessDeleter>(new PointerReadOnly(size, no_capture));
6✔
46
}
6✔
47

48
PointerAccessType PointerAccessMeta::create_invalidate() {
5✔
49
    return std::unique_ptr<PointerAccessMeta, PtrAccessDeleter>(new PointerInvalidate());
5✔
50
}
5✔
51

52
PointerAccessType PointerAccessMeta::create_full_write_only(const symbolic::Expression& size, bool no_capture) {
5✔
53
    return std::unique_ptr<
5✔
54
        PointerAccessMeta,
5✔
55
        PtrAccessDeleter>(new PointerFullWriteOnly(size, no_capture), PtrAccessDeleter(true));
5✔
56
}
5✔
57

58
PointerAccessType PointerAccessMeta::
59
    create_generic(MemoryAccessPatternType read_pattern, MemoryAccessPatternType write_pattern, bool no_capture) {
3✔
60
    return std::unique_ptr<
3✔
61
        PointerAccessMeta,
3✔
62
        PtrAccessDeleter>(new PointerGenericAccess(std::move(read_pattern), std::move(write_pattern), no_capture));
3✔
63
}
3✔
64

65
PointerReadOnly::PointerReadOnly(symbolic::Expression size, bool no_capture) : size_(size), no_capture_(no_capture) {}
6✔
66

67
MemoryAccessPatternType PointerReadOnly::access_read_pattern() const {
2✔
68
    if (size_.is_null()) {
2✔
NEW
69
        return {};
×
70
    } else {
2✔
71
        return ConvexAccessPattern::create(size_);
2✔
72
    }
2✔
73
}
2✔
74

75
MemoryAccessPatternType PointerReadOnly::access_write_pattern() const { return NoAccessPattern::instance(); }
2✔
76

NEW
77
void PointerReadOnly::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
×
NEW
78
    size_ = symbolic::subs(size_, old_expression, new_expression);
×
NEW
79
}
×
80

NEW
81
PointerAccessType PointerReadOnly::clone() const { return PointerAccessType(new PointerReadOnly(size_, no_capture_)); }
×
82

83
void PointerReadOnly::serialize_to_json(nlohmann::json& entry) {
1✔
84
    serializer::JSONSerializer serializer;
1✔
85
    entry["type"] = "PointerReadOnly";
1✔
86
    entry["size"] = serializer.expression(size_);
1✔
87
    entry["no_capture"] = no_capture_;
1✔
88
}
1✔
89

90
PointerFullWriteOnly::PointerFullWriteOnly(symbolic::Expression size, bool no_capture)
91
    : size_(size), no_capture_(no_capture) {}
5✔
92

93
MemoryAccessPatternType PointerFullWriteOnly::access_write_pattern() const {
2✔
94
    if (size_.is_null()) {
2✔
NEW
95
        return nullptr;
×
96
    } else {
2✔
97
        return ConvexAccessPattern::create(size_, true);
2✔
98
    }
2✔
99
}
2✔
100

101
MemoryAccessPatternType PointerFullWriteOnly::access_read_pattern() const { return NoAccessPattern::instance(); }
2✔
102

NEW
103
void PointerFullWriteOnly::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
×
NEW
104
    size_ = symbolic::subs(size_, old_expression, new_expression);
×
NEW
105
}
×
106

NEW
107
PointerAccessType PointerFullWriteOnly::clone() const {
×
NEW
108
    return PointerAccessType(new PointerFullWriteOnly(size_, no_capture_));
×
NEW
109
}
×
110

111
void PointerFullWriteOnly::serialize_to_json(nlohmann::json& entry) {
1✔
112
    serializer::JSONSerializer serializer;
1✔
113
    entry["type"] = "PointerWriteOnly";
1✔
114
    entry["size"] = serializer.expression(size_);
1✔
115
    entry["no_capture"] = no_capture_;
1✔
116
}
1✔
117

118
PointerGenericAccess::
119
    PointerGenericAccess(MemoryAccessPatternType read_pattern, MemoryAccessPatternType write_pattern, bool no_capture)
120
    : read_pattern_(std::move(read_pattern)), write_pattern_(std::move(write_pattern)), no_capture_(no_capture) {}
3✔
121

122
MemoryAccessPatternType PointerGenericAccess::access_read_pattern() const {
1✔
123
    return read_pattern_ ? read_pattern_->ref() : nullptr;
1✔
124
}
1✔
125

126
MemoryAccessPatternType PointerGenericAccess::access_write_pattern() const {
1✔
127
    return write_pattern_ ? write_pattern_->ref() : nullptr;
1✔
128
}
1✔
129

130
bool PointerGenericAccess::may_contain_reads() const { return !read_pattern_ || !read_pattern_->empty(); }
1✔
131

132
bool PointerGenericAccess::may_contain_writes() const { return !write_pattern_ || !write_pattern_->empty(); }
1✔
133

NEW
134
void PointerGenericAccess::replace(const symbolic::Expression old_expression, const symbolic::Expression new_expression) {
×
NEW
135
    if (read_pattern_) {
×
NEW
136
        read_pattern_->replace(old_expression, new_expression);
×
NEW
137
    }
×
NEW
138
    if (write_pattern_) {
×
NEW
139
        write_pattern_->replace(old_expression, new_expression);
×
NEW
140
    }
×
NEW
141
}
×
142

NEW
143
PointerAccessType PointerGenericAccess::clone() const {
×
NEW
144
    auto rd_patt_new = read_pattern_ ? read_pattern_->clone() : nullptr;
×
NEW
145
    auto wr_patt_new = write_pattern_ ? write_pattern_->clone() : nullptr;
×
NEW
146
    return PointerAccessType(new PointerGenericAccess(std::move(rd_patt_new), std::move(wr_patt_new), no_capture_));
×
NEW
147
}
×
148

149
void PointerGenericAccess::serialize_to_json(nlohmann::json& entry) {
1✔
150
    entry["type"] = "PointerGenericAccess";
1✔
151
    if (read_pattern_) {
1✔
152
        read_pattern_->serialize_to_json(entry["read_pattern"]);
1✔
153
    }
1✔
154
    if (write_pattern_) {
1✔
155
        write_pattern_->serialize_to_json(entry["write_pattern"]);
1✔
156
    }
1✔
157
    entry["no_capture"] = no_capture_;
1✔
158
}
1✔
159

NEW
160
PointerAccessType PointerInvalidate::clone() const { return PointerAccessType(new PointerInvalidate()); }
×
161

162
void PointerInvalidate::serialize_to_json(nlohmann::json& entry) { entry["type"] = "PointerInvalidate"; }
1✔
163

164
PointerAccessType PointerAccessMetaSerializer::deserialize(const nlohmann::json& entry) {
4✔
165
    if (entry.is_null()) {
4✔
NEW
166
        return nullptr;
×
167
    } else {
4✔
168
        auto type = entry.at("type").get<std::string>();
4✔
169

170
        if (type == "PointerInvalidate") {
4✔
171
            return PointerAccessMeta::create_invalidate();
1✔
172
        } else if (type == "PointerReadOnly") {
3✔
173
            return deserialize_read_only(entry);
1✔
174
        } else if (type == "PointerWriteOnly") {
2✔
175
            return deserialize_write_only(entry);
1✔
176
        } else if (type == "PointerGenericAccess") {
1✔
177
            return deserialize_generic(entry);
1✔
178
        } else {
1✔
NEW
179
            throw std::runtime_error("Unknown MemoryAccessPattern type: " + type);
×
NEW
180
        }
×
181
    }
4✔
182
}
4✔
183

184
std::vector<PointerAccessType> PointerAccessMetaSerializer::deserialize_list(nlohmann::json::const_reference list) {
4✔
185
    std::vector<PointerAccessType> result;
4✔
186
    for (const auto& entry : list) {
4✔
187
        result.push_back(deserialize(entry));
4✔
188
    }
4✔
189
    return result;
4✔
190
}
4✔
191

192
std::vector<PointerAccessType> PointerAccessMetaSerializer::
193
    deserialize_list(nlohmann::json::const_iterator key, const nlohmann::json& parent) {
3✔
194
    if (key != parent.end()) {
3✔
195
        return deserialize_list(*key);
3✔
196
    } else {
3✔
NEW
197
        return {};
×
NEW
198
    }
×
199
}
3✔
200

201
PointerAccessType PointerAccessMetaSerializer::deserialize_read_only(nlohmann::json::const_reference entry) {
1✔
202
    serializer::JSONSerializer serializer;
1✔
203
    bool no_capture = entry.at("no_capture").get<bool>();
1✔
204
    auto size = serializer.json_to_expr(entry.at("size"));
1✔
205
    return PointerAccessMeta::create_read_only(size, no_capture);
1✔
206
}
1✔
207

208
PointerAccessType PointerAccessMetaSerializer::deserialize_write_only(nlohmann::json::const_reference entry) {
1✔
209
    serializer::JSONSerializer serializer;
1✔
210
    bool no_capture = entry.at("no_capture").get<bool>();
1✔
211
    auto size = serializer.json_to_expr(entry.at("size"));
1✔
212
    return PointerAccessMeta::create_full_write_only(size, no_capture);
1✔
213
}
1✔
214

215
PointerAccessType PointerAccessMetaSerializer::deserialize_generic(nlohmann::json::const_reference entry) {
1✔
216
    auto read_pattern = deserialize_access_pattern(entry.at("read_pattern"));
1✔
217
    auto write_pattern = deserialize_access_pattern(entry.at("write_pattern"));
1✔
218
    bool no_capture = entry.at("no_capture").get<bool>();
1✔
219
    return PointerAccessMeta::create_generic(std::move(read_pattern), std::move(write_pattern), no_capture);
1✔
220
}
1✔
221

222
MemoryAccessPatternType PointerAccessMetaSerializer::deserialize_convex_pattern(nlohmann::json::const_reference entry) {
1✔
223
    serializer::JSONSerializer serializer;
1✔
224
    auto size = serializer.json_to_expr(entry.at("size"));
1✔
225
    bool not_sparse = entry.at("not_sparse").get<bool>();
1✔
226
    return ConvexAccessPattern::create(size, not_sparse);
1✔
227
}
1✔
228

229
MemoryAccessPatternType PointerAccessMetaSerializer::deserialize_access_pattern(nlohmann::json::const_reference entry) {
2✔
230
    if (entry.is_null()) {
2✔
NEW
231
        return nullptr;
×
232
    } else {
2✔
233
        auto type = entry.at("type").get<std::string>();
2✔
234
        if (type == "NoAccessPattern") {
2✔
235
            return NoAccessPattern::instance();
1✔
236
        } else if (type == "ConvexAccessPattern") {
1✔
237
            return deserialize_convex_pattern(entry);
1✔
238
        } else {
1✔
NEW
239
            throw std::runtime_error("Unknown MemoryAccessPattern type: " + type);
×
NEW
240
        }
×
241
    }
2✔
242
}
2✔
243

244
nlohmann::json PointerAccessMetaSerializer::serialize(const std::vector<PointerAccessType>& vector) {
4✔
245
    auto arr = nlohmann::json::array();
4✔
246
    for (const auto& entry : vector) {
4✔
247
        nlohmann::json j;
4✔
248
        entry->serialize_to_json(j);
4✔
249
        arr.push_back(j);
4✔
250
    }
4✔
251
    return arr;
4✔
252
}
4✔
253

254
} // namespace sdfg::data_flow
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