• 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_AARCH64_AARCH64_CG_H
17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CG_H
18 
19 #include "cg.h"
20 #include "aarch64_cgfunc.h"
21 #include "aarch64_ssa.h"
22 #include "aarch64_phi_elimination.h"
23 #include "aarch64_prop.h"
24 #include "aarch64_dce.h"
25 #include "aarch64_live.h"
26 #include "aarch64_reaching.h"
27 #include "aarch64_args.h"
28 #include "aarch64_alignment.h"
29 #include "aarch64_validbit_opt.h"
30 #include "aarch64_reg_coalesce.h"
31 #include "aarch64_cfgo.h"
32 
33 namespace maplebe {
34 constexpr int64 kShortBRDistance = (8 * 1024);
35 constexpr int64 kNegativeImmLowerLimit = -4096;
36 constexpr int32 kIntRegTypeNum = 5;
37 constexpr uint32 kAlignPseudoSize = 3;
38 constexpr uint32 kInsnSize = 4;
39 constexpr uint32 kAlignMovedFlag = 31;
40 
41 /* Supporting classes for GCTIB merging */
42 class GCTIBKey {
43 public:
GCTIBKey(MapleAllocator & allocator,uint32 rcHeader,std::vector<uint64> & patternWords)44     GCTIBKey(MapleAllocator &allocator, uint32 rcHeader, std::vector<uint64> &patternWords)
45         : header(rcHeader), bitMapWords(allocator.Adapter())
46     {
47         (void)bitMapWords.insert(bitMapWords.begin(), patternWords.begin(), patternWords.end());
48     }
49 
50     ~GCTIBKey() = default;
51 
GetHeader()52     uint32 GetHeader() const
53     {
54         return header;
55     }
56 
GetBitmapWords()57     const MapleVector<uint64> &GetBitmapWords() const
58     {
59         return bitMapWords;
60     }
61 
62 private:
63     uint32 header;
64     MapleVector<uint64> bitMapWords;
65 };
66 
67 class Hasher {
68 public:
operator()69     size_t operator()(const GCTIBKey *key) const
70     {
71         CHECK_NULL_FATAL(key);
72         size_t hash = key->GetHeader();
73         return hash;
74     }
75 };
76 
77 class EqualFn {
78 public:
operator()79     bool operator()(const GCTIBKey *firstKey, const GCTIBKey *secondKey) const
80     {
81         CHECK_NULL_FATAL(firstKey);
82         CHECK_NULL_FATAL(secondKey);
83         const MapleVector<uint64> &firstWords = firstKey->GetBitmapWords();
84         const MapleVector<uint64> &secondWords = secondKey->GetBitmapWords();
85 
86         if ((firstKey->GetHeader() != secondKey->GetHeader()) || (firstWords.size() != secondWords.size())) {
87             return false;
88         }
89 
90         for (size_t i = 0; i < firstWords.size(); ++i) {
91             if (firstWords[i] != secondWords[i]) {
92                 return false;
93             }
94         }
95         return true;
96     }
97 };
98 
99 class GCTIBPattern {
100 public:
GCTIBPattern(GCTIBKey & patternKey,MemPool & mp)101     GCTIBPattern(GCTIBKey &patternKey, MemPool &mp) : name(&mp)
102     {
103         key = &patternKey;
104         id = GetId();
105         name = GCTIB_PREFIX_STR + std::string("PTN_") + std::to_string(id);
106     }
107 
108     ~GCTIBPattern() = default;
109 
GetId()110     int GetId() const
111     {
112         static int id = 0;
113         return id++;
114     }
115 
GetName()116     std::string GetName() const
117     {
118         DEBUG_ASSERT(!name.empty(), "null name check!");
119         return std::string(name.c_str());
120     }
121 
SetName(const std::string & ptnName)122     void SetName(const std::string &ptnName)
123     {
124         name = ptnName;
125     }
126 
127 private:
128     int id;
129     MapleString name;
130     GCTIBKey *key;
131 };
132 
133 /* sub Target info & implement */
134 class AArch64CG : public CG {
135 public:
AArch64CG(MIRModule & mod,const CGOptions & opts,const std::vector<std::string> & nameVec,const std::unordered_map<std::string,std::vector<std::string>> & patternMap)136     AArch64CG(MIRModule &mod, const CGOptions &opts, const std::vector<std::string> &nameVec,
137               const std::unordered_map<std::string, std::vector<std::string>> &patternMap)
138         : CG(mod, opts),
139           ehExclusiveNameVec(nameVec),
140           cyclePatternMap(patternMap),
141           keyPatternMap(allocator.Adapter()),
142           symbolPatternMap(allocator.Adapter())
143     {
144     }
145 
146     ~AArch64CG() override = default;
147 
CreateCGFunc(MIRModule & mod,MIRFunction & mirFunc,BECommon & bec,MemPool & memPool,StackMemPool & stackMp,MapleAllocator & mallocator,uint32 funcId)148     CGFunc *CreateCGFunc(MIRModule &mod, MIRFunction &mirFunc, BECommon &bec, MemPool &memPool, StackMemPool &stackMp,
149                          MapleAllocator &mallocator, uint32 funcId) override
150     {
151         return memPool.New<AArch64CGFunc>(mod, *this, mirFunc, bec, memPool, stackMp, mallocator, funcId);
152     }
153 
154     void EnrollTargetPhases(MaplePhaseManager *pm) const override;
155 
GetCyclePatternMap()156     const std::unordered_map<std::string, std::vector<std::string>> &GetCyclePatternMap() const
157     {
158         return cyclePatternMap;
159     }
160 
161     void GenerateObjectMaps(BECommon &beCommon) override;
162 
163     bool IsExclusiveFunc(MIRFunction &) override;
164 
165     void FindOrCreateRepresentiveSym(std::vector<uint64> &bitmapWords, uint32 rcHeader, const std::string &name);
166 
167     void CreateRefSymForGlobalPtn(GCTIBPattern &ptn) const;
168 
169     Insn &BuildPhiInsn(RegOperand &defOpnd, Operand &listParam) override;
170 
171     PhiOperand &CreatePhiOperand(MemPool &mp, MapleAllocator &mAllocator) override;
172 
173     std::string FindGCTIBPatternName(const std::string &name) const override;
174 
CreateLiveAnalysis(MemPool & mp,CGFunc & f)175     LiveAnalysis *CreateLiveAnalysis(MemPool &mp, CGFunc &f) const override
176     {
177         return mp.New<AArch64LiveAnalysis>(f, mp);
178     }
CreateReachingDefinition(MemPool & mp,CGFunc & f)179     ReachingDefinition *CreateReachingDefinition(MemPool &mp, CGFunc &f) const override
180     {
181         return mp.New<AArch64ReachingDefinition>(f, mp);
182     }
CreateMoveRegArgs(MemPool & mp,CGFunc & f)183     MoveRegArgs *CreateMoveRegArgs(MemPool &mp, CGFunc &f) const override
184     {
185         return mp.New<AArch64MoveRegArgs>(f);
186     }
CreateAlignAnalysis(MemPool & mp,CGFunc & f)187     AlignAnalysis *CreateAlignAnalysis(MemPool &mp, CGFunc &f) const override
188     {
189         return mp.New<AArch64AlignAnalysis>(f, mp);
190     }
CreateCGSSAInfo(MemPool & mp,CGFunc & f,DomAnalysis & da,MemPool & tmp)191     CGSSAInfo *CreateCGSSAInfo(MemPool &mp, CGFunc &f, DomAnalysis &da, MemPool &tmp) const override
192     {
193         return mp.New<AArch64CGSSAInfo>(f, da, mp, tmp);
194     }
CreateLLAnalysis(MemPool & mp,CGFunc & f)195     LiveIntervalAnalysis *CreateLLAnalysis(MemPool &mp, CGFunc &f) const override
196     {
197         return mp.New<AArch64LiveIntervalAnalysis>(f, mp);
198     };
CreatePhiElimintor(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)199     PhiEliminate *CreatePhiElimintor(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override
200     {
201         return mp.New<AArch64PhiEliminate>(f, ssaInfo, mp);
202     }
CreateCGProp(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo,LiveIntervalAnalysis & ll)203     CGProp *CreateCGProp(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo, LiveIntervalAnalysis &ll) const override
204     {
205         return mp.New<AArch64Prop>(mp, f, ssaInfo, ll);
206     }
CreateCGDce(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)207     CGDce *CreateCGDce(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override
208     {
209         return mp.New<AArch64Dce>(mp, f, ssaInfo);
210     }
CreateValidBitOpt(MemPool & mp,CGFunc & f,CGSSAInfo & ssaInfo)211     ValidBitOpt *CreateValidBitOpt(MemPool &mp, CGFunc &f, CGSSAInfo &ssaInfo) const override
212     {
213         return mp.New<AArch64ValidBitOpt>(f, ssaInfo);
214     }
CreateCFGOptimizer(MemPool & mp,CGFunc & f)215     CFGOptimizer *CreateCFGOptimizer(MemPool &mp, CGFunc &f) const override
216     {
217         return mp.New<AArch64CFGOptimizer>(f, mp);
218     }
219 
220     /* Return the copy operand id of reg1 if it is an insn who just do copy from reg1 to reg2.
221      * i. mov reg2, reg1
222      * ii. add/sub reg2, reg1, 0/zero register
223      * iii. mul reg2, reg1, 1
224      */
225     bool IsEffectiveCopy(Insn &insn) const final;
226     bool IsTargetInsn(MOperator mOp) const final;
227     bool IsClinitInsn(MOperator mOp) const final;
228     bool IsPseudoInsn(MOperator mOp) const final;
229     void DumpTargetOperand(Operand &opnd, const OpndDesc &opndDesc) const final;
GetTargetMd(MOperator mOp)230     const InsnDesc &GetTargetMd(MOperator mOp) const final
231     {
232         return kMd[mOp];
233     }
234 
235     static const InsnDesc kMd[kMopLast];
236     enum : uint8 { kR8List, kR16List, kR32List, kR64List, kV64List };
237     static std::array<std::array<const std::string, kAllRegNum>, kIntRegTypeNum> intRegNames;
238     static std::array<const std::string, kAllRegNum> vectorRegNames;
239 
240 private:
241     const std::vector<std::string> &ehExclusiveNameVec;
242     const std::unordered_map<std::string, std::vector<std::string>> &cyclePatternMap;
243     MapleUnorderedMap<GCTIBKey *, GCTIBPattern *, Hasher, EqualFn> keyPatternMap;
244     MapleUnorderedMap<std::string, GCTIBPattern *> symbolPatternMap;
245 };
246 } /* namespace maplebe */
247 
248 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_CG_H */
249