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

daisytuner / sdfglib / 19496232534

19 Nov 2025 09:22AM UTC coverage: 62.105% (-0.08%) from 62.184%
19496232534

push

github

web-flow
Merge pull request #354 from daisytuner/tenstorrent-transform

Tenstorrent transform

52 of 95 new or added lines in 15 files covered. (54.74%)

28 existing lines in 8 files now uncovered.

11141 of 17939 relevant lines covered (62.1%)

112.04 hits per line

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

70.0
/src/analysis/type_analysis.cpp
1
#include "sdfg/analysis/type_analysis.h"
2

3
#include "sdfg/analysis/users.h"
4
#include "sdfg/exceptions.h"
5

6
namespace sdfg {
7
namespace analysis {
8

9
void TypeAnalysis::run(analysis::AnalysisManager& analysis_manager) {
8✔
10
    std::vector<std::string> containers;
8✔
11
    for (auto container : this->sdfg_.containers()) {
22✔
12
        auto& contType = sdfg_.type(container);
14✔
13
        if (contType.type_id() == sdfg::types::TypeID::Pointer) {
14✔
14
            auto pointer_type = static_cast<const sdfg::types::Pointer*>(&sdfg_.type(container));
11✔
15
            if (!pointer_type->has_pointee_type()) {
11✔
16
                containers.push_back(container);
10✔
17
            }
10✔
18
        } else if (contType.type_id() == sdfg::types::TypeID::Structure) { // we model std::shared_ptr as pointer-like
14✔
19
                                                                           // structure
20
            // if we find uses of it AS a pointer those can also be used
NEW
21
            auto struct_type = static_cast<const sdfg::types::Structure&>(contType);
×
NEW
22
            if (struct_type.is_pointer_like()) {
×
NEW
23
                containers.push_back(container);
×
NEW
24
            }
×
UNCOV
25
        }
×
26
    }
14✔
27

28
    auto& users = analysis_manager.get<Users>();
8✔
29
    for (auto container : containers) {
18✔
30
        // iterate over writes
31
        for (auto user : users.writes(container)) {
12✔
32
            auto access_node = dynamic_cast<data_flow::AccessNode*>(user->element());
2✔
33
            if (access_node == nullptr) {
2✔
34
                continue;
×
35
            }
36

37
            for (auto& memlet : access_node->get_parent().in_edges(*access_node)) {
4✔
38
                auto base_type = &memlet.base_type();
2✔
39
                if (base_type->type_id() == types::TypeID::Pointer) {
2✔
40
                    auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
2✔
41
                    if (!pointer_type->has_pointee_type()) {
2✔
42
                        continue;
×
43
                    }
44
                } else if (base_type->type_id() == types::TypeID::Structure) { // pointer-likes may also be used raw.
2✔
45
                                                                               // Cannot glean anything from those
46
                                                                               // accesses directly
NEW
47
                    continue;
×
48
                }
49

50
                if (memlet.type() == data_flow::MemletType::Dereference_Src) {
2✔
51
                    if (base_type->type_id() == types::TypeID::Pointer) {
×
52
                        auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
×
53
                        base_type = &pointer_type->pointee_type();
×
54

55
                    } /* else if (base_type->type_id() == types::TypeID::Array) {
×
56
                        auto array_type = dynamic_cast<const types::Array*>(base_type);
57
                        base_type = &array_type->element_type();
58
                    } */
59

60
                    if (base_type->type_id() == types::TypeID::Pointer) {
×
61
                        auto inner_pointer_type = dynamic_cast<const types::Pointer*>(base_type);
×
62
                        if (!inner_pointer_type->has_pointee_type()) {
×
63
                            continue;
×
64
                        }
65
                    }
×
66
                }
×
67

68
                if (this->type_map_.find(container) == this->type_map_.end()) {
2✔
69
                    this->type_map_.insert({container, base_type});
2✔
70
                    continue;
2✔
71
                }
72
            }
73
        }
74

75
        // iterate over reads
76
        for (auto user : users.reads(container)) {
13✔
77
            // Pointers may be used in symbolic conditions
78
            auto access_node = dynamic_cast<data_flow::AccessNode*>(user->element());
3✔
79
            if (access_node == nullptr) {
3✔
80
                continue;
×
81
            }
82

83
            for (auto& memlet : access_node->get_parent().out_edges(*access_node)) {
6✔
84
                auto base_type = &memlet.base_type();
3✔
85
                if (base_type->type_id() == types::TypeID::Pointer) {
3✔
86
                    auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
3✔
87
                    if (!pointer_type->has_pointee_type()) {
3✔
88
                        continue;
×
89
                    }
90
                } else if (base_type->type_id() == types::TypeID::Structure) { // pointer-likes may also be used raw.
3✔
91
                                                                               // Cannot glean anything from those
92
                                                                               // accesses directly
NEW
93
                    continue;
×
94
                }
95

96
                if (memlet.type() == data_flow::MemletType::Dereference_Dst) {
3✔
97
                    if (base_type->type_id() == types::TypeID::Pointer) {
×
98
                        auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
×
99
                        base_type = &pointer_type->pointee_type();
×
100

101
                    } /* else if (base_type->type_id() == types::TypeID::Array) {
×
102
                        auto array_type = dynamic_cast<const types::Array*>(base_type);
103
                        base_type = &array_type->element_type();
104
                    } */
105

106
                    if (base_type->type_id() == types::TypeID::Pointer) {
×
107
                        auto inner_pointer_type = dynamic_cast<const types::Pointer*>(base_type);
×
108
                        if (!inner_pointer_type->has_pointee_type()) {
×
109
                            continue;
×
110
                        }
111
                    }
×
112
                }
×
113
                if (this->type_map_.find(container) == this->type_map_.end()) {
3✔
114
                    this->type_map_.insert({container, base_type});
3✔
115
                    continue;
3✔
116
                }
117
            }
118
        }
119

120
        // iterate over views
121
        for (auto user : users.views(container)) {
13✔
122
            auto access_node = dynamic_cast<data_flow::AccessNode*>(user->element());
3✔
123
            if (access_node == nullptr) {
3✔
124
                continue;
×
125
            }
126
            for (auto& memlet : access_node->get_parent().out_edges(*access_node)) {
6✔
127
                auto base_type = &memlet.base_type();
3✔
128
                if (base_type->type_id() == types::TypeID::Pointer) {
3✔
129
                    auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
3✔
130
                    if (!pointer_type->has_pointee_type()) {
3✔
131
                        continue;
×
132
                    }
133
                } else if (base_type->type_id() == types::TypeID::Structure) { // pointer-likes may also be used raw.
3✔
134
                                                                               // Cannot glean anything from those
135
                                                                               // accesses directly
NEW
136
                    continue;
×
137
                }
138

139
                if (memlet.type() == data_flow::MemletType::Dereference_Dst) {
3✔
140
                    if (base_type->type_id() == types::TypeID::Pointer) {
2✔
141
                        auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
2✔
142
                        base_type = &pointer_type->pointee_type();
2✔
143

144
                    } /* else if (base_type->type_id() == types::TypeID::Array) {
2✔
145
                        auto array_type = dynamic_cast<const types::Array*>(base_type);
146
                        base_type = &array_type->element_type();
147
                    } */
148

149
                    if (base_type->type_id() == types::TypeID::Pointer) {
2✔
150
                        auto inner_pointer_type = dynamic_cast<const types::Pointer*>(base_type);
2✔
151
                        if (!inner_pointer_type->has_pointee_type()) {
2✔
152
                            continue;
×
153
                        }
154
                    }
2✔
155
                }
2✔
156
                if (this->type_map_.find(container) == this->type_map_.end()) {
3✔
157
                    this->type_map_.insert({container, base_type});
3✔
158
                    continue;
3✔
159
                }
160
            }
161
        }
162

163
        // iterate over moves
164
        for (auto user : users.moves(container)) {
13✔
165
            auto access_node = dynamic_cast<data_flow::AccessNode*>(user->element());
3✔
166
            if (access_node == nullptr) {
3✔
167
                continue;
×
168
            }
169
            for (auto& memlet : access_node->get_parent().in_edges(*access_node)) {
7✔
170
                auto base_type = &memlet.base_type();
4✔
171
                if (base_type->type_id() == types::TypeID::Pointer) {
4✔
172
                    auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
4✔
173
                    if (!pointer_type->has_pointee_type()) {
4✔
174
                        continue;
×
175
                    }
176
                } else if (base_type->type_id() == types::TypeID::Structure) {
4✔
NEW
177
                    continue;
×
178
                }
179

180
                if (memlet.type() == data_flow::MemletType::Dereference_Src) {
4✔
181
                    if (base_type->type_id() == types::TypeID::Pointer) {
2✔
182
                        auto pointer_type = dynamic_cast<const types::Pointer*>(base_type);
2✔
183
                        base_type = &pointer_type->pointee_type();
2✔
184

185
                    } /* else if (base_type->type_id() == types::TypeID::Array) {
2✔
186
                        auto array_type = dynamic_cast<const types::Array*>(base_type);
187
                        base_type = &array_type->element_type();
188
                    } */
189

190
                    if (base_type->type_id() == types::TypeID::Pointer) {
2✔
191
                        auto inner_pointer_type = dynamic_cast<const types::Pointer*>(base_type);
2✔
192
                        if (!inner_pointer_type->has_pointee_type()) {
2✔
193
                            continue;
×
194
                        }
195
                    }
2✔
196
                }
2✔
197
                if (this->type_map_.find(container) == this->type_map_.end()) {
4✔
198
                    this->type_map_.insert({container, base_type});
2✔
199
                    continue;
2✔
200
                }
201
            }
202
        }
203
    }
10✔
204
}
8✔
205

206
TypeAnalysis::TypeAnalysis(StructuredSDFG& sdfg) : Analysis(sdfg) {}
8✔
207

208
const sdfg::types::IType* TypeAnalysis::get_outer_type(const std::string& container) const {
28✔
209
    auto& contType = sdfg_.type(container);
28✔
210
    if (contType.type_id() == sdfg::types::TypeID::Pointer) {
28✔
211
        auto pointer_type = static_cast<const sdfg::types::Pointer*>(&contType);
22✔
212
        if (pointer_type->has_pointee_type()) {
22✔
213
            return pointer_type;
2✔
214
        }
215
    } else if (contType.type_id() == sdfg::types::TypeID::Structure &&
26✔
NEW
216
               static_cast<const types::Structure&>(contType).is_pointer_like()) {
×
UNCOV
217
    } else {
×
218
        return &contType;
6✔
219
    }
220

221
    auto it = type_map_.find(container);
20✔
222
    if (it != type_map_.end()) {
20✔
223
        return it->second;
20✔
224
    }
225
    return nullptr;
×
226
}
28✔
227

228
} // namespace analysis
229
} // 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