• 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_EBO_H
17 #define MAPLEBE_INCLUDE_CG_EBO_H
18 
19 #include "cg_phase.h"
20 #include "cgbb.h"
21 #include "live.h"
22 #include "loop.h"
23 
24 namespace maplebe {
25 namespace {
26 constexpr uint32 kEboDefaultMemHash = 0;
27 constexpr uint32 kEboNoAliasMemHash = 1;
28 constexpr uint32 kEboSpillMemHash = 2;
29 constexpr uint32 kEboCopyInsnHash = 3;
30 constexpr uint32 kEboReservedInsnHash = 4;
31 constexpr uint32 kEboMaxExpInsnHash = 1024;
32 constexpr uint32 kEboMaxOpndHash = 521;
33 constexpr uint32 kEboMaxInsnHash = kEboReservedInsnHash + kEboMaxExpInsnHash;
34 };  // namespace
35 
36 #define EBO_EXP_INSN_HASH(val) ((kEboMaxExpInsnHash - 1ULL) & (static_cast<uint64>(val) >> 6))
37 
38 /* forward decls */
39 class InsnInfo;
40 
41 struct OpndInfo {
OpndInfoOpndInfo42     explicit OpndInfo(Operand &opnd) : opnd(&opnd) {}
43 
44     virtual ~OpndInfo() = default;
45 
46     int32 hashVal = 0; /* Mem operand is placed in hash table, this is the hashVal of it, and otherwise -1. */
47     Operand *opnd;     /* Operand */
48     Operand *replacementOpnd = nullptr;  /* Rename opnd with this new name. */
49     OpndInfo *replacementInfo = nullptr; /* Rename opnd with this info. */
50     BB *bb = nullptr;                    /* The Definining bb. */
51     Insn *insn = nullptr;                /* The Defining insn. */
52     InsnInfo *insnInfo = nullptr;
53     bool redefinedInBB = false;    /* A following definition exisit in bb. */
54     bool redefined = false;        /* A following definition exisit. */
55     Insn *redefinedInsn = nullptr; /* Next defined insn if redefinedInBB is true */
56 #if TARGARM32
57     bool mayReDef = false;
58 #endif
59     OpndInfo *same = nullptr; /* Other definitions of the same operand. */
60     OpndInfo *prev = nullptr;
61     OpndInfo *next = nullptr;
62     OpndInfo *hashNext = nullptr;
63     int32 refCount = 0; /* Number of references to the operand. */
64 };
65 
66 struct MemOpndInfo : public OpndInfo {
MemOpndInfoMemOpndInfo67     explicit MemOpndInfo(Operand &opnd) : OpndInfo(opnd) {}
68 
69     ~MemOpndInfo() override = default;
70 
GetBaseInfoMemOpndInfo71     OpndInfo *GetBaseInfo() const
72     {
73         return base;
74     }
75 
GetOffsetInfoMemOpndInfo76     OpndInfo *GetOffsetInfo() const
77     {
78         return offset;
79     }
80 
SetBaseInfoMemOpndInfo81     void SetBaseInfo(OpndInfo &baseInfo)
82     {
83         base = &baseInfo;
84     }
85 
SetOffsetInfoMemOpndInfo86     void SetOffsetInfo(OpndInfo &offInfo)
87     {
88         offset = &offInfo;
89     }
90 
91 private:
92     OpndInfo *base = nullptr;
93     OpndInfo *offset = nullptr;
94 };
95 
96 class InsnInfo {
97 public:
InsnInfo(MemPool & memPool,Insn & insn)98     InsnInfo(MemPool &memPool, Insn &insn)
99         : alloc(&memPool),
100           bb(insn.GetBB()),
101           insn(&insn),
102           result(alloc.Adapter()),
103           origOpnd(alloc.Adapter()),
104           optimalOpnd(alloc.Adapter())
105     {
106     }
107 
108     virtual ~InsnInfo() = default;
109     MapleAllocator alloc;
110     uint32 hashIndex = 0;
111     bool mustNotBeRemoved = false; /* Some condition requires this insn. */
112     BB *bb;                        /* The defining bb. */
113     Insn *insn;                    /* The defining insn. */
114     InsnInfo *same = nullptr;      /* Other insns with the same hash value. */
115     InsnInfo *prev = nullptr;
116     InsnInfo *next = nullptr;
117     MapleVector<OpndInfo *> result; /* Result array. */
118     MapleVector<OpndInfo *> origOpnd;
119     MapleVector<OpndInfo *> optimalOpnd;
120 };
121 
122 class Ebo {
123 public:
Ebo(CGFunc & func,MemPool & memPool,LiveAnalysis * live,bool before,const std::string & phase)124     Ebo(CGFunc &func, MemPool &memPool, LiveAnalysis *live, bool before, const std::string &phase)
125         : cgFunc(&func),
126           beforeRegAlloc(before),
127           phaseName(phase),
128           live(live),
129           eboMp(&memPool),
130           eboAllocator(&memPool),
131           visitedBBs(eboAllocator.Adapter()),
132           vRegInfo(eboAllocator.Adapter()),
133           exprInfoTable(eboAllocator.Adapter()),
134           insnInfoTable(eboAllocator.Adapter())
135     {
136     }
137 
138     virtual ~Ebo() = default;
139 
140     MemOpndInfo *GetMemInfo(InsnInfo &insnInfo);
SetInsnInfo(uint32 hashVal,InsnInfo & info)141     void SetInsnInfo(uint32 hashVal, InsnInfo &info)
142     {
143         DEBUG_ASSERT(hashVal < insnInfoTable.size(), "hashVal out of insnInfoTable range");
144         insnInfoTable.at(hashVal) = &info;
145     }
146 
IncRef(OpndInfo & info)147     void IncRef(OpndInfo &info) const
148     {
149         ++info.refCount;
150     }
151 
DecRef(OpndInfo & info)152     void DecRef(OpndInfo &info) const
153     {
154         --info.refCount;
155     }
156     bool IsSaveReg(const Operand &opnd);
157     bool IsFrameReg(Operand &opnd) const;
158     bool OperandEqual(const Operand &op1, const Operand &op2) const;
159     Operand *GetZeroOpnd(uint32 size) const;
160     bool IsPhysicalReg(const Operand &opnd) const;
161     bool HasAssignedReg(const Operand &opnd) const;
162     bool IsOfSameClass(const Operand &op0, const Operand &op1) const;
163     bool OpndAvailableInBB(const BB &bb, OpndInfo *info);
164     bool ForwardPropCheck(const Operand *opndReplace, const OpndInfo &opndInfo, const Operand &opnd, Insn &insn);
165     bool RegForwardCheck(Insn &insn, const Operand &opnd, const Operand *opndReplace, Operand &oldOpnd,
166                          const OpndInfo *tmpInfo);
IsNotVisited(const BB & bb)167     bool IsNotVisited(const BB &bb)
168     {
169         return !visitedBBs.at(bb.GetId());
170     };
171 
SetBBVisited(const BB & bb)172     void SetBBVisited(const BB &bb)
173     {
174         visitedBBs.at(bb.GetId()) = true;
175     };
176 
177     void UpdateOpndInfo(const Operand &opnd, OpndInfo &opndInfo, OpndInfo *newInfo, int32 hashVal);
178     void SetOpndInfo(const Operand &opnd, OpndInfo *opndInfo, int32 hashVal);
179     bool RegistersIdentical(const Operand &op0, const Operand &op1) const;
180     OpndInfo *GetOpndInfo(const Operand &opnd, int32 hashVal) const;
181     OpndInfo *GetNewOpndInfo(BB &bb, Insn *insn, Operand &opnd, int32 hashVal);
182     OpndInfo *OperandInfoUse(BB &currentBB, Operand &localOpnd);
183     InsnInfo *GetNewInsnInfo(Insn &insn);
184     int32 ComputeOpndHash(const Operand &opnd) const;
185     uint32 ComputeHashVal(Insn &insn, const MapleVector<OpndInfo *> &opndInfos) const;
186     void MarkOpndLiveIntoBB(const Operand &opnd, BB &into, BB &def) const;
187     void RemoveInsn(InsnInfo &info);
188     void RemoveUses(uint32 opndNum, const MapleVector<OpndInfo *> &origInfo);
189     void HashInsn(Insn &insn, const MapleVector<OpndInfo *> &origInfo, const MapleVector<OpndInfo *> &opndInfos);
190     InsnInfo *LocateInsnInfo(const OpndInfo &info);
191     void UpdateNextInfo(const OpndInfo &opndInfo);
192     void BackupOpndInfoList(OpndInfo *saveLast);
193     void BackupInsnInfoList(InsnInfo *saveLast);
194     void AddBB2EB(BB &bb);
195     void EboInit();
196     void EboProcessSingleBB();
197     void EboProcess();
198     void Run();
PhaseName()199     std::string PhaseName() const
200     {
201         return phaseName;
202     }
203 
204 protected:
205     CGFunc *cgFunc;
206     bool beforeRegAlloc; /* True if perform Ebo before register allocation. */
207     virtual OpndInfo *OperandInfoDef(BB &currentBB, Insn &currentInsn, Operand &localOpnd) = 0;
208     virtual const RegOperand &GetRegOperand(const Operand &opnd) const = 0;
209     virtual bool IsGlobalNeeded(Insn &insn) const = 0;
210     virtual bool IsDecoupleStaticOp(Insn &insn) const = 0;
211     virtual bool IsFmov(const Insn &insn) const = 0;
212     virtual int32 GetOffsetVal(const MemOperand &mem) const = 0;
213     virtual bool OperandEqSpecial(const Operand &op1, const Operand &op2) const = 0;
214     virtual void BuildCallerSaveRegisters() = 0;
215     virtual void DefineAsmRegisters(InsnInfo &insnInfo) = 0;
216     virtual void DefineCallerSaveRegisters(InsnInfo &insnInfo) = 0;
217     virtual void DefineReturnUseRegister(Insn &insn) = 0;
218     virtual void DefineCallUseSpecialRegister(Insn &insn) = 0;
219     virtual void DefineClinitSpecialRegisters(InsnInfo &insnInfo) = 0;
220     virtual bool IsMovToSIMDVmov(Insn &insn, const Insn &replaceInsn) const = 0;
221     virtual bool IsPseudoRet(Insn &insn) const = 0;
222     virtual bool IsAdd(const Insn &insn) const = 0;
223     virtual bool IsClinitCheck(const Insn &insn) const = 0;
224     virtual bool IsLastAndBranch(BB &bb, Insn &insn) const = 0;
225     virtual bool IsSameRedefine(BB &bb, Insn &insn, OpndInfo &opndInfo) const = 0;
226     virtual bool ResIsNotDefAndUse(Insn &insn) const = 0;
227     virtual bool LiveOutOfBB(const Operand &opnd, const BB &bb) const = 0;
228     virtual bool IsInvalidReg(const RegOperand &opnd) const = 0;
229     virtual bool IsZeroRegister(const Operand &opnd) const = 0;
230     virtual bool IsConstantImmOrReg(const Operand &opnd) const = 0;
231     OpndInfo *BuildMemOpndInfo(BB &bb, Insn &insn, Operand &opnd, uint32 opndIndex);
232     OpndInfo *BuildOperandInfo(BB &bb, Insn &insn, Operand &opnd, uint32 opndIndex, MapleVector<OpndInfo *> &origInfos);
233     void FindRedundantInsns(BB &bb, Insn *&insn, const Insn *prev, bool insnReplaced, MapleVector<Operand *> &opnds,
234                             MapleVector<OpndInfo *> &opndInfos, const MapleVector<OpndInfo *> &origInfos);
235     void PreProcessSpecialInsn(Insn &insn);
236 
237     std::string phaseName;
238     LiveAnalysis *live;
239     uint32 bbNum = 0; /* bb numbers for an extend block. */
240     MemPool *eboMp;
241     MapleAllocator eboAllocator;
242     MapleVector<bool> visitedBBs;
243     OpndInfo *firstOpndInfo = nullptr;
244     OpndInfo *lastOpndInfo = nullptr;
245     InsnInfo *firstInsnInfo = nullptr;
246     InsnInfo *lastInsnInfo = nullptr;
247     MapleUnorderedMap<uint32, OpndInfo *> vRegInfo;
248     MapleVector<OpndInfo *> exprInfoTable;
249     MapleVector<InsnInfo *> insnInfoTable;
250     bool optSuccess = false;
251 };
252 
253 MAPLE_FUNC_PHASE_DECLARE(CgEbo0, maplebe::CGFunc)
254 MAPLE_FUNC_PHASE_DECLARE(CgEbo1, maplebe::CGFunc)
255 MAPLE_FUNC_PHASE_DECLARE(CgPostEbo, maplebe::CGFunc)
256 } /* namespace maplebe */
257 
258 #endif /* MAPLEBE_INCLUDE_CG_EBO_H */
259