VapourSynth-llvmexpr
Loading...
Searching...
No Matches
ForwardDataflowAnalysis.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_ANALYSIS_FRAMEWORK_FORWARD_DATAFLOW_ANALYSIS_HPP
21#define LLVMEXPR_ANALYSIS_FRAMEWORK_FORWARD_DATAFLOW_ANALYSIS_HPP
22
24#include "DataStructures.hpp"
25
26#include <algorithm>
27#include <iterator>
28#include <vector>
29
30namespace analysis {
31
32template <typename DomainT> class ForwardDataflowAnalysis {
33 public:
35 virtual ~ForwardDataflowAnalysis() = default;
41
42 virtual DomainT computeGenSet(size_t block_idx,
43 const std::vector<Token>& tokens,
44 const std::vector<CFGBlock>& cfg_blocks) = 0;
45
46 virtual DomainT meetOperation(const std::vector<DomainT>& inputs) = 0;
47
48 virtual DomainT transferFunction(const DomainT& in_value,
49 const DomainT& gen_set) = 0;
50
51 virtual DomainT getBoundaryValue() = 0;
52
53 virtual DomainT getInitialOutValue() { return DomainT{}; }
54
55 std::pair<std::vector<DomainT>, std::vector<DomainT>>
56 analyze(const std::vector<Token>& tokens,
57 const std::vector<CFGBlock>& cfg_blocks) {
58 const size_t num_blocks = cfg_blocks.size();
59
60 std::vector<DomainT> gen_sets(num_blocks);
61 for (size_t i = 0; i < num_blocks; ++i) {
62 gen_sets[i] = computeGenSet(i, tokens, cfg_blocks);
63 }
64
65 std::vector<DomainT> in_sets(num_blocks);
66 std::vector<DomainT> out_sets(num_blocks, getInitialOutValue());
67
68 if (!cfg_blocks.empty()) {
69 in_sets[0] = getBoundaryValue();
70 }
71
72 bool changed = true;
73 while (changed) {
74 changed = false;
75
76 for (size_t i = 0; i < num_blocks; ++i) {
77 DomainT new_in;
78 if (i == 0 || cfg_blocks[i].predecessors.empty()) {
79 new_in = getBoundaryValue();
80 } else {
81 std::vector<DomainT> pred_outs;
82 pred_outs.reserve(cfg_blocks[i].predecessors.size());
83 std::transform(cfg_blocks[i].predecessors.begin(),
84 cfg_blocks[i].predecessors.end(),
85 std::back_inserter(pred_outs),
86 [&out_sets](int pred_idx) {
87 return out_sets[pred_idx];
88 });
89 new_in = meetOperation(pred_outs);
90 }
91
92 if (new_in != in_sets[i]) {
93 in_sets[i] = std::move(new_in);
94 }
95
96 DomainT new_out = transferFunction(in_sets[i], gen_sets[i]);
97
98 if (new_out != out_sets[i]) {
99 out_sets[i] = std::move(new_out);
100 changed = true;
101 }
102 }
103 }
104
105 return {std::move(in_sets), std::move(out_sets)};
106 }
107};
108
109} // namespace analysis
110
111#endif // LLVMEXPR_ANALYSIS_FRAMEWORK_FORWARD_DATAFLOW_ANALYSIS_HPP
ForwardDataflowAnalysis(ForwardDataflowAnalysis &&)=default
std::pair< std::vector< DomainT >, std::vector< DomainT > > analyze(const std::vector< Token > &tokens, const std::vector< CFGBlock > &cfg_blocks)
virtual DomainT computeGenSet(size_t block_idx, const std::vector< Token > &tokens, const std::vector< CFGBlock > &cfg_blocks)=0
virtual DomainT transferFunction(const DomainT &in_value, const DomainT &gen_set)=0
virtual ~ForwardDataflowAnalysis()=default
virtual DomainT meetOperation(const std::vector< DomainT > &inputs)=0
ForwardDataflowAnalysis & operator=(const ForwardDataflowAnalysis &)=default
ForwardDataflowAnalysis & operator=(ForwardDataflowAnalysis &&)=default
ForwardDataflowAnalysis(const ForwardDataflowAnalysis &)=default
virtual DomainT getBoundaryValue()=0