• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 #ifndef MAPLEBE_INCLUDE_TARGET_REGISTRY_H
16 #define MAPLEBE_INCLUDE_TARGET_REGISTRY_H
17 #include "types_def.h"
18 #include "cg.h"
19 #if TARGX86_64
20 #include "x86_64/assembler/assembler.h"
21 #endif
22 #include "target_machine.h"
23 #include "mempool.h"
24 
25 
26 namespace maplebe {
27 using namespace maple;
28 class TargetMachine;
29 class Target {
30 using CGCtorFnTy = CG *(*)(MIRModule &mod, const CGOptions &opts, const std::vector<std::string> &nameVec,
31                                    const std::unordered_map<std::string, std::vector<std::string>> &patternMap);
32 using EmitterCtorFnTy = std::function<Emitter*(CG&, const std::string&)>;
33 #if TARGX86_64
34 using DecoupledEmitterCtorFnTy = std::function<Emitter*(CG &cg, assembler::Assembler &newAssembler)>;
35 #endif
36 using TargetMachineCtorFnTy = std::function<TargetMachine*()>;
37 friend struct TargetRegistry;
38 
39 public:
40     Target() = default;
41 
getNext()42     const Target *getNext() const
43     {
44         return next;
45     }
46 
getName()47     const std::string getName() const
48     {
49         return name;
50     }
51 
createCG(MIRModule & mod,const CGOptions & opts,const std::vector<std::string> & nameVec,const std::unordered_map<std::string,std::vector<std::string>> & patternMap)52     CG *createCG(MIRModule &mod, const CGOptions &opts, const std::vector<std::string> &nameVec,
53         const std::unordered_map<std::string, std::vector<std::string>> &patternMap) const
54     {
55         if (!CGCtorFn) {
56             return nullptr;
57         }
58         return CGCtorFn(mod, opts, nameVec, patternMap);
59     }
60 
createEmitter(CG & cg,const std::string & asmFileName)61     Emitter *createEmitter(CG &cg, const std::string &asmFileName) const
62     {
63         if (!EmitterCtorFn) {
64             return nullptr;
65         }
66         return EmitterCtorFn(cg, asmFileName);
67     }
68 
69 #if TARGX86_64
createDecoupledEmitter(CG & cg,assembler::Assembler & newAssembler)70     Emitter *createDecoupledEmitter(CG &cg, assembler::Assembler &newAssembler) const
71     {
72         if (!DecoupedEmitterCtorFn) {
73             return nullptr;
74         }
75         return DecoupedEmitterCtorFn(cg, newAssembler);
76     }
77 #endif
createTargetMachine()78     TargetMachine *createTargetMachine() const
79     {
80         if (!TargetMachineCtorFn) {
81             return nullptr;
82         }
83         return TargetMachineCtorFn();
84     }
85 
86 private:
87     // Next - The next registered target in the linked list, maintained by the
88     // TargetRegistry.
89     Target *next = nullptr;
90     // Name - The target name.
91     std::string name;
92     // Construction function for this target's CG, if
93     // registered (default = nullptr).
94     CGCtorFnTy CGCtorFn;
95     // Construction function for this target's Emitter, if
96     // registered (default = nullptr).
97     EmitterCtorFnTy EmitterCtorFn;
98 #if TARGX86_64
99     // Construction function for this target's DecoupledEmitter, if
100     // registered (default = nullptr).
101     DecoupledEmitterCtorFnTy DecoupedEmitterCtorFn;
102 #endif
103     // Construction function for this target's TargetMachine, if
104     // registered (default = nullptr).
105     TargetMachineCtorFnTy TargetMachineCtorFn;
106 };
107 
108 struct TargetRegistry {
109     TargetRegistry() = delete;
110     static void RegisterTarget(Target &t, const std::string name);
111     static Target *lookupTarget(const std::string &targetName);
112 
RegisterCGFuncTargetRegistry113     static void RegisterCGFunc(Target &t, Target::CGCtorFnTy Fn)
114     {
115         t.CGCtorFn = Fn;
116     }
117 
RegisterEmitterTargetRegistry118     static void RegisterEmitter(Target &t, Target::EmitterCtorFnTy Fn)
119     {
120         t.EmitterCtorFn = Fn;
121     }
122 #if TARGX86_64
RegisterDecoupledEmitterTargetRegistry123     static void RegisterDecoupledEmitter(Target &t, Target::DecoupledEmitterCtorFnTy Fn)
124     {
125         t.DecoupedEmitterCtorFn = Fn;
126     }
127 #endif
RegisterTargetMachineTargetRegistry128     static void RegisterTargetMachine(Target &t, Target::TargetMachineCtorFnTy Fn)
129     {
130         t.TargetMachineCtorFn = Fn;
131     }
132 };
133 
134 
135 struct RegisterTarget {
RegisterTargetRegisterTarget136     RegisterTarget(Target &t, const std::string name)
137     {
138         TargetRegistry::RegisterTarget(t, name);
139     }
140 };
141 
142 template <class CGImpl>
143 struct RegisterCGFUnc {
RegisterCGFUncRegisterCGFUnc144     RegisterCGFUnc(Target &T)
145     {
146         TargetRegistry::RegisterCGFunc(T, &Allocator);
147     }
148 
149 private:
AllocatorRegisterCGFUnc150     static CG *Allocator(MIRModule &mod, const CGOptions &opts, const std::vector<std::string> &nameVec,
151                          const std::unordered_map<std::string, std::vector<std::string>> &patternMap)
152     {
153         return new CGImpl(mod, opts, nameVec, patternMap);
154     }
155 };
156 
157 template <class EmitterImpl>
158 struct RegisterEmitter {
RegisterEmitterRegisterEmitter159     RegisterEmitter(Target &T, MemPool *m)
160     {
161         std::function<Emitter*(CG&, const std::string&)> Allocator = [m](CG &cg, const std::string &asmFileName) {
162             return m->New<EmitterImpl>(cg, asmFileName);
163         };
164         TargetRegistry::RegisterEmitter(T, Allocator);
165     }
166 };
167 
168 #if TARGX86_64
169 template <class DecoupledEmitterImpl>
170 struct RegisterDecoupledEmitter {
RegisterDecoupledEmitterRegisterDecoupledEmitter171     RegisterDecoupledEmitter(Target &T, MemPool *m)
172     {
173         std::function<Emitter*(CG &cg, assembler::Assembler &newAssembler)> Allocator = [m](CG &cg,
174             assembler::Assembler &newAssembler) {
175             return m->New<DecoupledEmitterImpl>(cg, newAssembler);
176         };
177         TargetRegistry::RegisterDecoupledEmitter(T, Allocator);
178     }
179 };
180 #endif
181 
182 template <class TargetMachineImpl>
183 struct RegisterTargetMachine {
RegisterTargetMachineRegisterTargetMachine184     RegisterTargetMachine(Target &T, MemPool *m)
185     {
186         std::function<TargetMachine*()> Allocator = [m]() {
187             return m->New<TargetMachineImpl>();
188         };
189         TargetRegistry::RegisterTargetMachine(T, Allocator);
190     }
191 };
192 
193 }  /* namespace maplebe */
194 
195 #endif  /* MAPLEBE_INCLUDE_TARGET_REGISTRY_H */
196