• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMPILER_OPTIMIZER_PASS_MANAGER_H
17 #define COMPILER_OPTIMIZER_PASS_MANAGER_H
18 
19 #include <tuple>
20 #include "compiler_options.h"
21 #include "pass.h"
22 #include "utils/bit_field.h"
23 #include "utils/arena_containers.h"
24 #include "pass_manager_statistics.h"
25 
26 namespace ark::compiler {
27 class Graph;
28 class Pass;
29 class Analysis;
30 class CatchInputs;
31 class LivenessAnalyzer;
32 class LiveRegisters;
33 class LoopAnalyzer;
34 class AliasAnalysis;
35 class DominatorsTree;
36 class Rpo;
37 class LinearOrder;
38 class BoundsAnalysis;
39 class MonitorAnalysis;
40 // NOLINTNEXTLINE(fuchsia-multiple-inheritance)
41 class ObjectTypePropagation;
42 class RegAllocVerifier;
43 class TypesAnalysis;
44 
45 namespace details {
46 template <typename... Types>
47 class PassTypeList {
48 public:
49     using IdentifierType = size_t;
50     using TupleType = std::tuple<std::decay_t<Types>...>;
51 
52     template <typename T>
HasType()53     static constexpr bool HasType()
54     {
55         return std::disjunction_v<std::is_same<T, Types>...>;
56     }
57 
58     template <typename T, typename... Args>
Instantiate(ArenaAllocator * allocator,Args &&...args)59     static ArenaVector<T> Instantiate(ArenaAllocator *allocator, Args &&...args)
60     {
61         ArenaVector<T> vec(allocator->Adapter());
62         vec.reserve(sizeof...(Types));
63         ((vec.push_back(allocator->New<Types>((std::forward<Args>(args))...))), ...);
64         return vec;
65     }
66 
67     template <typename Type, std::size_t... INDEXES>
GetIndex(std::index_sequence<INDEXES...>)68     static constexpr size_t GetIndex(std::index_sequence<INDEXES...> /* unused */)
69     {
70         static_assert(HasType<Type>());
71         return (0 + ... +
72                 (std::is_same_v<Type, std::tuple_element_t<INDEXES, TupleType>> ? size_t(INDEXES) : size_t {}));
73     }
74 
75     template <typename Type>
76     static constexpr IdentifierType ID = GetIndex<std::decay_t<Type>>(std::index_sequence_for<Types...> {});
77     static constexpr size_t SIZE = sizeof...(Types);
78 };
79 
80 using PredefinedAnalyses =
81     PassTypeList<LivenessAnalyzer, LoopAnalyzer, AliasAnalysis, DominatorsTree, Rpo, LinearOrder, BoundsAnalysis,
82                  MonitorAnalysis, LiveRegisters, ObjectTypePropagation, RegAllocVerifier, TypesAnalysis, CatchInputs>;
83 }  // namespace details
84 
85 class PassManager {
86 public:
87     PANDA_PUBLIC_API PassManager(Graph *graph, PassManager *parentPm);
88 
89     PANDA_PUBLIC_API ArenaAllocator *GetAllocator();
90     PANDA_PUBLIC_API ArenaAllocator *GetLocalAllocator();
91 
92     PANDA_PUBLIC_API bool RunPass(Pass *pass, size_t localMemSizeBeforePass);
93 
94     template <typename T, typename... Args>
RunPass(Args...args)95     bool RunPass(Args... args)
96     {
97         auto localMemSizeBefore = GetLocalAllocator()->GetAllocatedSize();
98         bool res = false;
99         // NOLINTNEXTLINE(readability-braces-around-statements)
100         if constexpr (details::PredefinedAnalyses::HasType<T>()) {
101             static_assert(sizeof...(Args) == 0);
102             res = RunPass(analyses_[details::PredefinedAnalyses::ID<T>], localMemSizeBefore);
103             // NOLINTNEXTLINE(readability-misleading-indentation)
104         } else {
105             T pass(graph_, std::forward<Args>(args)...);
106             res = RunPass(&pass, localMemSizeBefore);
107         }
108         if (!IsCheckMode()) {
109             if (g_options.IsCompilerResetLocalAllocator()) {
110                 ASSERT(GetLocalAllocator() != GetAllocator());
111                 GetLocalAllocator()->Resize(localMemSizeBefore);
112             }
113         }
114         return res;
115     }
116 
117     template <typename T>
GetAnalysis()118     T &GetAnalysis()
119     {
120         static_assert(std::is_base_of_v<Analysis, std::decay_t<T>>);
121         return *static_cast<T *>(analyses_[details::PredefinedAnalyses::ID<T>]);
122     }
123     std::string GetFileName(const char *passName = nullptr, const std::string &suffix = ".cfg");
124     void DumpGraph(const char *passName);
125     void DumpLifeIntervals(const char *passName);
126     void InitialDumpVisualizerGraph();
127     void DumpVisualizerGraph(const char *passName);
128     template <bool FORCE_RUN>
129     bool RunPassChecker(Pass *pass, bool result, bool isCodegen);
130     bool RunPassChecker(Pass *pass, bool result, bool isCodegen);
131 
GetGraph()132     Graph *GetGraph()
133     {
134         return graph_;
135     }
136 
137     void Finalize() const;
138 
GetStatistics()139     PassManagerStatistics *GetStatistics()
140     {
141         return stats_;
142     }
143 
SetCheckMode(bool v)144     void SetCheckMode(bool v)
145     {
146         checkMode_ = v;
147     }
148 
IsCheckMode()149     bool IsCheckMode() const
150     {
151         return checkMode_;
152     }
153 
154     // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
GetExecutionCounter()155     size_t GetExecutionCounter() const
156     {
157         return executionCounter_;
158     }
159 
160     // NOLINTNEXTLINE(readability-convert-member-functions-to-static)
StartExecution()161     void StartExecution()
162     {
163         executionCounter_++;
164     }
165 
166 private:
167     Graph *graph_ {nullptr};
168     ArenaVector<Optimization *> optimizations_;
169     const ArenaVector<Analysis *> analyses_;
170 
171     PassManagerStatistics *stats_ {nullptr};
172     inline static size_t executionCounter_ {0};
173 
174     // Whether passes are run by checker.
175     bool checkMode_ {false};
176 
177     bool firstExecution_ {true};
178 };
179 }  // namespace ark::compiler
180 
181 #endif  // COMPILER_OPTIMIZER_PASS_MANAGER_H
182