• 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 MAPLE_IR_INCLUDE_MIR_LOWER_H
17 #define MAPLE_IR_INCLUDE_MIR_LOWER_H
18 #include <iostream>
19 #include "mir_builder.h"
20 #include "opcodes.h"
21 
22 namespace maple {
23 // The base value for branch probability notes and edge probabilities.
24 static constexpr int32 kProbAll = 10000;
25 static constexpr int32 kProbLikely = 9000;
26 static constexpr int32 kProbUnlikely = kProbAll - kProbLikely;
27 constexpr uint32 kNodeFirstOpnd = 0;
28 constexpr uint32 kNodeSecondOpnd = 1;
29 constexpr uint32 kNodeThirdOpnd = 2;
30 enum MirLowerPhase : uint8 { kLowerUnder, kLowerMe, kLowerExpandArray, kLowerBe, kLowerCG, kLowerLNO };
31 
32 constexpr uint32 kShiftLowerMe = 1U << kLowerMe;
33 constexpr uint32 kShiftLowerExpandArray = 1U << kLowerExpandArray;
34 constexpr uint32 kShiftLowerBe = 1U << kLowerBe;
35 constexpr uint32 kShiftLowerCG = 1U << kLowerCG;
36 constexpr uint32 kShiftLowerLNO = 1U << kLowerLNO;
37 // check if a block node ends with an unconditional jump
OpCodeNoFallThrough(Opcode opCode)38 inline bool OpCodeNoFallThrough(Opcode opCode)
39 {
40     return opCode == OP_goto || opCode == OP_return || opCode == OP_switch || opCode == OP_throw ||
41            opCode == OP_gosub || opCode == OP_retsub;
42 }
43 
IfStmtNoFallThrough(const IfStmtNode & ifStmt)44 inline bool IfStmtNoFallThrough(const IfStmtNode &ifStmt)
45 {
46     return OpCodeNoFallThrough(ifStmt.GetThenPart()->GetLast()->GetOpCode());
47 }
48 
49 class MIRLower {
50 public:
51     static const std::set<std::string> kSetArrayHotFunc;
52 
MIRLower(MIRModule & mod,MIRFunction * f)53     MIRLower(MIRModule &mod, MIRFunction *f) : mirModule(mod), mirFunc(f) {}
54 
55     virtual ~MIRLower() = default;
56 
GetMirFunc()57     const MIRFunction *GetMirFunc() const
58     {
59         return mirFunc;
60     }
61 
SetMirFunc(MIRFunction * f)62     void SetMirFunc(MIRFunction *f)
63     {
64         mirFunc = f;
65     }
66 
Init()67     void Init()
68     {
69         mirBuilder = mirModule.GetMemPool()->New<MIRBuilder>(&mirModule);
70     }
71 
72     virtual BlockNode *LowerIfStmt(IfStmtNode &ifStmt, bool recursive);
73     BlockNode *LowerSwitchStmt(SwitchNode *switchNode);
74     virtual BlockNode *LowerWhileStmt(WhileStmtNode &);
75     BlockNode *LowerDowhileStmt(WhileStmtNode &);
76     BlockNode *LowerDoloopStmt(DoloopNode &);
77     BlockNode *LowerBlock(BlockNode &);
78     BaseNode *LowerEmbeddedCandCior(BaseNode *x, StmtNode *curstmt, BlockNode *block);
79     void LowerCandCior(BlockNode &block);
80     void LowerBuiltinExpect(BlockNode &block);
81     void LowerFunc(MIRFunction &func);
82     BaseNode *LowerFarray(ArrayNode *array);
83     BaseNode *LowerCArray(ArrayNode *array);
84     void ExpandArrayMrt(MIRFunction &func);
85     IfStmtNode *ExpandArrayMrtIfBlock(IfStmtNode &node);
86     WhileStmtNode *ExpandArrayMrtWhileBlock(WhileStmtNode &node);
87     DoloopNode *ExpandArrayMrtDoloopBlock(DoloopNode &node);
88     ForeachelemNode *ExpandArrayMrtForeachelemBlock(ForeachelemNode &node);
89     BlockNode *ExpandArrayMrtBlock(BlockNode &block);
90     void AddArrayMrtMpl(BaseNode &exp, BlockNode &newblk);
91     MIRFuncType *FuncTypeFromFuncPtrExpr(BaseNode *x);
SetLowerME()92     void SetLowerME()
93     {
94         lowerPhase |= kShiftLowerMe;
95     }
96 
SetLowerLNO()97     void SetLowerLNO()
98     {
99         lowerPhase |= kShiftLowerLNO;
100     }
101 
SetLowerExpandArray()102     void SetLowerExpandArray()
103     {
104         lowerPhase |= kShiftLowerExpandArray;
105     }
106 
SetLowerBE()107     void SetLowerBE()
108     {
109         lowerPhase |= kShiftLowerBe;
110     }
111 
SetLowerCG()112     void SetLowerCG()
113     {
114         lowerPhase |= kShiftLowerCG;
115     }
116 
GetOptLevel()117     uint8 GetOptLevel() const
118     {
119         return optLevel;
120     }
121 
SetOptLevel(uint8 optlvl)122     void SetOptLevel(uint8 optlvl)
123     {
124         optLevel = optlvl;
125     }
126 
IsLowerME()127     bool IsLowerME() const
128     {
129         return lowerPhase & kShiftLowerMe;
130     }
131 
IsLowerLNO()132     bool IsLowerLNO() const
133     {
134         return lowerPhase & kShiftLowerLNO;
135     }
136 
IsLowerExpandArray()137     bool IsLowerExpandArray() const
138     {
139         return lowerPhase & kShiftLowerExpandArray;
140     }
141 
IsLowerBE()142     bool IsLowerBE() const
143     {
144         return lowerPhase & kShiftLowerBe;
145     }
146 
IsLowerCG()147     bool IsLowerCG() const
148     {
149         return lowerPhase & kShiftLowerCG;
150     }
151 
152     static bool ShouldOptArrayMrt(const MIRFunction &func);
153 
InLFO()154     virtual bool InLFO() const
155     {
156         return false;
157     }
158 
GetFuncProfData()159     GcovFuncInfo *GetFuncProfData()
160     {
161         return mirFunc->GetFuncProfData();
162     }
CopyStmtFrequency(StmtNode * newStmt,StmtNode * oldStmt)163     void CopyStmtFrequency(StmtNode *newStmt, StmtNode *oldStmt)
164     {
165         DEBUG_ASSERT(GetFuncProfData() != nullptr, "nullptr check");
166         if (newStmt == oldStmt)
167             return;
168         int64_t freq = GetFuncProfData()->GetStmtFreq(oldStmt->GetStmtID());
169         GetFuncProfData()->SetStmtFreq(newStmt->GetStmtID(), freq);
170     }
171 
172 protected:
173     MIRModule &mirModule;
174 
175 private:
176     MIRFunction *mirFunc;
177     MIRBuilder *mirBuilder = nullptr;
178     uint32 lowerPhase = 0;
179     uint8 optLevel = 0;
180     LabelIdx CreateCondGotoStmt(Opcode op, BlockNode &blk, const IfStmtNode &ifStmt);
181     void CreateBrFalseStmt(BlockNode &blk, const IfStmtNode &ifStmt);
182     void CreateBrTrueStmt(BlockNode &blk, const IfStmtNode &ifStmt);
183     void CreateBrFalseAndGotoStmt(BlockNode &blk, const IfStmtNode &ifStmt);
184 };
185 }  // namespace maple
186 #endif  // MAPLE_IR_INCLUDE_MIR_LOWER_H
187