• 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_GLOBAL_H
17 #define MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_GLOBAL_H
18 
19 #include "global.h"
20 #include "aarch64_operand.h"
21 
22 namespace maplebe {
23 using namespace maple;
24 
25 class AArch64GlobalOpt : public GlobalOpt {
26 public:
AArch64GlobalOpt(CGFunc & func)27     explicit AArch64GlobalOpt(CGFunc &func) : GlobalOpt(func) {}
28     ~AArch64GlobalOpt() override = default;
29     void Run() override;
30 };
31 
32 class OptimizeManager {
33 public:
OptimizeManager(CGFunc & cgFunc)34     explicit OptimizeManager(CGFunc &cgFunc) : cgFunc(cgFunc) {}
35     ~OptimizeManager() = default;
36     template <typename OptimizePattern>
Optimize()37     void Optimize()
38     {
39         OptimizePattern optPattern(cgFunc);
40         optPattern.Run();
41     }
42 
43 private:
44     CGFunc &cgFunc;
45 };
46 
47 class OptimizePattern {
48 public:
OptimizePattern(CGFunc & cgFunc)49     explicit OptimizePattern(CGFunc &cgFunc) : cgFunc(cgFunc) {}
50     virtual ~OptimizePattern() = default;
51     virtual bool CheckCondition(Insn &insn) = 0;
52     virtual void Optimize(Insn &insn) = 0;
53     virtual void Run() = 0;
54     bool OpndDefByOne(Insn &insn, int32 useIdx) const;
55     bool OpndDefByZero(Insn &insn, int32 useIdx) const;
56     bool OpndDefByOneOrZero(Insn &insn, int32 useIdx) const;
57     void ReplaceAllUsedOpndWithNewOpnd(const InsnSet &useInsnSet, uint32 regNO, Operand &newOpnd,
58                                        bool updateInfo) const;
59 
60     static bool InsnDefOne(const Insn &insn);
61     static bool InsnDefZero(const Insn &insn);
62     static bool InsnDefOneOrZero(const Insn &insn);
63 
PhaseName()64     std::string PhaseName() const
65     {
66         return "globalopt";
67     }
68 
69 protected:
70     virtual void Init() = 0;
71     CGFunc &cgFunc;
72 };
73 
74 /*
75  * Do Forward prop when insn is mov
76  * mov xx, x1
77  * ... // BBs and x1 is live
78  * mOp yy, xx
79  *
80  * =>
81  * mov x1, x1
82  * ... // BBs and x1 is live
83  * mOp yy, x1
84  */
85 class ForwardPropPattern : public OptimizePattern {
86 public:
ForwardPropPattern(CGFunc & cgFunc)87     explicit ForwardPropPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
88     ~ForwardPropPattern() override = default;
89     bool CheckCondition(Insn &insn) final;
90     void Optimize(Insn &insn) final;
91     void Run() final;
92 
93 protected:
94     void Init() final;
95 
96 private:
97     InsnSet firstRegUseInsnSet;
98     void RemoveMopUxtwToMov(Insn &insn);
99     std::set<BB *, BBIdCmp> modifiedBB;
100 };
101 
102 /*
103  * Do back propagate of vreg/preg when encount following insn:
104  *
105  * mov vreg/preg1, vreg2
106  *
107  * back propagate reg1 to all vreg2's use points and def points, when all of them is in same bb
108  */
109 class BackPropPattern : public OptimizePattern {
110 public:
BackPropPattern(CGFunc & cgFunc)111     explicit BackPropPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~BackPropPattern()112     ~BackPropPattern() override
113     {
114         firstRegOpnd = nullptr;
115         secondRegOpnd = nullptr;
116         defInsnForSecondOpnd = nullptr;
117     }
118     bool CheckCondition(Insn &insn) final;
119     void Optimize(Insn &insn) final;
120     void Run() final;
121 
122 protected:
123     void Init() final;
124 
125 private:
126     bool CheckAndGetOpnd(const Insn &insn);
127     bool DestOpndHasUseInsns(Insn &insn);
128     bool DestOpndLiveOutToEHSuccs(Insn &insn) const;
129     bool CheckSrcOpndDefAndUseInsns(Insn &insn);
130     bool CheckSrcOpndDefAndUseInsnsGlobal(Insn &insn);
131     bool CheckPredefineInsn(Insn &insn);
132     bool CheckRedefineInsn(Insn &insn);
133     bool CheckReplacedUseInsn(Insn &insn);
134     RegOperand *firstRegOpnd = nullptr;
135     RegOperand *secondRegOpnd = nullptr;
136     uint32 firstRegNO = 0;
137     uint32 secondRegNO = 0;
138     InsnSet srcOpndUseInsnSet;
139     Insn *defInsnForSecondOpnd = nullptr;
140     bool globalProp = false;
141 };
142 
143 /*
144  *  when w0 has only one valid bit, these tranformation will be done
145  *  cmp  w0, #0
146  *  cset w1, NE --> mov w1, w0
147  *
148  *  cmp  w0, #0
149  *  cset w1, EQ --> eor w1, w0, 1
150  *
151  *  cmp  w0, #1
152  *  cset w1, NE --> eor w1, w0, 1
153  *
154  *  cmp  w0, #1
155  *  cset w1, EQ --> mov w1, w0
156  *
157  *  cmp w0,  #0
158  *  cset w0, NE -->null
159  *
160  *  cmp w0, #1
161  *  cset w0, EQ -->null
162  *
163  *  condition:
164  *    1. the first operand of cmp instruction must has only one valid bit
165  *    2. the second operand of cmp instruction must be 0 or 1
166  *    3. flag register of cmp isntruction must not be used later
167  */
168 class CmpCsetPattern : public OptimizePattern {
169 public:
CmpCsetPattern(CGFunc & cgFunc)170     explicit CmpCsetPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~CmpCsetPattern()171     ~CmpCsetPattern() override
172     {
173         nextInsn = nullptr;
174         cmpFirstOpnd = nullptr;
175         cmpSecondOpnd = nullptr;
176         csetFirstOpnd = nullptr;
177     }
178     bool CheckCondition(Insn &insn) final;
179     void Optimize(Insn &insn) final;
180     void Run() final;
181 
182 protected:
183     void Init() final;
184 
185 private:
186     Insn *nextInsn = nullptr;
187     int64 cmpConstVal = 0;
188     Operand *cmpFirstOpnd = nullptr;
189     Operand *cmpSecondOpnd = nullptr;
190     Operand *csetFirstOpnd = nullptr;
191 };
192 
193 /*
194  * mov w5, #1
195  *  ...                   --> cset w5, NE
196  * mov w0, #0
197  * csel w5, w5, w0, NE
198  *
199  * mov w5, #0
200  *  ...                   --> cset w5,EQ
201  * mov w0, #1
202  * csel w5, w5, w0, NE
203  *
204  * condition:
205  *    1.all define points of w5 are defined by:   mov w5, #1(#0)
206  *    2.all define points of w0 are defined by:   mov w0, #0(#1)
207  *    3.w0 will not be used after: csel w5, w5, w0, NE(EQ)
208  */
209 class CselPattern : public OptimizePattern {
210 public:
CselPattern(CGFunc & cgFunc)211     explicit CselPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
212     ~CselPattern() override = default;
213     bool CheckCondition(Insn &insn) final;
214     void Optimize(Insn &insn) final;
215     void Run() final;
216 
217 protected:
Init()218     void Init() final {}
219 };
220 
221 /*
222  * uxtb  w0, w0    -->   null
223  * uxth  w0, w0    -->   null
224  *
225  * condition:
226  * 1. validbits(w0)<=8,16,32
227  * 2. the first operand is same as the second operand
228  *
229  * uxtb  w0, w1    -->   null
230  * uxth  w0, w1    -->   null
231  *
232  * condition:
233  * 1. validbits(w1)<=8,16,32
234  * 2. the use points of w0 has only one define point, that is uxt w0, w1
235  */
236 class RedundantUxtPattern : public OptimizePattern {
237 public:
RedundantUxtPattern(CGFunc & cgFunc)238     explicit RedundantUxtPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~RedundantUxtPattern()239     ~RedundantUxtPattern() override
240     {
241         secondOpnd = nullptr;
242     }
243     bool CheckCondition(Insn &insn) final;
244     void Optimize(Insn &insn) final;
245     void Run() final;
246 
247 protected:
248     void Init() final;
249 
250 private:
251     uint32 GetMaximumValidBit(Insn &insn, uint8 udIdx, InsnSet &insnChecked) const;
252     static uint32 GetInsnValidBit(const Insn &insn);
253     InsnSet useInsnSet;
254     uint32 firstRegNO = 0;
255     Operand *secondOpnd = nullptr;
256 };
257 
258 /*
259  *  bl  MCC_NewObj_flexible_cname                              bl  MCC_NewObj_flexible_cname
260  *  mov x21, x0   //  [R203]
261  *  str x0, [x29,#16]   // local var: Reg0_R6340 [R203]  -->   str x0, [x29,#16]   // local var: Reg0_R6340 [R203]
262  *  ... (has call)                                             ... (has call)
263  *  mov x2, x21  // use of x21                                 ldr x2, [x29, #16]
264  *  bl ***                                                     bl ***
265  */
266 class LocalVarSaveInsnPattern : public OptimizePattern {
267 public:
LocalVarSaveInsnPattern(CGFunc & cgFunc)268     explicit LocalVarSaveInsnPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~LocalVarSaveInsnPattern()269     ~LocalVarSaveInsnPattern() override
270     {
271         firstInsnSrcOpnd = nullptr;
272         firstInsnDestOpnd = nullptr;
273         secondInsnSrcOpnd = nullptr;
274         secondInsnDestOpnd = nullptr;
275         useInsn = nullptr;
276         secondInsn = nullptr;
277     }
278     bool CheckCondition(Insn &insn) final;
279     void Optimize(Insn &insn) final;
280     void Run() final;
281 
282 protected:
283     void Init() final;
284 
285 private:
286     bool CheckFirstInsn(const Insn &firstInsn);
287     bool CheckSecondInsn();
288     bool CheckAndGetUseInsn(Insn &firstInsn);
289     bool CheckLiveRange(const Insn &firstInsn);
290     Operand *firstInsnSrcOpnd = nullptr;
291     Operand *firstInsnDestOpnd = nullptr;
292     Operand *secondInsnSrcOpnd = nullptr;
293     Operand *secondInsnDestOpnd = nullptr;
294     Insn *useInsn = nullptr;
295     Insn *secondInsn = nullptr;
296 };
297 
298 class ExtendShiftOptPattern : public OptimizePattern {
299 public:
ExtendShiftOptPattern(CGFunc & cgFunc)300     explicit ExtendShiftOptPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~ExtendShiftOptPattern()301     ~ExtendShiftOptPattern() override
302     {
303         defInsn = nullptr;
304         newInsn = nullptr;
305     }
306     bool CheckCondition(Insn &insn) final;
307     void Optimize(Insn &insn) final;
308     void Run() final;
309     void DoExtendShiftOpt(Insn &insn);
310 
311     enum ExMOpType : uint8 {
312         kExUndef,
313         kExAdd, /* MOP_xaddrrr | MOP_xxwaddrrre | MOP_xaddrrrs */
314         kEwAdd, /* MOP_waddrrr | MOP_wwwaddrrre | MOP_waddrrrs */
315         kExSub, /* MOP_xsubrrr | MOP_xxwsubrrre | MOP_xsubrrrs */
316         kEwSub, /* MOP_wsubrrr | MOP_wwwsubrrre | MOP_wsubrrrs */
317         kExCmn, /* MOP_xcmnrr | MOP_xwcmnrre | MOP_xcmnrrs */
318         kEwCmn, /* MOP_wcmnrr | MOP_wwcmnrre | MOP_wcmnrrs */
319         kExCmp, /* MOP_xcmprr | MOP_xwcmprre | MOP_xcmprrs */
320         kEwCmp, /* MOP_wcmprr | MOP_wwcmprre | MOP_wcmprrs */
321     };
322 
323     enum LsMOpType : uint8 {
324         kLsUndef,
325         kLxAdd, /* MOP_xaddrrr | MOP_xaddrrrs */
326         kLwAdd, /* MOP_waddrrr | MOP_waddrrrs */
327         kLxSub, /* MOP_xsubrrr | MOP_xsubrrrs */
328         kLwSub, /* MOP_wsubrrr | MOP_wsubrrrs */
329         kLxCmn, /* MOP_xcmnrr | MOP_xcmnrrs */
330         kLwCmn, /* MOP_wcmnrr | MOP_wcmnrrs */
331         kLxCmp, /* MOP_xcmprr | MOP_xcmprrs */
332         kLwCmp, /* MOP_wcmprr | MOP_wcmprrs */
333         kLxEor, /* MOP_xeorrrr | MOP_xeorrrrs */
334         kLwEor, /* MOP_weorrrr | MOP_weorrrrs */
335         kLxNeg, /* MOP_xinegrr | MOP_xinegrrs */
336         kLwNeg, /* MOP_winegrr | MOP_winegrrs */
337         kLxIor, /* MOP_xiorrrr | MOP_xiorrrrs */
338         kLwIor, /* MOP_wiorrrr | MOP_wiorrrrs */
339     };
340 
341     enum SuffixType : uint8 {
342         kNoSuffix, /* no suffix or do not perform the optimization. */
343         kLSL,      /* logical shift left */
344         kLSR,      /* logical shift right */
345         kASR,      /* arithmetic shift right */
346         kExten     /* ExtendOp */
347     };
348 
349 protected:
350     void Init() final;
351 
352 private:
353     void SelectExtendOrShift(const Insn &def);
354     bool CheckDefUseInfo(Insn &use, uint32 size);
355     SuffixType CheckOpType(const Operand &lastOpnd) const;
356     void ReplaceUseInsn(Insn &use, const Insn &def, uint32 amount);
357     void SetExMOpType(const Insn &use);
358     void SetLsMOpType(const Insn &use);
359 
360     MOperator replaceOp;
361     uint32 replaceIdx;
362     ExtendShiftOperand::ExtendOp extendOp;
363     BitShiftOperand::ShiftOp shiftOp;
364     Insn *defInsn = nullptr;
365     Insn *newInsn = nullptr;
366     bool optSuccess;
367     bool removeDefInsn;
368     ExMOpType exMOpType;
369     LsMOpType lsMOpType;
370 };
371 
372 /*
373  * This pattern do:
374  * 1)
375  * uxtw vreg:Rm validBitNum:[64], vreg:Rn validBitNum:[32]
376  * ------>
377  * mov vreg:Rm validBitNum:[64], vreg:Rn validBitNum:[32]
378  * 2)
379  * ldrh  R201, [...]
380  * and R202, R201, #65520
381  * uxth  R203, R202
382  * ------->
383  * ldrh  R201, [...]
384  * and R202, R201, #65520
385  * mov  R203, R202
386  */
387 class ExtenToMovPattern : public OptimizePattern {
388 public:
ExtenToMovPattern(CGFunc & cgFunc)389     explicit ExtenToMovPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
390     ~ExtenToMovPattern() override = default;
391     bool CheckCondition(Insn &insn) final;
392     void Optimize(Insn &insn) final;
393     void Run() final;
394 
395 protected:
396     void Init() final;
397 
398 private:
399     bool CheckHideUxtw(const Insn &insn, regno_t regno) const;
400     bool CheckUxtw(Insn &insn);
401     bool BitNotAffected(Insn &insn, uint32 validNum); /* check whether significant bits are affected */
402     bool CheckSrcReg(Insn &insn, regno_t srcRegNo, uint32 validNum);
403 
404     MOperator replaceMop = MOP_undef;
405 };
406 
407 class SameDefPattern : public OptimizePattern {
408 public:
SameDefPattern(CGFunc & cgFunc)409     explicit SameDefPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~SameDefPattern()410     ~SameDefPattern() override
411     {
412         currInsn = nullptr;
413         sameInsn = nullptr;
414     }
415     bool CheckCondition(Insn &insn) final;
416     void Optimize(Insn &insn) final;
417     void Run() final;
418 
419 protected:
420     void Init() final;
421 
422 private:
423     bool IsSameDef();
424     bool SrcRegIsRedefined(regno_t regNo);
425     bool IsSameOperand(Operand &opnd0, Operand &opnd1);
426 
427     Insn *currInsn = nullptr;
428     Insn *sameInsn = nullptr;
429 };
430 
431 /*
432  * and r0, r0, #4        (the imm is n power of 2)
433  * ...                   (r0 is not used)
434  * cbz r0, .Label
435  * ===>  tbz r0, #2, .Label
436  *
437  * and r0, r0, #4        (the imm is n power of 2)
438  * ...                   (r0 is not used)
439  * cbnz r0, .Label
440  * ===>  tbnz r0, #2, .Label
441  */
442 class AndCbzPattern : public OptimizePattern {
443 public:
AndCbzPattern(CGFunc & cgFunc)444     explicit AndCbzPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~AndCbzPattern()445     ~AndCbzPattern() override
446     {
447         prevInsn = nullptr;
448     }
449     bool CheckCondition(Insn &insn) final;
450     void Optimize(Insn &insn) final;
451     void Run() final;
452 
453 protected:
454     void Init() final;
455 
456 private:
457     int64 CalculateLogValue(int64 val) const;
458     bool IsAdjacentArea(Insn &prev, Insn &curr) const;
459     Insn *prevInsn = nullptr;
460 };
461 
462 /*
463  * [arithmetic operation]
464  * add/sub/ R202, R201, #1            add/sub/ R202, R201, #1
465  * ...                           ...
466  * add/sub/ R203, R201, #1    --->    mov R203, R202
467  *
468  * [copy operation]
469  * mov R201, #1                  mov R201, #1
470  * ...                           ...
471  * mov R202, #1          --->    mov R202, R201
472  *
473  * The pattern finds the insn with the same rvalue as the current insn,
474  * then prop its lvalue, and replaces the current insn with movrr insn.
475  * The mov can be prop in forwardprop or backprop.
476  *
477  * conditions:
478  * 1. in same BB
479  * 2. rvalue is not defined between two insns
480  * 3. lvalue is not defined between two insns
481  */
482 class SameRHSPropPattern : public OptimizePattern {
483 public:
SameRHSPropPattern(CGFunc & cgFunc)484     explicit SameRHSPropPattern(CGFunc &cgFunc) : OptimizePattern(cgFunc) {}
~SameRHSPropPattern()485     ~SameRHSPropPattern() override
486     {
487         prevInsn = nullptr;
488     }
489     bool CheckCondition(Insn &insn) final;
490     void Optimize(Insn &insn) final;
491     void Run() final;
492 
493 protected:
494     void Init() final;
495 
496 private:
497     bool IsSameOperand(Operand *opnd1, Operand *opnd2) const;
498     bool FindSameRHSInsnInBB(Insn &insn);
499     Insn *prevInsn = nullptr;
500     std::vector<MOperator> candidates;
501 };
502 } /* namespace maplebe */
503 
504 #endif /* MAPLEBE_INCLUDE_CG_AARCH64_AARCH64_GLOBAL_H */
505