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

daisytuner / sdfglib / 18187030480

02 Oct 2025 08:00AM UTC coverage: 61.116% (+0.05%) from 61.068%
18187030480

push

github

web-flow
Merge pull request #258 from daisytuner/debug-print-macro

adds macro for debug prints

0 of 16 new or added lines in 5 files covered. (0.0%)

10 existing lines in 2 files now uncovered.

9569 of 15657 relevant lines covered (61.12%)

111.31 hits per line

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

63.11
/src/codegen/code_generator.cpp
1
#include "sdfg/codegen/code_generator.h"
2
#include <symengine/constants.h>
3
#include <symengine/dict.h>
4
#include <symengine/number.h>
5
#include "sdfg/analysis/analysis.h"
6
#include "sdfg/analysis/mem_access_range_analysis.h"
7
#include "sdfg/analysis/type_analysis.h"
8
#include "sdfg/codegen/instrumentation/capture_var_plan.h"
9
#include "sdfg/helpers/helpers.h"
10
#include "sdfg/symbolic/symbolic.h"
11
#include "sdfg/types/structure.h"
12

13
namespace sdfg {
14
namespace codegen {
15

16
std::tuple<int, types::PrimitiveType> CodeGenerator::analyze_type_rec(
5✔
17
    symbolic::Expression* dims,
18
    int max_dim,
19
    int dim_idx,
20
    const types::IType& type,
21
    int arg_idx,
22
    const analysis::MemAccessRange* range,
23
    analysis::AnalysisManager& analysis_manager,
24
    const StructuredSDFG& sdfg,
25
    std::string var_name
26
) {
27
    if (dim_idx > max_dim) {
5✔
NEW
28
        DEBUG_PRINTLN(
×
29
            "In '" << sdfg_.name() << "', arg" << arg_idx << ": data nesting deeper than " << max_dim << ", ignoring"
30
        );
UNCOV
31
        return std::make_tuple(-1, types::Void);
×
32
    }
33

34
    if (auto* scalarType = dynamic_cast<const types::Scalar*>(&type)) {
5✔
35
        return std::make_tuple(dim_idx, scalarType->primitive_type());
3✔
36
    } else if (auto structureType = dynamic_cast<const sdfg::types::Structure*>(&type)) {
2✔
37
        return std::make_tuple(dim_idx, types::Void);
×
38
    } else if (auto* arrayType = dynamic_cast<const types::Array*>(&type)) {
2✔
39
        dims[dim_idx] = arrayType->num_elements();
1✔
40
        auto& inner = arrayType->element_type();
1✔
41

42
        return analyze_type_rec(dims, max_dim, dim_idx + 1, inner, arg_idx, range, analysis_manager, sdfg, var_name);
1✔
43
    } else if (auto* ptrType = dynamic_cast<const types::Pointer*>(&type)) {
1✔
44
        if (!range || range->is_undefined()) {
1✔
NEW
45
            DEBUG_PRINTLN(
×
46
                "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx << ": missing range, cannot capture!"
47
            );
UNCOV
48
            return std::make_tuple(-2, types::Void);
×
49
        }
50
        if (range->dims().size() <= dim_idx) {
1✔
NEW
51
            DEBUG_PRINTLN(
×
52
                "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx
53
                       << ": missing dimension in range, cannot capture!"
54
            );
UNCOV
55
            return std::make_tuple(-2, types::Void);
×
56
        }
57
        const auto& dim = range->dims().at(dim_idx);
1✔
58
        if (!symbolic::eq(dim.first, symbolic::zero())) {
1✔
NEW
59
            DEBUG_PRINTLN(
×
60
                "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx << ": has upper bound "
61
                       << dim.second->__str__() << ", but does not start at 0, cannot capture"
62
            );
UNCOV
63
            return std::make_tuple(-2, types::Void);
×
64
        }
65

66
        dims[dim_idx] = symbolic::add(dim.second, symbolic::one());
1✔
67
        const types::IType* inner = nullptr;
1✔
68
        if (ptrType->has_pointee_type()) {
1✔
69
            inner = &(ptrType->pointee_type());
1✔
70
        } else {
1✔
71
            if (dim_idx > 0) {
×
NEW
72
                DEBUG_PRINTLN(
×
73
                    "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx
74
                           << ": missing pointee type for dim > 0, cannot capture!"
75
                );
UNCOV
76
                return std::make_tuple(-2, types::Void);
×
77
            } else {
78
                auto& type_analysis = analysis_manager.get<analysis::TypeAnalysis>();
×
79
                auto outer = type_analysis.get_outer_type(var_name);
×
80
                if (outer != nullptr) {
×
81
                    if (auto* ptrType_new = dynamic_cast<const types::Pointer*>(outer)) {
×
82
                        if (ptrType_new->has_pointee_type()) {
×
83
                            inner = &(ptrType_new->pointee_type());
×
84
                        } else {
×
NEW
85
                            DEBUG_PRINTLN(
×
86
                                "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx
87
                                       << ": missing pointee type, cannot capture!"
88
                            );
UNCOV
89
                            return std::make_tuple(-2, types::Void);
×
90
                        }
91
                    }
×
92
                } else {
×
NEW
93
                    DEBUG_PRINTLN(
×
94
                        "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx
95
                               << ": could not infer type from container, cannot capture!"
96
                    );
UNCOV
97
                    return std::make_tuple(-2, types::Void);
×
98
                }
99
            }
100
            if (inner == nullptr) {
×
NEW
101
                DEBUG_PRINTLN(
×
102
                    "In '" << sdfg_.name() << "', arg" << arg_idx << " dim" << dim_idx
103
                           << ": could not infer type from container, cannot capture!"
104
                );
UNCOV
105
                return std::make_tuple(-2, types::Void);
×
106
            }
107
        }
108

109
        return analyze_type_rec(dims, max_dim, dim_idx + 1, *inner, arg_idx, range, analysis_manager, sdfg, var_name);
1✔
110
    }
111

NEW
112
    DEBUG_PRINTLN(
×
113
        "In '" << sdfg_.name() << "', arg" << arg_idx << ": unsupported type " << type.print() << ", cannot capture!"
114
    );
UNCOV
115
    return std::make_tuple(-1, types::Void);
×
116
}
5✔
117

118
bool CodeGenerator::add_capture_plan(
3✔
119
    const std::string& var_name,
120
    int arg_idx,
121
    bool is_external,
122
    std::vector<CaptureVarPlan>& plan,
123
    const analysis::MemAccessRanges& ranges
124
) {
125
    const types::IType* type = nullptr;
3✔
126
    if (is_external) {
3✔
127
        auto& pointer_type = dynamic_cast<const types::Pointer&>(sdfg_.type(var_name));
1✔
128
        assert(pointer_type.has_pointee_type() && "Externals must have a pointee type");
2✔
129
        type = &pointer_type.pointee_type();
1✔
130
    } else {
1✔
131
        type = &sdfg_.type(var_name);
2✔
132
    }
133

134
    const auto* range = ranges.get(var_name);
3✔
135

136
    analysis::AnalysisManager analysis_manager(sdfg_);
3✔
137

138
    symbolic::Expression dims[3];
9✔
139

140
    int dim_count = 0;
3✔
141
    types::PrimitiveType inner_type;
142

143
    std::tie(dim_count, inner_type) =
3✔
144
        analyze_type_rec(dims, 3, 0, *type, arg_idx, range, analysis_manager, sdfg_, var_name);
3✔
145

146
    bool is_read = range ? range->saw_read() : true;
3✔
147
    bool is_written = range ? range->saw_write() : true;
3✔
148

149
    if (dim_count == 0) {
3✔
150
        plan.emplace_back(
4✔
151
            is_read || is_written, is_written && is_external, CaptureVarType::CapRaw, arg_idx, is_external, inner_type
2✔
152
        );
153
    } else if (dim_count == 1) {
3✔
154
        plan.emplace_back(is_read, is_written, CaptureVarType::Cap1D, arg_idx, is_external, inner_type, dims[0]);
×
155
    } else if (dim_count == 2) {
1✔
156
        plan.emplace_back(is_read, is_written, CaptureVarType::Cap2D, arg_idx, is_external, inner_type, dims[0], dims[1]);
1✔
157
    } else if (dim_count == 3) {
1✔
158
        plan.emplace_back(
×
159
            is_read, is_written, CaptureVarType::Cap3D, arg_idx, is_external, inner_type, dims[0], dims[1], dims[2]
×
160
        );
161
    } else {
×
162
        return false;
×
163
    }
164

165
    return true;
3✔
166
}
3✔
167

168
std::unique_ptr<std::vector<CaptureVarPlan>> CodeGenerator::create_capture_plans() {
1✔
169
    auto name = sdfg_.name();
1✔
170

171
    analysis::AnalysisManager analysis_manager(sdfg_);
1✔
172
    const auto& args = sdfg_.arguments();
1✔
173
    auto& exts = sdfg_.externals();
1✔
174
    const auto& ranges = analysis_manager.get<analysis::MemAccessRanges>();
1✔
175

176
    auto plan = std::make_unique<std::vector<CaptureVarPlan>>();
1✔
177

178
    bool working = true;
1✔
179

180
    int arg_idx = -1;
1✔
181
    for (auto& arg_name : args) {
3✔
182
        ++arg_idx;
2✔
183

184
        working &= add_capture_plan(arg_name, arg_idx, false, *plan.get(), ranges);
2✔
185
    }
186

187
    for (auto& arg_name : exts) {
2✔
188
        if (sdfg_.type(arg_name).type_id() == types::TypeID::Function) {
1✔
189
            continue;
×
190
        }
191
        ++arg_idx;
1✔
192

193
        working &= add_capture_plan(arg_name, arg_idx, true, *plan.get(), ranges);
1✔
194
    }
195

196
    if (!working) {
1✔
NEW
197
        DEBUG_PRINTLN("In '" << name << "': could not create capture plan, returning empty plan");
×
198
        return std::make_unique<std::vector<CaptureVarPlan>>();
×
199
    }
200

201
    return plan;
1✔
202
}
1✔
203

204
} // namespace codegen
205
} // 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