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