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

daisytuner / sdfglib / 15044057891

15 May 2025 11:42AM UTC coverage: 59.37% (+1.8%) from 57.525%
15044057891

push

github

web-flow
Merge pull request #14 from daisytuner/sanitizers

enables sanitizer on unit tests

63 of 67 new or added lines in 47 files covered. (94.03%)

570 existing lines in 62 files now uncovered.

7356 of 12390 relevant lines covered (59.37%)

505.93 hits per line

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

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

3
namespace sdfg {
4
namespace passes {
5

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

19
    return false;
4✔
20
};
44✔
21

22
DeadCFGElimination::DeadCFGElimination()
7✔
23
    : Pass(){
7✔
24

25
      };
7✔
26

27
std::string DeadCFGElimination::name() { return "DeadCFGElimination"; };
×
28

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

33
    auto& sdfg = builder.subject();
9✔
34

35
    auto& root = sdfg.root();
9✔
36
    if (root.size() == 0) {
9✔
37
        return false;
×
38
    }
39
    auto last = root.at(root.size() - 1);
9✔
40
    if (last.second.empty() && dynamic_cast<structured_control_flow::Return*>(&last.first)) {
9✔
41
        builder.remove_child(root, root.size() - 1);
×
42
        applied = true;
×
UNCOV
43
    }
×
44

45
    std::list<structured_control_flow::ControlFlowNode*> queue = {&sdfg.root()};
9✔
46
    while (!queue.empty()) {
85✔
47
        auto curr = queue.front();
76✔
48
        queue.pop_front();
76✔
49

50
        if (auto sequence_stmt = dynamic_cast<structured_control_flow::Sequence*>(curr)) {
76✔
51
            // Simplify
52
            size_t i = 0;
36✔
53
            while (i < sequence_stmt->size()) {
80✔
54
                auto child = sequence_stmt->at(i);
44✔
55
                if (!child.second.empty()) {
44✔
56
                    i++;
×
57
                    continue;
×
58
                }
59

60
                // Dead
61
                if (is_dead(child.first)) {
44✔
62
                    builder.remove_child(*sequence_stmt, i);
×
63
                    applied = true;
×
64
                    continue;
×
65
                }
66

67
                // Trivial branch
68
                if (auto if_else_stmt =
44✔
69
                        dynamic_cast<structured_control_flow::IfElse*>(&child.first)) {
44✔
UNCOV
70
                    auto branch = if_else_stmt->at(0);
×
UNCOV
71
                    if (symbolic::is_true(branch.second)) {
×
72
                        builder.insert_children(*sequence_stmt, branch.first, i + 1);
×
73
                        builder.remove_child(*sequence_stmt, i);
×
74
                        applied = true;
×
75
                        continue;
×
76
                    }
UNCOV
77
                }
×
78

79
                i++;
44✔
80
            }
81

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

UNCOV
97
                i++;
×
98
            }
99

100
            // Trailing dead branches are safe to remove
UNCOV
101
            if (if_else_stmt->size() > 0) {
×
UNCOV
102
                if (is_dead(if_else_stmt->at(if_else_stmt->size() - 1).first)) {
×
103
                    builder.remove_case(*if_else_stmt, if_else_stmt->size() - 1);
×
104
                    applied = true;
×
UNCOV
105
                }
×
UNCOV
106
            }
×
107

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

123
            // Add to queue
UNCOV
124
            for (size_t j = 0; j < if_else_stmt->size(); j++) {
×
UNCOV
125
                queue.push_back(&if_else_stmt->at(j).first);
×
UNCOV
126
            }
×
127
        } else if (auto loop_stmt = dynamic_cast<structured_control_flow::While*>(curr)) {
40✔
128
            auto& root = loop_stmt->root();
×
129
            queue.push_back(&root);
×
130
        } else if (auto for_stmt = dynamic_cast<structured_control_flow::For*>(curr)) {
40✔
131
            auto& root = for_stmt->root();
19✔
132
            queue.push_back(&root);
19✔
133
        } else if (auto kernel_stmt = dynamic_cast<structured_control_flow::Kernel*>(curr)) {
40✔
134
            auto& root = kernel_stmt->root();
4✔
135
            queue.push_back(&root);
4✔
136
        }
4✔
137
    }
138

139
    return applied;
9✔
140
};
9✔
141

142
}  // namespace passes
143
}  // 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