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

daisytuner / sdfglib / 17117704192

21 Aug 2025 05:09AM UTC coverage: 61.329% (-4.2%) from 65.536%
17117704192

Pull #200

github

web-flow
Merge 4222c2d61 into a4938ca29
Pull Request #200: Type inference as analysis

97 of 130 new or added lines in 2 files covered. (74.62%)

256 existing lines in 7 files now uncovered.

9349 of 15244 relevant lines covered (61.33%)

119.41 hits per line

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

57.14
/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/symbolic/symbolic.h"
10
#include "sdfg/types/structure.h"
11

12
namespace sdfg {
13
namespace codegen {
14

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

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

40
        return analyze_type_rec(dims, maxDim, dimIdx + 1, inner, argIdx, range, analysis_manager, sdfg, var_name);
1✔
41
    } else if (auto* ptrType = dynamic_cast<const types::Pointer*>(&type)) {
2✔
42
        if (range && !range->is_undefined()) {
2✔
43
            const auto& dim = range->dims()[dimIdx];
2✔
44

45
            if (symbolic::eq(symbolic::zero(), dim.first)) {
2✔
46
                dims[dimIdx] = symbolic::add(dim.second, symbolic::one());
2✔
47
                const types::IType* inner = nullptr;
2✔
48
                if (ptrType->has_pointee_type()) {
2✔
49
                    inner = &(ptrType->pointee_type());
2✔
50
                } else {
2✔
51
                    if (dimIdx > 0) {
×
52
                        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
53
                                  << ": missing pointee type for dim > 0, cannot capture!" << std::endl;
×
54
                        return std::make_tuple(-2, types::Void);
×
55
                    } else {
NEW
56
                        auto& type_analysis = analysis_manager.get<analysis::TypeAnalysis>();
×
NEW
57
                        auto outer = type_analysis.get_outer_type(var_name);
×
58
                        if (outer != nullptr) {
×
59
                            if (auto* ptrType_new = dynamic_cast<const types::Pointer*>(outer)) {
×
60
                                if (ptrType_new->has_pointee_type()) {
×
61
                                    inner = &(ptrType_new->pointee_type());
×
62
                                } else {
×
63
                                    std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
64
                                              << ": missing pointee type, cannot capture!" << std::endl;
×
65
                                    return std::make_tuple(-2, types::Void);
×
66
                                }
67
                            }
×
68
                        } else {
×
69
                            std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
70
                                      << ": could not infer type from container, cannot capture!" << std::endl;
×
71
                            return std::make_tuple(-2, types::Void);
×
72
                        }
73
                    }
74
                    if (inner == nullptr) {
×
75
                        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
76
                                  << ": could not infer type from container, cannot capture!" << std::endl;
×
77
                        return std::make_tuple(-2, types::Void);
×
78
                    }
79
                }
80

81
                return analyze_type_rec(dims, maxDim, dimIdx + 1, *inner, argIdx, range, analysis_manager, sdfg, var_name);
2✔
82
            } else {
83
                std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx << ": has upper bound "
×
84
                          << dim.second->__str__() << ", but does not start at 0, cannot capture" << std::endl;
×
85
                return std::make_tuple(-2, types::Void);
×
86
            }
87
        } else {
88
            std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << " dim" << dimIdx
×
89
                      << ": missing range, cannot capture!" << std::endl;
×
90
            return std::make_tuple(-2, types::Void);
×
91
        }
92
    } else {
93
        std::cerr << "In '" << sdfg_.name() << "', arg" << argIdx << ": unsupported type " << type.print()
×
94
                  << ", cannot capture!" << std::endl;
×
95
        return std::make_tuple(-1, types::Void);
×
96
    }
97
}
7✔
98

99
bool CodeGenerator::add_capture_plan(
4✔
100
    const std::string& varName,
101
    int argIdx,
102
    bool isExternal,
103
    std::vector<CaptureVarPlan>& plan,
104
    const analysis::MemAccessRanges& ranges
105
) {
106
    auto& type = sdfg_.type(varName);
4✔
107

108
    const auto* range = ranges.get(varName);
4✔
109

110
    analysis::AnalysisManager analysis_manager(sdfg_);
4✔
111

112
    symbolic::Expression dims[3];
12✔
113

114
    int dimCount = 0;
4✔
115
    types::PrimitiveType innerPrim;
116

117
    std::tie(dimCount, innerPrim) = analyze_type_rec(dims, 3, 0, type, argIdx, range, analysis_manager, sdfg_, varName);
4✔
118

119
    bool isRead = range ? range->saw_read() : true;
4✔
120
    bool isWritten = range ? range->saw_write() : true;
4✔
121

122
    if (dimCount == 0) {
4✔
123
        plan.emplace_back(isRead, false, CaptureVarType::CapRaw, argIdx, isExternal, innerPrim);
2✔
124
    } else if (dimCount == 1) {
4✔
125
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap1D, argIdx, isExternal, innerPrim, dims[0]);
1✔
126
    } else if (dimCount == 2) {
2✔
127
        plan.emplace_back(isRead, isWritten, CaptureVarType::Cap2D, argIdx, isExternal, innerPrim, dims[0], dims[1]);
1✔
128
    } else if (dimCount == 3) {
1✔
129
        plan.emplace_back(
×
130
            isRead, isWritten, CaptureVarType::Cap3D, argIdx, isExternal, innerPrim, dims[0], dims[1], dims[2]
×
131
        );
132
    } else {
×
133
        return false;
×
134
    }
135

136
    return true;
4✔
137
}
4✔
138

139
std::unique_ptr<std::vector<CaptureVarPlan>> CodeGenerator::create_capture_plans() {
1✔
140
    auto name = sdfg_.name();
1✔
141

142
    analysis::AnalysisManager analysis_manager(sdfg_);
1✔
143
    const auto& args = sdfg_.arguments();
1✔
144
    auto& exts = sdfg_.externals();
1✔
145
    const auto& ranges = analysis_manager.get<analysis::MemAccessRanges>();
1✔
146

147
    auto plan = std::make_unique<std::vector<CaptureVarPlan>>();
1✔
148

149
    bool working = true;
1✔
150

151
    int argIdx = -1;
1✔
152
    for (auto& argName : args) {
3✔
153
        ++argIdx;
2✔
154

155
        working &= add_capture_plan(argName, argIdx, false, *plan.get(), ranges);
2✔
156
    }
157

158
    for (auto& argName : exts) {
3✔
159
        ++argIdx;
2✔
160

161
        working &= add_capture_plan(argName, argIdx, true, *plan.get(), ranges);
2✔
162
    }
163

164
    if (!working) {
1✔
165
        std::cerr << "In '" << name << "': could not create capture plan, returning empty plan" << std::endl;
×
166
        return std::make_unique<std::vector<CaptureVarPlan>>();
×
167
    }
168

169
    return plan;
1✔
170
}
1✔
171

172
} // namespace codegen
173
} // 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