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

daisytuner / sdfglib / 18186882603

02 Oct 2025 07:52AM UTC coverage: 61.116% (+0.05%) from 61.068%
18186882603

Pull #258

github

web-flow
Merge 0fbf718f8 into a12f62888
Pull Request #258: 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

82.98
/src/types/utils.cpp
1
#include "sdfg/types/utils.h"
2
#include <iostream>
3
#include <memory>
4
#include <string>
5

6
#include "sdfg/codegen/utils.h"
7
#include "sdfg/function.h"
8
#include "sdfg/helpers/helpers.h"
9
#include "sdfg/symbolic/symbolic.h"
10

11
#include "sdfg/codegen/language_extensions/c_language_extension.h"
12
#include "sdfg/types/type.h"
13

14
namespace sdfg {
15
namespace types {
16

17
const types::IType&
18
infer_type_internal(const sdfg::Function& function, const types::IType& type, const data_flow::Subset& subset) {
1,355✔
19
    if (subset.empty()) {
1,355✔
20
        return type;
706✔
21
    }
22

23
    if (type.type_id() == TypeID::Scalar) {
649✔
24
        if (!subset.empty()) {
×
25
            throw InvalidSDFGException("Scalar type must have no subset");
×
26
        }
27

28
        return type;
×
29
    } else if (type.type_id() == TypeID::Array) {
649✔
30
        auto& array_type = static_cast<const types::Array&>(type);
648✔
31

32
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
648✔
33
        return infer_type_internal(function, array_type.element_type(), element_subset);
648✔
34
    } else if (type.type_id() == TypeID::Structure) {
649✔
35
        auto& structure_type = static_cast<const types::Structure&>(type);
1✔
36

37
        auto& definition = function.structure(structure_type.name());
1✔
38

39
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
1✔
40
        auto member = SymEngine::rcp_dynamic_cast<const SymEngine::Integer>(subset.at(0));
1✔
41
        return infer_type_internal(function, definition.member_type(member), element_subset);
1✔
42
    } else if (type.type_id() == TypeID::Pointer) {
1✔
43
        throw InvalidSDFGException("Subset references non-contiguous memory");
×
44
    }
45

46
    throw InvalidSDFGException("Type inference failed because of unknown type");
×
47
};
1,355✔
48

49
const types::IType& infer_type(const sdfg::Function& function, const types::IType& type, const data_flow::Subset& subset) {
1,625✔
50
    if (subset.empty()) {
1,625✔
51
        return type;
919✔
52
    }
53

54
    if (type.type_id() == TypeID::Pointer) {
706✔
55
        auto& pointer_type = static_cast<const types::Pointer&>(type);
361✔
56
        if (!pointer_type.has_pointee_type()) {
361✔
57
            throw InvalidSDFGException("Opaque pointer with non-empty subset");
×
58
        }
59

60
        auto& pointee_type = pointer_type.pointee_type();
361✔
61
        data_flow::Subset element_subset(subset.begin() + 1, subset.end());
361✔
62
        return infer_type_internal(function, pointee_type, element_subset);
361✔
63
    } else {
361✔
64
        return infer_type_internal(function, type, subset);
345✔
65
    }
66
};
1,625✔
67

68
std::unique_ptr<types::IType> recombine_array_type(const types::IType& type, uint depth, const types::IType& inner_type) {
21✔
69
    if (depth == 0) {
21✔
70
        return inner_type.clone();
9✔
71
    } else {
72
        if (auto atype = dynamic_cast<const types::Array*>(&type)) {
12✔
73
            return std::make_unique<types::Array>(
12✔
74
                atype->storage_type(),
12✔
75
                atype->alignment(),
12✔
76
                atype->initializer(),
12✔
77
                *recombine_array_type(atype->element_type(), depth - 1, inner_type).get(),
12✔
78
                atype->num_elements()
12✔
79
            );
80
        } else {
81
            throw std::runtime_error("construct_type: Non array types are not supported yet!");
×
82
        }
83
    }
84
};
21✔
85

86
const IType& peel_to_innermost_element(const IType& type, int follow_ptr) {
13✔
87
    int next_follow = follow_ptr;
13✔
88
    if (follow_ptr == PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR) {
13✔
89
        next_follow = 0; // only follow an outermost pointer
5✔
90
    }
5✔
91

92
    switch (type.type_id()) {
13✔
93
        case TypeID::Array:
94
            return peel_to_innermost_element(dynamic_cast<const types::Array&>(type).element_type(), next_follow);
3✔
95
        case TypeID::Reference:
96
            return peel_to_innermost_element(dynamic_cast<const codegen::Reference&>(type).reference_type(), next_follow);
×
97
        case TypeID::Pointer:
98
            if (follow_ptr != 0) {
6✔
99
                if (follow_ptr != PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR) {
5✔
100
                    next_follow = follow_ptr - 1; // follow one less pointer
×
101
                }
×
102

103
                auto& pointer_type = dynamic_cast<const types::Pointer&>(type);
5✔
104
                if (pointer_type.has_pointee_type()) {
5✔
105
                    return peel_to_innermost_element(pointer_type.pointee_type(), next_follow);
5✔
106
                } else {
107
                    return type;
×
108
                }
109
            }
110
            // fall back to cut-off if we did not follow the pointer
111
        default:
112
            return type;
5✔
113
    }
114
}
13✔
115

116
symbolic::Expression get_contiguous_element_size(const types::IType& type, bool allow_comp_time_eval) {
5✔
117
    // need to peel explicitly, primitive_type() would follow ALL pointers, even ***, even though this is not contiguous
118
    auto& innermost = peel_to_innermost_element(type, PEEL_TO_INNERMOST_ELEMENT_FOLLOW_ONLY_OUTER_PTR);
5✔
119

120
    return get_type_size(innermost, allow_comp_time_eval);
5✔
121
}
122

123
symbolic::Expression get_type_size(const types::IType& type, bool allow_comp_time_eval) {
11✔
124
    bool only_symbolic = false;
11✔
125

126
    auto id = type.type_id();
11✔
127
    if (id == TypeID::Pointer || id == TypeID::Reference || id == TypeID::Function) {
11✔
128
        return symbolic::integer(8); // assume 64-bit pointers
2✔
129
    } else if (id == TypeID::Structure) {
9✔
130
        // TODO if we have the target definition, we could evaluate the StructureDefinition to a size
131
        only_symbolic = true;
5✔
132
    } else if (id == TypeID::Array) {
9✔
133
        auto& arr = dynamic_cast<const types::Array&>(type);
1✔
134
        auto inner_element_size = get_type_size(arr.element_type(), allow_comp_time_eval);
1✔
135
        if (!inner_element_size.is_null()) {
1✔
136
            return symbolic::mul(inner_element_size, arr.num_elements());
1✔
137
        } else {
138
            return {};
×
139
        }
140
    }
1✔
141

142
    if (only_symbolic) {
8✔
143
        // Could not statically figure out the size
144
        // Could be struct we could evaluate by its definition or sth. we do not understand here
145
        if (allow_comp_time_eval) {
5✔
146
            return symbolic::size_of_type(type);
4✔
147
        } else { // size unknown
148
            return {};
1✔
149
        }
150
    } else { // should just be a primitive type
151
        auto prim_type = type.primitive_type();
3✔
152

153
        long size_of_type = static_cast<long>(types::bit_width(prim_type)) / 8;
3✔
154
        if (size_of_type != 0) {
3✔
155
            return symbolic::integer(size_of_type);
3✔
156
        } else {
157
            codegen::CLanguageExtension lang;
×
NEW
158
            DEBUG_PRINTLN(
×
159
                "Unexpected primitive_type " << primitive_type_to_string(prim_type) << " of "
160
                                             << lang.declaration("", type) << ", unknown size"
161
            );
162
            return {};
×
163
        }
×
164
    }
165
}
11✔
166

167
} // namespace types
168
} // 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