• 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 
33 namespace maplebe {
34 #define ADDTARGETPHASE(PhaseName, condition)  \
35     if (!CGOptions::IsSkipPhase(PhaseName)) { \
36         pm->AddPhase(PhaseName, condition);   \
37     }
38 /* subtarget opt phase -- cyclic Dependency, use Forward declaring */
39 class CGSSAInfo;
40 class PhiEliminate;
41 class DomAnalysis;
42 class CGProp;
43 class CGDce;
44 class AlignAnalysis;
45 class MoveRegArgs;
46 class MPISel;
47 class Standardize;
48 class LiveIntervalAnalysis;
49 class ValidBitOpt;
50 class CG;
51 class LocalOpt;
52 class CFGOptimizer;
53 
54 class Globals {
55 public:
GetInstance()56     static Globals *GetInstance()
57     {
58         static Globals instance;
59         return &instance;
60     }
61 
62     ~Globals() = default;
63 
SetBECommon(BECommon & bc)64     void SetBECommon(BECommon &bc)
65     {
66         beCommon = &bc;
67     }
68 
GetBECommon()69     BECommon *GetBECommon()
70     {
71         return beCommon;
72     }
73 
GetBECommon()74     const BECommon *GetBECommon() const
75     {
76         return beCommon;
77     }
78 
SetMAD(MAD & m)79     void SetMAD(MAD &m)
80     {
81         mad = &m;
82     }
83 
GetMAD()84     MAD *GetMAD()
85     {
86         return mad;
87     }
88 
GetMAD()89     const MAD *GetMAD() const
90     {
91         return mad;
92     }
93 
SetOptimLevel(int32 opLevel)94     void SetOptimLevel(int32 opLevel)
95     {
96         optimLevel = opLevel;
97     }
98 
GetOptimLevel()99     int32 GetOptimLevel() const
100     {
101         return optimLevel;
102     }
103 
104     void SetTarget(CG &target);
105     const CG *GetTarget() const;
106 
107 private:
108     BECommon *beCommon = nullptr;
109     MAD *mad = nullptr;
110     int32 optimLevel = 0;
111     CG *cg = nullptr;
112     Globals() = default;
113 };
114 
115 class CG {
116 public:
117     using GenerateFlag = uint64;
118 
119 public:
CG(MIRModule & mod,const CGOptions & cgOptions)120     CG(MIRModule &mod, const CGOptions &cgOptions)
121         : memPool(memPoolCtrler.NewMemPool("maplecg mempool", false /* isLocalPool */)),
122           allocator(memPool),
123           mirModule(&mod),
124           emitter(nullptr),
125           labelOrderCnt(0),
126           cgOption(cgOptions),
127           instrumentationFunction(nullptr),
128           fileGP(nullptr)
129     {
130         const std::string &internalNameLiteral = namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr);
131         GStrIdx strIdxFromName = GlobalTables::GetStrTable().GetStrIdxFromName(internalNameLiteral);
132         isLibcore = (GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdxFromName) != nullptr);
133         DefineDebugTraceFunctions();
134         isLmbc = (mirModule->GetFlavor() == MIRFlavor::kFlavorLmbc);
135     }
136 
137     virtual ~CG();
138 
139     /* enroll all code generator phases for target machine */
140     virtual void EnrollTargetPhases(MaplePhaseManager *pm) const = 0;
141 
142     void GenExtraTypeMetadata(const std::string &classListFileName, const std::string &outputBaseName);
143     void GenPrimordialObjectList(const std::string &outputBaseName);
144     const std::string ExtractFuncName(const std::string &str);
145 
146     virtual Insn &BuildPhiInsn(RegOperand &defOpnd, Operand &listParam) = 0;
147     virtual PhiOperand &CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator) = 0;
148 
149     virtual CGFunc *CreateCGFunc(MIRModule &mod, MIRFunction &, BECommon &, MemPool &, StackMemPool &, MapleAllocator &,
150                                  uint32) = 0;
151 
IsExclusiveEH()152     bool IsExclusiveEH() const
153     {
154         return CGOptions::IsExclusiveEH();
155     }
156 
157     virtual bool IsExclusiveFunc(MIRFunction &mirFunc) = 0;
158 
159     /* NOTE: Consider making be_common a field of CG. */
160     virtual void GenerateObjectMaps(BECommon &beCommon) = 0;
161 
162     /* Used for GCTIB pattern merging */
163     virtual std::string FindGCTIBPatternName(const std::string &name) const = 0;
164 
GenerateVerboseAsm()165     bool GenerateVerboseAsm() const
166     {
167         return cgOption.GenerateVerboseAsm();
168     }
169 
GenerateVerboseCG()170     bool GenerateVerboseCG() const
171     {
172         return cgOption.GenerateVerboseCG();
173     }
174 
DoPrologueEpilogue()175     bool DoPrologueEpilogue() const
176     {
177         return cgOption.DoPrologueEpilogue();
178     }
179 
DoTailCall()180     bool DoTailCall() const
181     {
182         return cgOption.DoTailCall();
183     }
184 
DoCheckSOE()185     bool DoCheckSOE() const
186     {
187         return cgOption.DoCheckSOE();
188     }
189 
GenerateDebugFriendlyCode()190     bool GenerateDebugFriendlyCode() const
191     {
192         return cgOption.GenerateDebugFriendlyCode();
193     }
194 
GetOptimizeLevel()195     int32 GetOptimizeLevel() const
196     {
197         return cgOption.GetOptimizeLevel();
198     }
199 
UseFastUnwind()200     bool UseFastUnwind() const
201     {
202         return true;
203     }
204 
IsStackProtectorStrong()205     bool IsStackProtectorStrong() const
206     {
207         return cgOption.IsStackProtectorStrong();
208     }
209 
IsStackProtectorAll()210     bool IsStackProtectorAll() const
211     {
212         return cgOption.IsStackProtectorAll();
213     }
214 
NeedInsertInstrumentationFunction()215     bool NeedInsertInstrumentationFunction() const
216     {
217         return cgOption.NeedInsertInstrumentationFunction();
218     }
219 
220     void SetInstrumentationFunction(const std::string &name);
GetInstrumentationFunction()221     const MIRSymbol *GetInstrumentationFunction() const
222     {
223         return instrumentationFunction;
224     }
225 
InstrumentWithDebugTraceCall()226     bool InstrumentWithDebugTraceCall() const
227     {
228         return cgOption.InstrumentWithDebugTraceCall();
229     }
230 
InstrumentWithProfile()231     bool InstrumentWithProfile() const
232     {
233         return cgOption.InstrumentWithProfile();
234     }
235 
DoPatchLongBranch()236     bool DoPatchLongBranch() const
237     {
238         return cgOption.DoPatchLongBranch();
239     }
240 
GetRematLevel()241     uint8 GetRematLevel() const
242     {
243         return CGOptions::GetRematLevel();
244     }
245 
GenYieldPoint()246     bool GenYieldPoint() const
247     {
248         return cgOption.GenYieldPoint();
249     }
250 
GenLocalRC()251     bool GenLocalRC() const
252     {
253         return cgOption.GenLocalRC();
254     }
255 
GenerateExceptionHandlingCode()256     bool GenerateExceptionHandlingCode() const
257     {
258         return cgOption.GenerateExceptionHandlingCode();
259     }
260 
DoConstFold()261     bool DoConstFold() const
262     {
263         return cgOption.DoConstFold();
264     }
265 
266     void AddStackGuardvar();
267     void DefineDebugTraceFunctions();
GetMIRModule()268     MIRModule *GetMIRModule()
269     {
270         return mirModule;
271     }
272 
SetEmitter(Emitter & emitter)273     void SetEmitter(Emitter &emitter)
274     {
275         this->emitter = &emitter;
276     }
277 
GetEmitter()278     Emitter *GetEmitter() const
279     {
280         return emitter;
281     }
282 
GetMIRModule()283     MIRModule *GetMIRModule() const
284     {
285         return mirModule;
286     }
287 
IncreaseLabelOrderCnt()288     void IncreaseLabelOrderCnt()
289     {
290         labelOrderCnt++;
291     }
292 
GetLabelOrderCnt()293     LabelIDOrder GetLabelOrderCnt() const
294     {
295         return labelOrderCnt;
296     }
297 
GetCGOptions()298     const CGOptions &GetCGOptions() const
299     {
300         return cgOption;
301     }
302 
UpdateCGOptions(const CGOptions & newOption)303     void UpdateCGOptions(const CGOptions &newOption)
304     {
305         cgOption.SetOptionFlag(newOption.GetOptionFlag());
306     }
307 
IsLibcore()308     bool IsLibcore() const
309     {
310         return isLibcore;
311     }
312 
IsLmbc()313     bool IsLmbc() const
314     {
315         return isLmbc;
316     }
317 
GetDebugTraceEnterFunction()318     MIRSymbol *GetDebugTraceEnterFunction()
319     {
320         return dbgTraceEnter;
321     }
322 
GetDebugTraceEnterFunction()323     const MIRSymbol *GetDebugTraceEnterFunction() const
324     {
325         return dbgTraceEnter;
326     }
327 
GetProfileFunction()328     MIRSymbol *GetProfileFunction()
329     {
330         return dbgFuncProfile;
331     }
332 
GetProfileFunction()333     const MIRSymbol *GetProfileFunction() const
334     {
335         return dbgFuncProfile;
336     }
337 
GetDebugTraceExitFunction()338     const MIRSymbol *GetDebugTraceExitFunction() const
339     {
340         return dbgTraceExit;
341     }
342 
343     /* Init SubTarget phase */
CreateLiveAnalysis(MemPool & mp,CGFunc & f)344     virtual LiveAnalysis *CreateLiveAnalysis(MemPool &mp, CGFunc &f) const
345     {
346         return nullptr;
347     };
CreateReachingDefinition(MemPool & mp,CGFunc & f)348     virtual ReachingDefinition *CreateReachingDefinition(MemPool &mp, CGFunc &f) const
349     {
350         return nullptr;
351     };
CreateMoveRegArgs(MemPool & mp,CGFunc & f)352     virtual MoveRegArgs *CreateMoveRegArgs(MemPool &mp, CGFunc &f) const
353     {
354         return nullptr;
355     };
CreateAlignAnalysis(MemPool & mp,CGFunc & f)356     virtual AlignAnalysis *CreateAlignAnalysis(MemPool &mp, CGFunc &f) const
357     {
358         return nullptr;
359     };
CreateMPIsel(MemPool & mp,MapleAllocator & allocator,CGFunc & f)360     virtual MPISel *CreateMPIsel(MemPool &mp, MapleAllocator &allocator, CGFunc &f) const
361     {
362         return nullptr;
363     }
CreateStandardize(MemPool & mp,CGFunc & f)364     virtual Standardize *CreateStandardize(MemPool &mp, CGFunc &f) const
365     {
366         return nullptr;
367     }
CreateValidBitOpt(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)368     virtual ValidBitOpt *CreateValidBitOpt(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const
369     {
370         return nullptr;
371     }
372 
373     /* Init SubTarget optimization */
CreateCGSSAInfo(MemPool & mp,CGFunc & f,DomAnalysis & da,MemPool & tmp)374     virtual CGSSAInfo *CreateCGSSAInfo(MemPool &mp, CGFunc &f, DomAnalysis &da, MemPool &tmp) const
375     {
376         return nullptr;
377     };
CreateLLAnalysis(MemPool & mp,CGFunc & f)378     virtual LiveIntervalAnalysis *CreateLLAnalysis(MemPool &mp, CGFunc &f) const
379     {
380         return nullptr;
381     };
CreatePhiElimintor(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)382     virtual PhiEliminate *CreatePhiElimintor(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const
383     {
384         return nullptr;
385     };
CreateCGProp(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo,LiveIntervalAnalysis & ll)386     virtual CGProp *CreateCGProp(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo, LiveIntervalAnalysis &ll) const
387     {
388         return nullptr;
389     };
CreateCGDce(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)390     virtual CGDce *CreateCGDce(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const
391     {
392         return nullptr;
393     };
CreateLocalOpt(MemPool & mp,CGFunc & f,ReachingDefinition &)394     virtual LocalOpt *CreateLocalOpt(MemPool &mp, CGFunc &f, ReachingDefinition &) const
395     {
396         return nullptr;
397     };
CreateCFGOptimizer(MemPool & mp,CGFunc & f)398     virtual CFGOptimizer *CreateCFGOptimizer(MemPool &mp, CGFunc &f) const
399     {
400         return nullptr;
401     }
402 
403     /* Object map generation helper */
404     std::vector<int64> GetReferenceOffsets64(const BECommon &beCommon, MIRStructType &structType);
405 
SetGP(MIRSymbol * sym)406     void SetGP(MIRSymbol *sym)
407     {
408         fileGP = sym;
409     }
GetGP()410     MIRSymbol *GetGP() const
411     {
412         return fileGP;
413     }
414 
IsInFuncWrapLabels(MIRFunction * func)415     static bool IsInFuncWrapLabels(MIRFunction *func)
416     {
417         return funcWrapLabels.find(func) != funcWrapLabels.end();
418     }
419 
SetFuncWrapLabels(MIRFunction * func,const std::pair<LabelIdx,LabelIdx> labels)420     static void SetFuncWrapLabels(MIRFunction *func, const std::pair<LabelIdx, LabelIdx> labels)
421     {
422         if (!IsInFuncWrapLabels(func)) {
423             funcWrapLabels[func] = labels;
424         }
425     }
426 
GetFuncWrapLabels()427     static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> &GetFuncWrapLabels()
428     {
429         return funcWrapLabels;
430     }
SetCurCGFunc(CGFunc & cgFunc)431     static void SetCurCGFunc(CGFunc &cgFunc)
432     {
433         currentCGFunction = &cgFunc;
434     }
435 
GetCurCGFunc()436     static const CGFunc *GetCurCGFunc()
437     {
438         return currentCGFunction;
439     }
440 
GetCurCGFuncNoConst()441     static CGFunc *GetCurCGFuncNoConst()
442     {
443         return currentCGFunction;
444     }
445 
446     virtual const InsnDesc &GetTargetMd(MOperator mOp) const = 0;
447     virtual bool IsEffectiveCopy(Insn &insn) const = 0;
448     virtual bool IsTargetInsn(MOperator mOp) const = 0;
449     virtual bool IsClinitInsn(MOperator mOp) const = 0;
450     virtual bool IsPseudoInsn(MOperator mOp) const = 0;
451     virtual void DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const = 0;
452 
453 protected:
454     MemPool *memPool;
455     MapleAllocator allocator;
456 
457 private:
458     MIRModule *mirModule;
459     Emitter *emitter;
460     LabelIDOrder labelOrderCnt;
461     static CGFunc *currentCGFunction; /* current cg function being compiled */
462     CGOptions cgOption;
463     MIRSymbol *instrumentationFunction;
464     MIRSymbol *dbgTraceEnter = nullptr;
465     MIRSymbol *dbgTraceExit = nullptr;
466     MIRSymbol *dbgFuncProfile = nullptr;
467     MIRSymbol *fileGP; /* for lmbc, one local %GP per file */
468     static std::map<MIRFunction *, std::pair<LabelIdx, LabelIdx>> funcWrapLabels;
469     bool isLibcore;
470     bool isLmbc;
471 }; /* class CG */
472 } /* namespace maplebe */
473 
474 #endif /* MAPLEBE_INCLUDE_CG_CG_H */
475