• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-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
16namespace ark::libllvmbackend {
17
18void RegisterPasses(llvm::PassInstrumentationCallbacks &passInstrumentation)
19{
20    auto registerName = [&passInstrumentation](llvm::StringRef className, llvm::StringRef passName) {
21        passInstrumentation.addClassToPassName(className, passName);
22    };
23
24% PassRegistry::llvm_passes.each do |pass|
25    registerName("<%= PassRegistry::passes_namespace %>::<%= pass.name %>", <%= PassRegistry::passes_namespace %>::<%= pass.name %>::ARG_NAME);
26% end
27}
28
29using StringRef = llvm::StringRef;
30using LLVMCompilerOptions = ark::llvmbackend::LLVMCompilerOptions;
31using PipelineElements = llvm::ArrayRef<llvm::PassBuilder::PipelineElement>;
32
33struct PassParser
34{
35public:
36    explicit PassParser(ark::llvmbackend::LLVMArkInterface *arkInterface) : arkInterface_{arkInterface}
37    {
38    }
39
40    bool ParseModulePasses(StringRef name, llvm::ModulePassManager &modulePm, const LLVMCompilerOptions &options);
41    bool ParseFunctionPasses(StringRef name, llvm::FunctionPassManager &functionPm, const LLVMCompilerOptions &options);
42    bool ParseSCCPasses(StringRef name, llvm::CGSCCPassManager &sccPm, const LLVMCompilerOptions &options);
43    bool ParseLoopPasses(StringRef name, llvm::LoopPassManager &sccPm, const LLVMCompilerOptions &options);
44
45    void RegisterParserCallbacks(llvm::PassBuilder &builder, const ark::llvmbackend::LLVMCompilerOptions &options)
46    {
47        builder.registerPipelineParsingCallback(
48        [&](StringRef name, llvm::ModulePassManager &modulePm, PipelineElements /*unused*/) -> bool {
49            return ParseModulePasses(name, modulePm, options);
50        });
51        builder.registerPipelineParsingCallback(
52        [&](StringRef name, llvm::FunctionPassManager &functionPm, PipelineElements /*unused*/) -> bool {
53            return ParseFunctionPasses(name, functionPm, options);
54        });
55        builder.registerPipelineParsingCallback(
56        [&](StringRef name, llvm::CGSCCPassManager &sccPm, PipelineElements /*unused*/) -> bool {
57            return ParseSCCPasses(name, sccPm, options);
58        });
59        builder.registerPipelineParsingCallback(
60        [&](StringRef name, llvm::LoopPassManager &sccPm, PipelineElements /*unused*/) -> bool {
61            return ParseLoopPasses(name, sccPm, options);
62        });
63    }
64private:
65    ark::llvmbackend::LLVMArkInterface *arkInterface_;
66};
67
68bool PassParser::ParseModulePasses(StringRef name, llvm::ModulePassManager &modulePm, const LLVMCompilerOptions &options)
69{
70    auto &pm = modulePm;
71    namespace pass = <%= PassRegistry::passes_namespace %>;
72
73% PassRegistry::llvm_passes.select{|p| p.type.include? 'module'}.each do |pass|
74    if (name.equals(pass::<%= pass.name %>::ARG_NAME)) {
75        if (pass::<%= pass.name %>::ShouldInsert(&options)) {
76% if pass.setup == 'default'
77            pm.addPass(pass::<%= pass.name %>());
78% else
79            pm.addPass(pass::<%= pass.name %>::Create(arkInterface_, &options));
80% end
81#ifndef NDEBUG
82            pm.addPass(llvm::VerifierPass());
83#endif
84        }
85        return true;
86    }
87% end
88
89    return false;
90}
91
92bool PassParser::ParseFunctionPasses(StringRef name, llvm::FunctionPassManager &functionPm, const LLVMCompilerOptions &options)
93{
94    auto &pm = functionPm;
95    namespace pass = <%= PassRegistry::passes_namespace %>;
96
97% PassRegistry::llvm_passes.select{|p| p.type.include? 'function'}.each do |pass|
98    if (name.equals(pass::<%= pass.name %>::ARG_NAME)) {
99        if (pass::<%= pass.name %>::ShouldInsert(&options)) {
100% if pass.setup == 'default'
101            pm.addPass(pass::<%= pass.name %>());
102% else
103            pm.addPass(pass::<%= pass.name %>::Create(arkInterface_, &options));
104% end
105#ifndef NDEBUG
106            pm.addPass(llvm::VerifierPass());
107#endif
108        }
109        return true;
110    }
111% end
112
113    return false;
114}
115
116bool PassParser::ParseSCCPasses(StringRef name, llvm::CGSCCPassManager &sccPm, const LLVMCompilerOptions &options)
117{
118    auto &pm = sccPm;
119    namespace pass = <%= PassRegistry::passes_namespace %>;
120
121% PassRegistry::llvm_passes.select{|p| p.type.include? 'scc'}.each do |pass|
122    if (name.equals(pass::<%= pass.name %>::ARG_NAME)) {
123        if (pass::<%= pass.name %>::ShouldInsert(&options)) {
124% if pass.setup == 'default'
125            pm.addPass(pass::<%= pass.name %>());
126% else
127            pm.addPass(pass::<%= pass.name %>::Create(arkInterface_, &options));
128% end
129        }
130        return true;
131    }
132% end
133
134    return false;
135}
136
137bool PassParser::ParseLoopPasses(StringRef name, llvm::LoopPassManager &loopPm, const LLVMCompilerOptions &options)
138{
139    auto &pm = loopPm;
140    namespace pass = <%= PassRegistry::passes_namespace %>;
141
142% PassRegistry::llvm_passes.select{|p| p.type.include? 'loop'}.each do |pass|
143    if (name.equals(pass::<%= pass.name %>::ARG_NAME)) {
144        if (pass::<%= pass.name %>::ShouldInsert(&options)) {
145% if pass.setup == 'default'
146            pm.addPass(pass::<%= pass.name %>());
147% else
148            pm.addPass(pass::<%= pass.name %>::Create(arkInterface_, &options));
149% end
150        }
151        return true;
152    }
153% end
154
155    return false;
156}
157
158}  // namespace ark::libllvmbackend
159