• 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 
16 #ifndef MAPLEBE_INCLUDE_CG_CG_H
17 #define MAPLEBE_INCLUDE_CG_CG_H
18 
19 /* C++ headers. */
20 #include <cstddef>
21 #include <string>
22 /* MapleIR headers. */
23 #include "operand.h"
24 #include "insn.h"
25 #include "cgfunc.h"
26 #include "live.h"
27 #include "cg_option.h"
28 #include "opcode_info.h"
29 #include "global_tables.h"
30 #include "mir_function.h"
31 #include "mad.h"
32 #include "target_machine.h"
33 #include "proepilog.h"
34 #include "mir_builder.h"
35 namespace maplebe {
36 #define ADDTARGETPHASE(PhaseName, condition)  \
37     if (!CGOptions::IsSkipPhase(PhaseName)) { \
38         pm->AddPhase(PhaseName, condition);   \
39     }
40 /* subtarget opt phase -- cyclic Dependency, use Forward declaring */
41 class DomAnalysis;
42 class MoveRegArgs;
43 class MPISel;
44 class Standardize;
45 class CG;
46 class CFGOptimizer;
47 class CGPeepHole;
48 class GenProEpilog;
49 class LoopAnalysis;
50 
51 class Globals {
52 public:
GetInstance()53     static Globals *GetInstance()
54     {
55         static Globals instance;
56         return &instance;
57     }
58 
59     ~Globals() = default;
60 
SetBECommon(BECommon & bc)61     void SetBECommon(BECommon &bc)
62     {
63         beCommon = &bc;
64     }
65 
GetBECommon()66     BECommon *GetBECommon()
67     {
68         return beCommon;
69     }
70 
GetBECommon()71     const BECommon *GetBECommon() const
72     {
73         return beCommon;
74     }
75 
SetOptimLevel(int32 opLevel)76     void SetOptimLevel(int32 opLevel)
77     {
78         optimLevel = opLevel;
79     }
80 
GetOptimLevel()81     int32 GetOptimLevel() const
82     {
83         return optimLevel;
84     }
85 
86     void SetTarget(CG &target);
87     const CG *GetTarget() const;
88 
89 private:
90     BECommon *beCommon = nullptr;
91     int32 optimLevel = 0;
92     CG *cg = nullptr;
93     Globals() = default;
94 };
95 
96 class GCTIBKey {
97 public:
GCTIBKey(MapleAllocator & allocator,uint32 rcHeader,const std::vector<uint64> & patternWords)98     GCTIBKey(MapleAllocator &allocator, uint32 rcHeader, const std::vector<uint64> &patternWords)
99         : header(rcHeader),
100           bitMapWords(allocator.Adapter())
101     {
102         (void)bitMapWords.insert(bitMapWords.cbegin(), patternWords.cbegin(), patternWords.cend());
103     }
104 
105     ~GCTIBKey() = default;
106 
GetHeader()107     uint32 GetHeader() const
108     {
109         return header;
110     }
111 
GetBitmapWords()112     const MapleVector<uint64> &GetBitmapWords() const
113     {
114         return bitMapWords;
115     }
116 
117 private:
118     uint32 header;
119     MapleVector<uint64> bitMapWords;
120 };
121 
122 class Hasher {
123 public:
operator()124     size_t operator()(const GCTIBKey *key) const
125     {
126         CHECK_NULL_FATAL(key);
127         size_t hash = key->GetHeader();
128         return hash;
129     }
130 };
131 
132 class EqualFn {
133 public:
operator()134     bool operator()(const GCTIBKey *firstKey, const GCTIBKey *secondKey) const
135     {
136         CHECK_NULL_FATAL(firstKey);
137         CHECK_NULL_FATAL(secondKey);
138         const MapleVector<uint64> &firstWords = firstKey->GetBitmapWords();
139         const MapleVector<uint64> &secondWords = secondKey->GetBitmapWords();
140 
141         if ((firstKey->GetHeader() != secondKey->GetHeader()) || (firstWords.size() != secondWords.size())) {
142             return false;
143         }
144 
145         for (size_t i = 0; i < firstWords.size(); ++i) {
146             if (firstWords[i] != secondWords[i]) {
147                 return false;
148             }
149         }
150         return true;
151     }
152 };
153 
154 class GCTIBPattern {
155 public:
GCTIBPattern(GCTIBKey & patternKey,MemPool & mp)156     GCTIBPattern(GCTIBKey &patternKey, MemPool &mp)
157         : name(&mp)
158     {
159         key = &patternKey;
160         id = GetId();
161         name = GCTIB_PREFIX_STR + std::string("PTN_") + std::to_string(id);
162     }
163 
164     ~GCTIBPattern() = default;
165 
GetId()166     int GetId() const
167     {
168         static int createNum = 0;
169         return createNum++;
170     }
171 
GetName()172     std::string GetName() const
173     {
174         return std::string(name.c_str());
175     }
176 
SetName(const std::string & ptnName)177     void SetName(const std::string &ptnName)
178     {
179         name = ptnName;
180     }
181 
182 private:
183     int id = 0;
184     MapleString name;
185     GCTIBKey *key = nullptr;
186 };
187 
188 class CG {
189 public:
190     using GenerateFlag = uint64;
191 
192 public:
CG(MIRModule & mod,const CGOptions & cgOptions)193     CG(MIRModule &mod, const CGOptions &cgOptions)
194         : memPool(memPoolCtrler.NewMemPool("maplecg mempool", false /* isLocalPool */)),
195           allocator(memPool),
196           mirModule(&mod),
197           cgOption(cgOptions)
198     {
199         isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc);
200     }
201 
202     virtual ~CG();
203 
204     /* enroll all code generator phases for target machine */
205     virtual void EnrollTargetPhases(MaplePhaseManager *pm) const = 0;
206 
207     virtual PhiOperand &CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator) = 0;
208 
209     virtual CGFunc *CreateCGFunc(MIRModule &mod, MIRFunction &, BECommon &, MemPool &, StackMemPool &, MapleAllocator &,
210                                  uint32) = 0;
211 
212     virtual bool IsExclusiveFunc(MIRFunction &mirFunc) = 0;
213 
214 #ifdef ARK_LITECG_DEBUG
215     /* Used for GCTIB pattern merging */
216     virtual std::string FindGCTIBPatternName(const std::string &name) const = 0;
217 #endif
218 
GenerateVerboseAsm()219     bool GenerateVerboseAsm() const
220     {
221         return cgOption.GenerateVerboseAsm();
222     }
223 
GenerateVerboseCG()224     bool GenerateVerboseCG() const
225     {
226         return cgOption.GenerateVerboseCG();
227     }
228 
DoTailCall()229     bool DoTailCall() const
230     {
231         return cgOption.DoTailCall();
232     }
233 
GenerateDebugFriendlyCode()234     bool GenerateDebugFriendlyCode() const
235     {
236         return cgOption.GenerateDebugFriendlyCode();
237     }
238 
GetOptimizeLevel()239     int32 GetOptimizeLevel() const
240     {
241         return cgOption.GetOptimizeLevel();
242     }
243 
UseFastUnwind()244     bool UseFastUnwind() const
245     {
246         return true;
247     }
248 
GenYieldPoint()249     bool GenYieldPoint() const
250     {
251         return cgOption.GenYieldPoint();
252     }
253 
GenLocalRC()254     bool GenLocalRC() const
255     {
256         return cgOption.GenLocalRC();
257     }
258 
GenerateExceptionHandlingCode()259     bool GenerateExceptionHandlingCode() const
260     {
261         return cgOption.GenerateExceptionHandlingCode();
262     }
263 
GetMIRModule()264     MIRModule *GetMIRModule()
265     {
266         return mirModule;
267     }
268 
SetObjEmitter(Emitter & emitter)269     void SetObjEmitter(Emitter &emitter)
270     {
271         DEBUG_ASSERT(emitters.empty(), "ObjEmitter already exist");
272         emitters.push_back(&emitter);
273     }
274 
SetAsmEmitter(Emitter & emitter)275     void SetAsmEmitter(Emitter &emitter)
276     {
277         DEBUG_ASSERT(emitters.size() == 1U, "AsmEmitter need to be added after objEmmiter");
278         emitters.push_back(&emitter);
279     }
280 
281     enum EmitterType: uint8_t {
282         ObjEmiter = 0,
283         AsmEmitter = 1,
284         All
285     };
286 
287     // NOTE: It's would de better to remove EmmiterType and always use EmitterType::All,
288     //       but it's need to unify interfaces. It's better because, it's harder to make a error.
289     template <EmitterType emitType = EmitterType::All>
Emit(const std::function<void (Emitter *)> & cb)290     void Emit(const std::function<void(Emitter*)> &cb) const
291     {
292         if constexpr (emitType == EmitterType::All) {
293             EmitAllEmitters(cb);
294         } else if constexpr (emitType == EmitterType::AsmEmitter) {
295             EmitAsmEmitters(cb);
296         } else if constexpr (emitType == EmitterType::ObjEmiter) {
297             EmitObjEmitters(cb);
298         }
299     }
300 
GetMIRModule()301     MIRModule *GetMIRModule() const
302     {
303         return mirModule;
304     }
305 
SetTargetMachine(TargetMachine & targetMachine)306     void SetTargetMachine(TargetMachine &targetMachine)
307     {
308         this->targetMachine = &targetMachine;
309     }
310 
GetTargetMachine()311     TargetMachine *GetTargetMachine() const
312     {
313         return targetMachine;
314     }
315 
IncreaseLabelOrderCnt()316     void IncreaseLabelOrderCnt()
317     {
318         labelOrderCnt++;
319     }
320 
GetLabelOrderCnt()321     LabelIDOrder GetLabelOrderCnt() const
322     {
323         return labelOrderCnt;
324     }
325 
GetCGOptions()326     const CGOptions &GetCGOptions() const
327     {
328         return cgOption;
329     }
330 
UpdateCGOptions(const CGOptions & newOption)331     void UpdateCGOptions(const CGOptions &newOption)
332     {
333         cgOption.SetOptionFlag(newOption.GetOptionFlag());
334     }
335 
IsLibcore()336     bool IsLibcore() const
337     {
338         return isLibcore;
339     }
340 
IsLmbc()341     bool IsLmbc() const
342     {
343         return isLmbc;
344     }
345 
GetDebugTraceEnterFunction()346     MIRSymbol *GetDebugTraceEnterFunction()
347     {
348         return dbgTraceEnter;
349     }
350 
GetDebugTraceEnterFunction()351     const MIRSymbol *GetDebugTraceEnterFunction() const
352     {
353         return dbgTraceEnter;
354     }
355 
GetProfileFunction()356     MIRSymbol *GetProfileFunction()
357     {
358         return dbgFuncProfile;
359     }
360 
GetProfileFunction()361     const MIRSymbol *GetProfileFunction() const
362     {
363         return dbgFuncProfile;
364     }
365 
GetDebugTraceExitFunction()366     const MIRSymbol *GetDebugTraceExitFunction() const
367     {
368         return dbgTraceExit;
369     }
370 
371     /* Init SubTarget phase */
CreateLiveAnalysis(MemPool & mp,CGFunc & f)372     virtual LiveAnalysis *CreateLiveAnalysis(MemPool &mp, CGFunc &f) const
373     {
374         return nullptr;
375     };
376     virtual GenProEpilog *CreateGenProEpilog(CGFunc &func, MemPool &mp, MemPool *tempMemPool = nullptr) const = 0;
377     virtual CGPeepHole *CreateCGPeepHole(MemPool &mp, CGFunc &f) const = 0;
CreateMoveRegArgs(MemPool & mp,CGFunc & f)378     virtual MoveRegArgs *CreateMoveRegArgs(MemPool &mp, CGFunc &f) const
379     {
380         return nullptr;
381     };
CreateMPIsel(MemPool & mp,MapleAllocator & allocator,CGFunc & f)382     virtual MPISel *CreateMPIsel(MemPool &mp, MapleAllocator &allocator, CGFunc &f) const
383     {
384         return nullptr;
385     }
CreateStandardize(MemPool & mp,CGFunc & f)386     virtual Standardize *CreateStandardize(MemPool &mp, CGFunc &f) const
387     {
388         return nullptr;
389     }
390     virtual CFGOptimizer *CreateCFGOptimizer(MemPool &mp, CGFunc &f, LoopAnalysis &loop) const = 0;
391 
SetGP(MIRSymbol * sym)392     void SetGP(MIRSymbol *sym)
393     {
394         fileGP = sym;
395     }
GetGP()396     MIRSymbol *GetGP() const
397     {
398         return fileGP;
399     }
400 
IsInFuncWrapLabels(MIRFunction * func)401     static bool IsInFuncWrapLabels(MIRFunction *func)
402     {
403         return funcWrapLabels.find(func) != funcWrapLabels.end();
404     }
405 
SetFuncWrapLabels(MIRFunction * func,const std::pair<LabelIdx,LabelIdx> labels)406     static void SetFuncWrapLabels(MIRFunction *func, const std::pair<LabelIdx, LabelIdx> labels)
407     {
408         if (!IsInFuncWrapLabels(func)) {
409             funcWrapLabels[func] = labels;
410         }
411     }
412 
GetFuncWrapLabels()413     static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> &GetFuncWrapLabels()
414     {
415         return funcWrapLabels;
416     }
SetCurCGFunc(CGFunc & cgFunc)417     static void SetCurCGFunc(CGFunc &cgFunc)
418     {
419         currentCGFunction = &cgFunc;
420     }
421 
GetCurCGFunc()422     static const CGFunc *GetCurCGFunc()
423     {
424         return currentCGFunction;
425     }
426 
GetCurCGFuncNoConst()427     static CGFunc *GetCurCGFuncNoConst()
428     {
429         return currentCGFunction;
430     }
431 
432     virtual const InsnDesc &GetTargetMd(MOperator mOp) const = 0;
433     virtual bool IsEffectiveCopy(Insn &insn) const = 0;
434     virtual bool IsTargetInsn(MOperator mOp) const = 0;
435     virtual bool IsClinitInsn(MOperator mOp) const = 0;
436     virtual bool IsPseudoInsn(MOperator mOp) const = 0;
437     virtual void DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const = 0;
438 
439 protected:
440     MemPool *memPool;
441     MapleAllocator allocator;
442 
443 private:
444     void EmitAllEmitters(const std::function<void(Emitter *)>& cb) const;
445     void EmitAsmEmitters(const std::function<void(Emitter *)>& cb) const;
446     void EmitObjEmitters(const std::function<void(Emitter *)>& cb) const;
447 
448 private:
449     MIRModule *mirModule;
450     std::vector<Emitter *> emitters;
451     TargetMachine *targetMachine = nullptr;
452     LabelIDOrder labelOrderCnt = 0;
453     static CGFunc *currentCGFunction; /* current cg function being compiled */
454     CGOptions cgOption;
455     MIRSymbol *dbgTraceEnter = nullptr;
456     MIRSymbol *dbgTraceExit = nullptr;
457     MIRSymbol *dbgFuncProfile = nullptr;
458     MIRSymbol *fileGP = nullptr; /* for lmbc, one local %GP per file */
459     static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> funcWrapLabels;
460     bool isLibcore = false;
461     bool isLmbc;
462 }; /* class CG */
463 } /* namespace maplebe */
464 
465 #endif /* MAPLEBE_INCLUDE_CG_CG_H */
466