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

daisytuner / sdfglib / 15948486670

28 Jun 2025 09:48PM UTC coverage: 65.154% (+0.1%) from 65.01%
15948486670

push

github

web-flow
Merge pull request #117 from daisytuner/while-loops

Improves lifting of for loops

27 of 53 new or added lines in 4 files covered. (50.94%)

1 existing line in 1 file now uncovered.

8571 of 13155 relevant lines covered (65.15%)

144.59 hits per line

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

83.33
/src/passes/structured_control_flow/loop_normalization.cpp
1
#include "sdfg/passes/structured_control_flow/loop_normalization.h"
2

3
#include "sdfg/analysis/assumptions_analysis.h"
4
#include "sdfg/analysis/loop_analysis.h"
5
#include "sdfg/symbolic/conjunctive_normal_form.h"
6
#include "sdfg/symbolic/series.h"
7

8
namespace sdfg {
9
namespace passes {
10

11
bool LoopNormalization::apply(builder::StructuredSDFGBuilder& builder,
3✔
12
                              analysis::AnalysisManager& analysis_manager,
13
                              structured_control_flow::For& loop) {
14
    auto condition = loop.condition();
3✔
15

16
    bool applied = false;
3✔
17

18
    // Step 1: Normalize condition
19
    try {
20
        auto cnf = symbolic::conjunctive_normal_form(condition);
3✔
21
        symbolic::Condition new_condition = symbolic::__true__();
3✔
22
        for (auto& clause : cnf) {
7✔
23
            symbolic::Condition new_clause = symbolic::__false__();
4✔
24
            for (auto& literal : clause) {
9✔
25
                new_clause = symbolic::Or(new_clause, literal);
5✔
26
            }
27
            new_condition = symbolic::And(new_condition, new_clause);
4✔
28
        }
4✔
29
        if (!symbolic::eq(new_condition, condition)) {
3✔
NEW
30
            loop.condition() = new_condition;
×
NEW
31
            applied = true;
×
NEW
32
        }
×
33

34
        condition = new_condition;
3✔
35
    } catch (const symbolic::CNFException e) {
3✔
NEW
36
        return false;
×
NEW
37
    }
×
38

39
    auto& assumptions_analysis = analysis_manager.get<analysis::AssumptionsAnalysis>();
3✔
40
    if (!analysis::LoopAnalysis::is_contiguous(&loop, assumptions_analysis)) {
3✔
NEW
41
        return applied;
×
42
    }
43

44
    // Section: Condition
45
    // Turn inequalities into strict less than
46
    auto indvar = loop.indvar();
3✔
47

48
    try {
49
        auto cnf = symbolic::conjunctive_normal_form(condition);
3✔
50
        symbolic::CNF new_cnf;
3✔
51
        for (auto& clause : cnf) {
7✔
52
            std::vector<symbolic::Condition> new_clause;
4✔
53
            for (auto& literal : clause) {
9✔
54
                if (SymEngine::is_a<SymEngine::Unequality>(*literal)) {
5✔
55
                    auto eq = SymEngine::rcp_static_cast<const SymEngine::Unequality>(literal);
5✔
56
                    auto eq_args = eq->get_args();
5✔
57
                    auto lhs = eq_args.at(0);
5✔
58
                    auto rhs = eq_args.at(1);
5✔
59
                    if (SymEngine::eq(*lhs, *indvar) && !symbolic::uses(rhs, indvar)) {
5✔
60
                        new_clause.push_back(symbolic::Lt(lhs, rhs));
×
61
                    } else if (SymEngine::eq(*rhs, *indvar) && !symbolic::uses(lhs, indvar)) {
5✔
62
                        new_clause.push_back(symbolic::Lt(rhs, lhs));
5✔
63
                    } else {
5✔
UNCOV
64
                        new_clause.push_back(literal);
×
65
                    }
66
                } else {
5✔
67
                    new_clause.push_back(literal);
×
68
                }
69
            }
70
            new_cnf.push_back(new_clause);
4✔
71
        }
4✔
72
        // Construct new condition
73
        symbolic::Condition new_condition = symbolic::__true__();
3✔
74
        for (auto& clause : new_cnf) {
7✔
75
            symbolic::Condition new_clause = symbolic::__false__();
4✔
76
            for (auto& literal : clause) {
9✔
77
                new_clause = symbolic::Or(new_clause, literal);
5✔
78
            }
79
            new_condition = symbolic::And(new_condition, new_clause);
4✔
80
        }
4✔
81
        if (!symbolic::eq(new_condition, condition)) {
3✔
82
            loop.condition() = new_condition;
3✔
83
            applied = true;
3✔
84
        }
3✔
85
        condition = new_condition;
3✔
86
    } catch (const symbolic::CNFException e) {
3✔
87
    }
×
88

89
    return applied;
3✔
90
};
3✔
91

92
LoopNormalization::LoopNormalization()
3✔
93
    : Pass() {
3✔
94

95
      };
3✔
96

97
std::string LoopNormalization::name() { return "LoopNormalization"; };
×
98

99
bool LoopNormalization::run_pass(builder::StructuredSDFGBuilder& builder,
3✔
100
                                 analysis::AnalysisManager& analysis_manager) {
101
    bool applied = false;
3✔
102

103
    auto& loop_analysis = analysis_manager.get<analysis::LoopAnalysis>();
3✔
104
    for (const auto& loop : loop_analysis.loops()) {
6✔
105
        if (auto for_loop = dynamic_cast<structured_control_flow::For*>(loop)) {
3✔
106
            applied |= this->apply(builder, analysis_manager, *for_loop);
3✔
107
        }
3✔
108
    }
109

110
    return applied;
3✔
111
};
×
112

113
}  // namespace passes
114
}  // 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

© 2025 Coveralls, Inc