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
10namespace taichi::lang {
11
12using PassID = std::string;
13
14class 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
30class AnalysisManager;
31
32// Abstract concept of an analysis result.
33struct AnalysisResultConcept {
34 virtual ~AnalysisResultConcept() = default;
35};
36
37template <typename ResultT>
38struct AnalysisResultModel : public AnalysisResultConcept {
39 explicit AnalysisResultModel(ResultT result) : result(std::move(result)) {
40 }
41 ResultT result;
42};
43
44class 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
65class 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