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

daisytuner / sdfglib / 18685751061

21 Oct 2025 01:38PM UTC coverage: 61.158% (+0.2%) from 60.927%
18685751061

push

github

web-flow
Merge pull request #290 from daisytuner/storage-types

utilizes storage type for allocations of variables

71 of 117 new or added lines in 6 files covered. (60.68%)

157 existing lines in 6 files now uncovered.

9337 of 15267 relevant lines covered (61.16%)

92.73 hits per line

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

81.63
/src/codegen/code_generators/c_code_generator.cpp
1
#include "sdfg/codegen/code_generators/c_code_generator.h"
2

3
#include "sdfg/analysis/analysis.h"
4
#include "sdfg/analysis/users.h"
5
#include "sdfg/codegen/dispatchers/node_dispatcher_registry.h"
6
#include "sdfg/codegen/instrumentation/capture_var_plan.h"
7
#include "sdfg/codegen/instrumentation/instrumentation_plan.h"
8

9
namespace sdfg {
10
namespace codegen {
11

12
std::string CCodeGenerator::function_definition() {
1✔
13
    /********** Arglist **********/
14
    std::vector<std::string> args;
1✔
15
    for (auto& container : sdfg_.arguments()) {
1✔
16
        args.push_back(language_extension_.declaration(container, sdfg_.type(container)));
×
17
    }
18
    std::stringstream arglist;
1✔
19
    arglist << sdfg::helpers::join(args, ", ");
1✔
20
    std::string arglist_str = arglist.str();
1✔
21
    if (arglist_str.empty()) {
1✔
22
        arglist_str = "void";
1✔
23
    }
1✔
24

25
    return "extern " + this->language_extension_.declaration("", sdfg_.return_type()) + sdfg_.name() + "(" +
2✔
26
           arglist_str + ")";
1✔
27
};
1✔
28

29
void CCodeGenerator::emit_capture_context_init(std::ostream& ofs_source) const {
1✔
30
    std::string name = sdfg_.name();
1✔
31
    std::string arg_capture_path = sdfg_.metadata().at("arg_capture_path");
1✔
32

33
    ofs_source << "static void* __capture_ctx;" << std::endl;
1✔
34
    ofs_source << "static void __attribute__((constructor(1000))) __capture_ctx_init(void) {" << std::endl;
1✔
35
    ofs_source << "\t__capture_ctx = __daisy_capture_init(\"" << name << "\", \"" << arg_capture_path << "\");"
1✔
36
               << std::endl;
1✔
37
    ofs_source << "}" << std::endl;
1✔
38
    ofs_source << std::endl;
1✔
39
}
1✔
40

41
void CCodeGenerator::dispatch_includes() {
10✔
42
    this->includes_stream_ << "#include <math.h>" << std::endl;
10✔
43
    this->includes_stream_ << "#include <alloca.h>" << std::endl;
10✔
44
    this->includes_stream_ << "#include <stdbool.h>" << std::endl;
10✔
45
    this->includes_stream_ << "#include <stdio.h>" << std::endl;
10✔
46
    this->includes_stream_ << "#include <stdlib.h>" << std::endl;
10✔
47
    this->includes_stream_ << "#include <string.h>" << std::endl;
10✔
48
    this->includes_stream_ << "#include <cblas.h>" << std::endl;
10✔
49
    this->includes_stream_ << "#include <daisy_rtl/daisy_rtl.h>" << std::endl;
10✔
50
};
10✔
51

52
void CCodeGenerator::dispatch_structures() {
10✔
53
    // Forward declarations
54
    for (auto& structure : sdfg_.structures()) {
13✔
55
        this->classes_stream_ << "typedef struct " << structure << " " << structure << ";" << std::endl;
3✔
56
    }
57

58
    // Generate topology-sorted structure definitions
59
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS> structures_graph;
60
    typedef boost::graph_traits<structures_graph>::vertex_descriptor Vertex;
61
    std::vector<std::string> names;
10✔
62
    for (auto& structure : sdfg_.structures()) {
13✔
63
        names.push_back(structure);
3✔
64
    }
65
    structures_graph graph(names.size());
10✔
66

67
    for (auto& structure : names) {
13✔
68
        auto& definition = sdfg_.structure(structure);
3✔
69
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
70
            auto member_type = &definition.member_type(symbolic::integer(i));
3✔
71
            while (dynamic_cast<const types::Array*>(member_type)) {
3✔
72
                auto array_type = static_cast<const types::Array*>(member_type);
×
73
                member_type = &array_type->element_type();
×
74
            }
75

76
            if (auto member_structure = dynamic_cast<const sdfg::types::Structure*>(member_type)) {
3✔
77
                boost::add_edge(
1✔
78
                    std::find(names.begin(), names.end(), member_structure->name()) - names.begin(),
1✔
79
                    std::find(names.begin(), names.end(), structure) - names.begin(),
1✔
80
                    graph
81
                );
82
            }
1✔
83
        }
3✔
84
    }
85

86
    std::list<Vertex> order;
10✔
87
    std::unordered_map<Vertex, boost::default_color_type> vertex_colors;
10✔
88
    boost::topological_sort(
10✔
89
        graph, std::back_inserter(order), boost::color_map(boost::make_assoc_property_map(vertex_colors))
10✔
90
    );
91
    order.reverse();
10✔
92

93
    for (auto& structure_index : order) {
13✔
94
        std::string structure = names.at(structure_index);
3✔
95
        auto& definition = sdfg_.structure(structure);
3✔
96
        this->classes_stream_ << "typedef struct ";
3✔
97
        if (definition.is_packed()) {
3✔
98
            this->classes_stream_ << "__attribute__((packed)) ";
×
99
        }
×
100
        this->classes_stream_ << structure << std::endl;
3✔
101
        this->classes_stream_ << "{\n";
3✔
102

103
        for (size_t i = 0; i < definition.num_members(); i++) {
6✔
104
            auto& member_type = definition.member_type(symbolic::integer(i));
3✔
105
            if (auto pointer_type = dynamic_cast<const sdfg::types::Pointer*>(&member_type)) {
3✔
106
                if (pointer_type->has_pointee_type() &&
×
107
                    dynamic_cast<const sdfg::types::Structure*>(&pointer_type->pointee_type())) {
×
108
                    this->classes_stream_ << "struct ";
×
109
                }
×
110
            }
×
111
            this->classes_stream_
6✔
112
                << language_extension_.declaration("member_" + std::to_string(i), member_type, false, true);
3✔
113
            this->classes_stream_ << ";" << std::endl;
3✔
114
        }
3✔
115

116
        this->classes_stream_ << "} " << structure << ";" << std::endl;
3✔
117
    }
3✔
118
};
10✔
119

120
void CCodeGenerator::dispatch_globals() {
10✔
121
    // Declare globals
122
    for (auto& container : sdfg_.externals()) {
11✔
123
        // Function declarations
124
        if (dynamic_cast<const types::Function*>(&sdfg_.type(container))) {
1✔
125
            // Declare function
126
            this->globals_stream_ << "extern ";
×
127
            this->globals_stream_
×
128
                << language_extension_.declaration(this->externals_prefix_ + container, sdfg_.type(container)) << ";"
×
129
                << std::endl;
×
130
            continue;
×
131
        }
132

133
        // Other types must be pointers
134
        auto& type = dynamic_cast<const types::Pointer&>(sdfg_.type(container));
1✔
135
        assert(type.has_pointee_type() && "Externals must have a pointee type");
2✔
136
        auto& base_type = type.pointee_type();
1✔
137

138
        if (sdfg_.linkage_type(container) == LinkageType_External) {
1✔
139
            this->globals_stream_ << "extern "
2✔
140
                                  << language_extension_.declaration(this->externals_prefix_ + container, base_type)
1✔
141
                                  << ";" << std::endl;
1✔
142
        } else {
1✔
143
            this->globals_stream_ << "static "
×
144
                                  << language_extension_.declaration(this->externals_prefix_ + container, base_type);
×
145
            if (!type.initializer().empty()) {
×
146
                this->globals_stream_ << " = " << type.initializer();
×
147
            }
×
148
            this->globals_stream_ << ";" << std::endl;
×
149
        }
150
    }
151
};
10✔
152

153
void CCodeGenerator::dispatch_schedule() {
10✔
154
    // Allocate variables
155
    for (auto& container : sdfg_.containers()) {
18✔
156
        if (sdfg_.is_external(container)) {
8✔
157
            continue;
1✔
158
        }
159
        auto& type = sdfg_.type(container);
7✔
160

161
        // Declare transient
162
        if (sdfg_.is_transient(container)) {
7✔
163
            std::string val = this->language_extension_.declaration(container, sdfg_.type(container), false, true);
3✔
164
            if (!val.empty()) {
3✔
165
                this->main_stream_ << val;
3✔
166
                this->main_stream_ << ";" << std::endl;
3✔
167
            }
3✔
168
        }
3✔
169

170
        // Allocate if needed
171
        if (type.storage_type().is_cpu_stack()) {
7✔
172
            if (type.storage_type().allocation_size().is_null()) {
2✔
173
                continue;
2✔
174
            }
NEW
175
            this->main_stream_ << container << " = ";
×
NEW
176
            this->main_stream_ << this->language_extension_.type_cast("", type);
×
NEW
177
            this->main_stream_ << "alloca("
×
NEW
178
                               << this->language_extension_.expression(type.storage_type().allocation_size()) << ")";
×
179
            this->main_stream_ << ";" << std::endl;
×
180
        } else if (type.storage_type().is_cpu_heap()) {
5✔
181
            if (type.storage_type().allocation_size().is_null()) {
5✔
182
                continue;
1✔
183
            }
184
            this->main_stream_ << container << " = ";
4✔
185
            this->main_stream_ << this->language_extension_.type_cast("", type);
4✔
186
            this->main_stream_ << "malloc("
8✔
187
                               << this->language_extension_.expression(type.storage_type().allocation_size()) << ")";
4✔
188
            this->main_stream_ << ";" << std::endl;
4✔
189
        } else {
4✔
NEW
190
            assert(false && "Only CPU_Stack and CPU_Heap storage types are supported in C codegen");
×
191
        }
192
    }
193

194
    auto dispatcher = create_dispatcher(language_extension_, sdfg_, sdfg_.root(), instrumentation_plan_);
10✔
195
    dispatcher->dispatch(this->main_stream_, this->globals_stream_, this->library_snippet_factory_);
10✔
196

197
    // Free heap allocations
198
    for (auto& container : sdfg_.containers()) {
18✔
199
        if (sdfg_.is_external(container)) {
8✔
200
            continue;
1✔
201
        }
202
        auto& type = sdfg_.type(container);
7✔
203

204
        // Free if needed
205
        if (type.storage_type().is_cpu_heap()) {
7✔
206
            if (type.storage_type().allocation_lifetime() == types::StorageType::AllocationLifetime::Lifetime_SDFG) {
5✔
207
                this->main_stream_ << "free(" << container << ");" << std::endl;
3✔
208
            }
3✔
209
        }
5✔
210
    }
211
};
10✔
212

213
} // namespace codegen
214
} // 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