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

daisytuner / sdfglib / 17907551353

22 Sep 2025 07:12AM UTC coverage: 60.192% (-0.5%) from 60.653%
17907551353

push

github

web-flow
Merge pull request #233 from daisytuner/returns

adds constant returns with type and extends API

60 of 184 new or added lines in 10 files covered. (32.61%)

19 existing lines in 5 files now uncovered.

9514 of 15806 relevant lines covered (60.19%)

105.75 hits per line

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

45.1
/src/passes/structured_control_flow/dead_cfg_elimination.cpp
1
#include "sdfg/passes/structured_control_flow/dead_cfg_elimination.h"
2

3
#include "sdfg/structured_control_flow/structured_loop.h"
4

5
namespace sdfg {
6
namespace passes {
7

8
bool DeadCFGElimination::is_dead(const structured_control_flow::ControlFlowNode& node) {
15✔
9
    if (auto block_stmt = dynamic_cast<const structured_control_flow::Block*>(&node)) {
15✔
10
        return (block_stmt->dataflow().nodes().size() == 0);
8✔
11
    } else if (auto sequence_stmt = dynamic_cast<const structured_control_flow::Sequence*>(&node)) {
7✔
12
        return (sequence_stmt->size() == 0);
×
13
    } else if (auto if_else_stmt = dynamic_cast<const structured_control_flow::IfElse*>(&node)) {
7✔
14
        return (if_else_stmt->size() == 0);
×
15
    } else if (auto while_stmt = dynamic_cast<const structured_control_flow::While*>(&node)) {
7✔
16
        return is_dead(while_stmt->root());
×
17
    } else if (dynamic_cast<const structured_control_flow::For*>(&node)) {
7✔
18
        return false;
7✔
19
    }
20

21
    return false;
×
22
};
15✔
23

24
DeadCFGElimination::DeadCFGElimination()
5✔
25
    : Pass() {
5✔
26

27
      };
5✔
28

29
std::string DeadCFGElimination::name() { return "DeadCFGElimination"; };
×
30

31
bool DeadCFGElimination::run_pass(builder::StructuredSDFGBuilder& builder, analysis::AnalysisManager& analysis_manager) {
4✔
32
    bool applied = false;
4✔
33

34
    auto& sdfg = builder.subject();
4✔
35

36
    auto& root = sdfg.root();
4✔
37
    if (root.size() == 0) {
4✔
38
        return false;
×
39
    }
40
    auto last = root.at(root.size() - 1);
4✔
41
    if (last.second.empty()) {
4✔
42
        if (auto return_node = dynamic_cast<structured_control_flow::Return*>(&last.first)) {
3✔
43
            // void node or unreachable
NEW
44
            if (return_node->is_data() && return_node->data().empty() || return_node->is_unreachable()) {
×
45
                builder.remove_child(root, root.size() - 1);
×
46
                return true;
×
47
            }
48
        }
×
49
    }
3✔
50

51
    std::list<structured_control_flow::ControlFlowNode*> queue = {&sdfg.root()};
4✔
52
    while (!queue.empty()) {
32✔
53
        auto curr = queue.front();
28✔
54
        queue.pop_front();
28✔
55

56
        if (auto sequence_stmt = dynamic_cast<structured_control_flow::Sequence*>(curr)) {
28✔
57
            // Simplify
58
            size_t i = 0;
12✔
59
            while (i < sequence_stmt->size()) {
28✔
60
                auto child = sequence_stmt->at(i);
16✔
61
                if (!child.second.empty()) {
16✔
62
                    i++;
1✔
63
                    continue;
1✔
64
                }
65

66
                // Dead
67
                if (is_dead(child.first)) {
15✔
68
                    builder.remove_child(*sequence_stmt, i);
×
69
                    applied = true;
×
70
                    continue;
×
71
                }
72

73
                // Trivial branch
74
                if (auto if_else_stmt = dynamic_cast<structured_control_flow::IfElse*>(&child.first)) {
15✔
75
                    auto branch = if_else_stmt->at(0);
×
76
                    if (symbolic::is_true(branch.second)) {
×
77
                        builder.move_children(branch.first, *sequence_stmt, i + 1);
×
78
                        builder.remove_child(*sequence_stmt, i);
×
79
                        applied = true;
×
80
                        continue;
×
81
                    }
82
                }
×
83

84
                i++;
15✔
85
            }
86

87
            // Add to queue
88
            for (size_t j = 0; j < sequence_stmt->size(); j++) {
28✔
89
                queue.push_back(&sequence_stmt->at(j).first);
16✔
90
            }
16✔
91
        } else if (auto if_else_stmt = dynamic_cast<structured_control_flow::IfElse*>(curr)) {
28✔
92
            // False branches are safe to remove
93
            size_t i = 0;
×
94
            while (i < if_else_stmt->size()) {
×
95
                auto child = if_else_stmt->at(i);
×
96
                if (symbolic::is_false(child.second)) {
×
97
                    builder.remove_case(*if_else_stmt, i);
×
98
                    applied = true;
×
99
                    continue;
×
100
                }
101

102
                i++;
×
103
            }
×
104

105
            // Trailing dead branches are safe to remove
106
            if (if_else_stmt->size() > 0) {
×
107
                if (is_dead(if_else_stmt->at(if_else_stmt->size() - 1).first)) {
×
108
                    builder.remove_case(*if_else_stmt, if_else_stmt->size() - 1);
×
109
                    applied = true;
×
110
                }
×
111
            }
×
112

113
            // If-else to simple if conversion
114
            if (if_else_stmt->size() == 2) {
×
115
                auto if_condition = if_else_stmt->at(0).second;
×
116
                auto else_condition = if_else_stmt->at(1).second;
×
117
                if (symbolic::eq(if_condition->logical_not(), else_condition)) {
×
118
                    if (is_dead(if_else_stmt->at(1).first)) {
×
119
                        builder.remove_case(*if_else_stmt, 1);
×
120
                        applied = true;
×
121
                    } else if (is_dead(if_else_stmt->at(0).first)) {
×
122
                        builder.remove_case(*if_else_stmt, 0);
×
123
                        applied = true;
×
124
                    }
×
125
                }
×
126
            }
×
127

128
            // Add to queue
129
            for (size_t j = 0; j < if_else_stmt->size(); j++) {
×
130
                queue.push_back(&if_else_stmt->at(j).first);
×
131
            }
×
132
        } else if (auto loop_stmt = dynamic_cast<structured_control_flow::While*>(curr)) {
16✔
133
            auto& root = loop_stmt->root();
×
134
            queue.push_back(&root);
×
135
        } else if (auto sloop_stmt = dynamic_cast<structured_control_flow::StructuredLoop*>(curr)) {
16✔
136
            auto& root = sloop_stmt->root();
8✔
137
            queue.push_back(&root);
8✔
138
        } else if (auto map_stmt = dynamic_cast<structured_control_flow::Map*>(curr)) {
16✔
139
            auto& root = map_stmt->root();
×
140
            queue.push_back(&root);
×
141
        }
×
142
    }
143

144
    return applied;
4✔
145
};
4✔
146

147
} // namespace passes
148
} // 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