1 | #pragma once |
2 | |
3 | #include "taichi/ir/ir.h" |
4 | #include "taichi/program/compile_config.h" |
5 | |
6 | #include <unordered_map> |
7 | #include <typeindex> |
8 | #include <utility> |
9 | |
10 | namespace taichi::lang { |
11 | |
12 | using PassID = std::string; |
13 | |
14 | class Program; |
15 | |
16 | /*class PassContext { |
17 | public: |
18 | PassContext() { |
19 | } |
20 | explicit PassContext(CompileConfig config) : config_(std::move(config)) { |
21 | } |
22 | [[nodiscard]] const CompileConfig &get_config() const { |
23 | return config_; |
24 | } |
25 | |
26 | private: |
27 | CompileConfig config_; |
28 | };*/ |
29 | |
30 | class AnalysisManager; |
31 | |
32 | // Abstract concept of an analysis result. |
33 | struct AnalysisResultConcept { |
34 | virtual ~AnalysisResultConcept() = default; |
35 | }; |
36 | |
37 | template <typename ResultT> |
38 | struct AnalysisResultModel : public AnalysisResultConcept { |
39 | explicit AnalysisResultModel(ResultT result) : result(std::move(result)) { |
40 | } |
41 | ResultT result; |
42 | }; |
43 | |
44 | class Pass { |
45 | public: |
46 | static const PassID id; |
47 | |
48 | // The numbers for the cases are assigned to make sure that Failure & anything |
49 | // is Failure, SuccessWithChange & any success is SuccessWithChange. |
50 | enum class Status { |
51 | Failure = 0x00, |
52 | SuccessWithChange = 0x10, |
53 | SuccessWithoutChange = 0x11, |
54 | }; |
55 | |
56 | /*virtual Status run(const PassContext &ctx, |
57 | IRNode *module, |
58 | AnalysisManager *amgr) { |
59 | return Status::Failure; |
60 | }*/ |
61 | |
62 | virtual ~Pass() = default; |
63 | }; |
64 | |
65 | class AnalysisManager { |
66 | public: |
67 | template <typename PassT> |
68 | typename PassT::Result *get_pass_result() { |
69 | auto result = result_.find(PassT::id); |
70 | if (result == result_.end()) { |
71 | return nullptr; |
72 | } |
73 | using ResultModelT = AnalysisResultModel<typename PassT::Result>; |
74 | return &(static_cast<ResultModelT *>(result->second.get())->result); |
75 | } |
76 | |
77 | template <typename PassT> |
78 | void put_pass_result(typename PassT::Result &&result) { |
79 | using ResultModelT = AnalysisResultModel<typename PassT::Result>; |
80 | result_[PassT::id] = std::make_unique<ResultModelT>(std::move(result)); |
81 | } |
82 | |
83 | private: |
84 | std::unordered_map<PassID, std::unique_ptr<AnalysisResultConcept>> result_; |
85 | }; |
86 | |
87 | } // namespace taichi::lang |
88 | |