Branch data Line data Source code
1 : : #pragma once
2 : :
3 : : #include <mutable/IR/PhysicalOptimizer.hpp>
4 : :
5 : :
6 : : namespace m {
7 : :
8 : : namespace interpreter {
9 : :
10 : : // forward declarations
11 : : struct MatchBaseVisitor;
12 : : struct ConstMatchBaseVisitor;
13 : :
14 : : /** An abstract `MatchBase` for the `Interpreter` backend. Adds accept methods for respective visitor. */
15 : : struct MatchBase : m::MatchBase
16 : : {
17 : : virtual void accept(MatchBaseVisitor &v) = 0;
18 : : virtual void accept(ConstMatchBaseVisitor &v) const = 0;
19 : : };
20 : :
21 : : }
22 : :
23 : : /** This macro declares a simple 1:1 mapping between logical and physical operator for the `Interpreter`. */
24 : : #define DECLARE(CLASS) \
25 : : /* forward declarations */ \
26 : : namespace interpreter { struct CLASS; } \
27 : : template<> struct Match<interpreter::CLASS>; \
28 : : \
29 : : namespace interpreter { \
30 : : \
31 : : struct CLASS : PhysicalOperator<CLASS, m::CLASS> \
32 : : { \
33 : : static void execute(const Match<CLASS>&, setup_t, pipeline_t, teardown_t) { M_unreachable("not implemented"); } \
34 : : static double cost(const Match<CLASS>&) { return 1.0; } \
35 : : static ConditionSet \
36 : : adapt_post_conditions(const Match<CLASS>&, std::vector<std::reference_wrapper<const ConditionSet>>&&) { \
37 : : return ConditionSet(); /* has to be overwritten for operators with multiple children, i.e. `JoinOperator` */ \
38 : : } \
39 : : }; \
40 : : \
41 : : } \
42 : : \
43 : : template<> \
44 : : struct Match<interpreter::CLASS> : interpreter::MatchBase \
45 : : { \
46 : : const CLASS &op; \
47 : : std::vector<unsharable_shared_ptr<const interpreter::MatchBase>> children; \
48 : : \
49 : : Match(const CLASS *op, std::vector<unsharable_shared_ptr<const m::MatchBase>> &&children) \
50 : : : op(*op) \
51 : : , children([&children](){ \
52 : : std::vector<unsharable_shared_ptr<const interpreter::MatchBase>> res; \
53 : : for (auto &c : children) \
54 : : res.push_back(as<const interpreter::MatchBase>(std::move(c))); \
55 : : return res; \
56 : : }()) \
57 : : { } \
58 : : \
59 : : void execute(setup_t, pipeline_t, teardown_t) const override { \
60 : : M_unreachable("must not be called since `Interpreter` uses former visitor pattern on logical operators for " \
61 : : "execution"); \
62 : : } \
63 : : \
64 : : const Operator & get_matched_root() const override { return op; } \
65 : : \
66 : : void accept(interpreter::MatchBaseVisitor &v) override; \
67 : : void accept(interpreter::ConstMatchBaseVisitor &v) const override; \
68 : : \
69 : : protected: \
70 : : void print(std::ostream &out, unsigned level) const override { \
71 : : indent(out, level) << "interpreter::" << #CLASS << " (cumulative cost " << cost() << ')'; \
72 : : for (auto &child : children) \
73 : : child->print(out, level + 1); \
74 : : } \
75 : : };
76 [ # # # # : 972 : M_OPERATOR_LIST(DECLARE)
# # # # #
# # # # #
# # # # #
# # # # #
+ - + - #
# # # + -
+ - + + +
- + - + -
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
+ - + + +
- + - + -
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
77 : : #undef DECLARE
78 : :
79 : : void register_interpreter_operators(PhysicalOptimizer &phys_opt);
80 : :
81 : : namespace interpreter {
82 : :
83 : : #define MAKE_INTERPRETER_MATCH_(OP) m::Match<m::interpreter::OP>
84 : : #define M_INTERPRETER_MATCH_LIST(X) M_TRANSFORM_X_MACRO(X, M_OPERATOR_LIST, MAKE_INTERPRETER_MATCH_)
85 : :
86 : : M_DECLARE_VISITOR(MatchBaseVisitor, interpreter::MatchBase, M_INTERPRETER_MATCH_LIST)
87 : : M_DECLARE_VISITOR(ConstMatchBaseVisitor, const interpreter::MatchBase, M_INTERPRETER_MATCH_LIST)
88 : :
89 : : /** A generic base class for implementing recursive `interpreter::MatchBase` visitors. */
90 : : template<bool C>
91 : : struct TheRecursiveMatchBaseVisitorBase : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
92 : : {
93 : : using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
94 : : template<typename T> using Const = typename super::template Const<T>;
95 : :
96 : 0 : virtual ~TheRecursiveMatchBaseVisitorBase() { }
97 : :
98 : : using super::operator();
99 : : #define DECLARE(CLASS) \
100 : : void operator()(Const<CLASS> &M) override { for (auto &c : M.children) (*this)(*c); }
101 [ # # # # : 0 : M_INTERPRETER_MATCH_LIST(DECLARE)
# # # # #
# # # # #
# # # # #
# # # #
# ]
102 : : #undef DECLARE
103 : : };
104 : :
105 : : using RecursiveConstMatchBaseVisitorBase = TheRecursiveMatchBaseVisitorBase<true>;
106 : :
107 : : template<bool C>
108 : : struct ThePreOrderMatchBaseVisitor : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
109 : : {
110 : : using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
111 : : template<typename T> using Const = typename super::template Const<T>;
112 : :
113 : 0 : virtual ~ThePreOrderMatchBaseVisitor() { }
114 : :
115 : : void operator()(Const<MatchBase>&);
116 : : };
117 : :
118 : : template<bool C>
119 : : struct ThePostOrderMatchBaseVisitor : std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>
120 : : {
121 : : using super = std::conditional_t<C, ConstMatchBaseVisitor, MatchBaseVisitor>;
122 : : template<typename T> using Const = typename super::template Const<T>;
123 : :
124 : 0 : virtual ~ThePostOrderMatchBaseVisitor() { }
125 : :
126 : : void operator()(Const<MatchBase>&);
127 : : };
128 : :
129 : : using ConstPreOrderMatchBaseVisitor = ThePreOrderMatchBaseVisitor<true>;
130 : : using ConstPostOrderMatchBaseVisitor = ThePostOrderMatchBaseVisitor<true>;
131 : :
132 : : M_MAKE_STL_VISITABLE(ConstPreOrderMatchBaseVisitor, const interpreter::MatchBase, M_INTERPRETER_MATCH_LIST)
133 : : M_MAKE_STL_VISITABLE(ConstPostOrderMatchBaseVisitor, const interpreter::MatchBase, M_INTERPRETER_MATCH_LIST)
134 : :
135 : : }
136 : :
137 : : }
|