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

ahueck / llvm-dimeta / 13933486559

18 Mar 2025 09:06PM UTC coverage: 83.197% (-0.4%) from 83.637%
13933486559

push

github

web-flow
Refactoring (#35)

1027 of 1482 branches covered (69.3%)

Branch coverage included in aggregate %.

86 of 87 new or added lines in 10 files covered. (98.85%)

17 existing lines in 7 files now uncovered.

1924 of 2065 relevant lines covered (93.17%)

3950.95 hits per line

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

68.75
/lib/type/DefUseAnalysis.h
1
//  llvm-dimeta library
2
//  Copyright (c) 2022-2025 llvm-dimeta authors
3
//  Distributed under the BSD 3-Clause license.
4
//  (See accompanying file LICENSE)
5
//  SPDX-License-Identifier: BSD-3-Clause
6
//
7

8
#ifndef DIMETA_DEFUSEANALYSIS_H
9
#define DIMETA_DEFUSEANALYSIS_H
10

11
#include "Util.h"
12
#include "ValuePath.h"
13

14
#include "llvm/ADT/SmallPtrSet.h"
15
#include "llvm/IR/Instructions.h"
16
#include "llvm/Support/raw_ostream.h"
17

18
#include <algorithm>
19
#include <functional>
20

21
namespace dimeta::dataflow {
22

23
struct DefUseChain {
24
 public:
25
  enum MatchResult { kContinue = 0, kCancel, kSkip };
26

27
 private:
28
  llvm::SmallVector<ValuePath, 16> working_set_;
29
  llvm::SmallPtrSet<const llvm::Value*, 16> seen_set_;
30

31
  void addToWorkS(const ValuePath& value) {
6,690✔
32
    if (!value.empty() && seen_set_.find(value.value().value_or(nullptr)) == seen_set_.end()) {
6,690!
33
      working_set_.push_back(value);
6,670✔
34
    }
6,670✔
35
  }
6,690✔
36

37
  template <typename Range>
38
  void addToWork(Range&& vals, const ValuePath& current) {
4,480✔
39
    for (auto value : vals) {
8,976✔
40
      auto path = current + value;
4,496✔
41
      addToWorkS(path);
4,496✔
42
    }
4,496✔
43
  }
4,480✔
44

45
  auto peek() -> ValuePath {
6,670✔
46
    if (working_set_.empty()) {
6,670!
47
      return ValuePath{};
×
48
    }
49
    auto* user_iter = working_set_.end() - 1;
6,670✔
50
    working_set_.erase(user_iter);
6,670✔
51
    return *user_iter;
6,670✔
52
  }
6,670✔
53

54
  template <typename ShouldSearchFn, typename SDirectionFn, typename CallBackFn>
55
  void do_traverse(ShouldSearchFn&& should_search, SDirectionFn&& search, const llvm::Value* start,
2,194✔
56
                   CallBackFn&& match) {
57
    //    const auto should_search = [](auto user) {
58
    //      return llvm::isa<AllowedTy>(user) && !llvm::isa<llvm::ConstantData>(user);
59
    //    };
60
    const auto scope_clean = util::create_scope_exit([&]() {
4,388✔
61
      working_set_.clear();
2,194✔
62
      seen_set_.clear();
2,194✔
63
    });
2,194✔
64

65
    const auto apply_search_direction = [&](const ValuePath& current_path) {
6,680✔
66
      auto value = search(current_path);
4,486✔
67
      if (value) {
4,486!
68
        addToWork(value.value(), current_path);
4,480✔
69
      }
4,480✔
70
    };
4,486✔
71

72
    addToWorkS(ValuePath{start});
2,194✔
73

74
    while (!working_set_.empty()) {
8,770!
75
      const ValuePath user = peek();
6,670✔
76
      if (user.empty()) {
6,670!
77
        continue;
×
78
      }
79

80
      const auto current_node = user.value();
6,670✔
81
      if (current_node) {
6,670!
82
        seen_set_.insert(current_node.value());
6,670✔
83
      }
6,670✔
84

85
      if (MatchResult match_v = match(user)) {
8,854!
86
        switch (match_v) {
2,184!
87
          case kSkip:
88
            continue;
2,090✔
89
          case kCancel:
90
            return;
94✔
91
          default:
UNCOV
92
            break;
×
93
        }
UNCOV
94
      }
×
95

96
      if (should_search(user)) {
4,486!
97
        apply_search_direction(user);
4,486✔
98
      }
4,486✔
99
    }
6,670!
100
  }
2,194!
101

102
 public:
103
  template <typename CallBackFn, typename ShouldSearchFn>
104
  void traverse(const llvm::Value* start, CallBackFn&& match, ShouldSearchFn&& should_search) {
1,174✔
105
    do_traverse(
1,174✔
106
        std::forward<ShouldSearchFn>(should_search),
1,174✔
107
        [](const ValuePath& val) -> std::optional<decltype(val.value().value()->users())> {
2,770✔
108
          const auto value = val.value();
1,596✔
109
          if (!value) {
1,596!
110
            return {};
×
111
          }
112
          return value.value()->users();
1,596✔
113
        },
1,596✔
114
        start, std::forward<CallBackFn>(match));
1,174✔
115
  }
1,174✔
116

117
  template <typename CallBackFn, typename ShouldSearchFn, typename SearchDirFn>
118
  void traverse_custom(const llvm::Value* start, CallBackFn&& match, ShouldSearchFn&& should_search,
1,020✔
119
                       SearchDirFn&& search_dir) {
120
    do_traverse(std::forward<ShouldSearchFn>(should_search), std::forward<SearchDirFn>(search_dir), start,
2,040✔
121
                std::forward<CallBackFn>(match));
1,020✔
122
  }
1,020✔
123
};
124

125
}  // namespace dimeta::dataflow
126

127
#endif  // DIMETA_DEFUSEANALYSIS_H
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