• 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 #include "cgfunc.h"
17 #if DEBUG
18 #endif
19 #include "cg.h"
20 #include "factory.h"
21 #include "cfgo.h"
22 
23 namespace maplebe {
24 using namespace maple;
25 
HandleDread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)26 static Operand *HandleDread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
27 {
28     auto &dreadNode = static_cast<AddrofNode &>(expr);
29     return cgFunc.SelectDread(parent, dreadNode);
30 }
31 
HandleRegread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)32 static Operand *HandleRegread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
33 {
34     (void)parent;
35     auto &regReadNode = static_cast<RegreadNode &>(expr);
36     return cgFunc.SelectRegread(regReadNode);
37 }
38 
HandleConstVal(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)39 static Operand *HandleConstVal(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
40 {
41     auto &constValNode = static_cast<ConstvalNode &>(expr);
42     MIRConst *mirConst = constValNode.GetConstVal();
43     DEBUG_ASSERT(mirConst != nullptr, "get constval of constvalnode failed");
44     if (mirConst->GetKind() == kConstInt) {
45         auto *mirIntConst = safe_cast<MIRIntConst>(mirConst);
46         return cgFunc.SelectIntConst(*mirIntConst, parent);
47     } else if (mirConst->GetKind() == kConstFloatConst) {
48         auto *mirFloatConst = safe_cast<MIRFloatConst>(mirConst);
49         return cgFunc.SelectFloatConst(*mirFloatConst, parent);
50     } else {
51         CHECK_FATAL(mirConst->GetKind() == kConstDoubleConst, "NYI");
52         auto *mirDoubleConst = safe_cast<MIRDoubleConst>(mirConst);
53         return cgFunc.SelectDoubleConst(*mirDoubleConst, parent);
54     }
55     return nullptr;
56 }
57 
HandleAdd(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)58 static Operand *HandleAdd(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
59 {
60     return cgFunc.SelectAdd(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
61                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
62 }
63 
HandleShift(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)64 static Operand *HandleShift(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
65 {
66     return cgFunc.SelectShift(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
67                               *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
68 }
69 
HandleMpy(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)70 static Operand *HandleMpy(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
71 {
72     return cgFunc.SelectMpy(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
73                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
74 }
75 
HandleDiv(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)76 static Operand *HandleDiv(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
77 {
78     return cgFunc.SelectDiv(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
79                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
80 }
81 
HandleRem(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)82 static Operand *HandleRem(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
83 {
84     return cgFunc.SelectRem(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
85                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
86 }
87 
HandleIread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)88 static Operand *HandleIread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
89 {
90     auto &ireadNode = static_cast<IreadNode &>(expr);
91     return cgFunc.SelectIread(parent, ireadNode);
92 }
93 
HandleSub(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)94 static Operand *HandleSub(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
95 {
96     return cgFunc.SelectSub(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
97                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
98 }
99 
HandleBand(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)100 static Operand *HandleBand(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
101 {
102     return cgFunc.SelectBand(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
103                              *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
104 }
105 
HandleBior(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)106 static Operand *HandleBior(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
107 {
108     return cgFunc.SelectBior(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
109                              *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
110 }
111 
HandleBxor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)112 static Operand *HandleBxor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
113 {
114     return cgFunc.SelectBxor(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
115                              *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
116 }
117 
HandleAbs(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)118 static Operand *HandleAbs(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
119 {
120     (void)parent;
121     DEBUG_ASSERT(expr.Opnd(0) != nullptr, "expr.Opnd(0) should not be nullptr");
122     return cgFunc.SelectAbs(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
123 }
124 
HandleBnot(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)125 static Operand *HandleBnot(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
126 {
127     return cgFunc.SelectBnot(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
128 }
129 
HandleExtractBits(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)130 static Operand *HandleExtractBits(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
131 {
132     ExtractbitsNode &node = static_cast<ExtractbitsNode &>(expr);
133     uint8 bitOffset = node.GetBitsOffset();
134     uint8 bitSize = node.GetBitsSize();
135     if (!CGOptions::IsBigEndian() && (bitSize == k8BitSize || bitSize == k16BitSize) &&
136         GetPrimTypeBitSize(node.GetPrimType()) != k64BitSize &&
137         (bitOffset == 0 || bitOffset == k8BitSize || bitOffset == k16BitSize || bitOffset == k24BitSize) &&
138         expr.Opnd(0)->GetOpCode() == OP_iread && node.GetOpCode() == OP_extractbits) {
139         return cgFunc.SelectRegularBitFieldLoad(node, parent);
140     }
141     return cgFunc.SelectExtractbits(static_cast<ExtractbitsNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
142                                     parent);
143 }
144 
HandleLnot(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)145 static Operand *HandleLnot(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
146 {
147     DEBUG_ASSERT(expr.Opnd(0) != nullptr, "nullptr check");
148     return cgFunc.SelectLnot(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
149 }
150 
151 
HandleMin(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)152 static Operand *HandleMin(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
153 {
154     return cgFunc.SelectMin(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
155                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
156 }
157 
HandleMax(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)158 static Operand *HandleMax(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
159 {
160     return cgFunc.SelectMax(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
161                             *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
162 }
163 
HandleSqrt(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)164 static Operand *HandleSqrt(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
165 {
166     return cgFunc.SelectSqrt(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
167 }
168 
HandleCeil(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)169 static Operand *HandleCeil(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
170 {
171     return cgFunc.SelectCeil(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
172 }
173 
HandleFloor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)174 static Operand *HandleFloor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
175 {
176     DEBUG_ASSERT(expr.Opnd(0) != nullptr, "expr.Opnd(0) should not be nullptr");
177     return cgFunc.SelectFloor(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
178 }
179 
HandleRetype(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)180 static Operand *HandleRetype(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
181 {
182     (void)parent;
183     DEBUG_ASSERT(expr.Opnd(0) != nullptr, "nullptr check");
184     return cgFunc.SelectRetype(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
185 }
186 
HandleCvt(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)187 static Operand *HandleCvt(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
188 {
189     return cgFunc.SelectCvt(parent, static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
190 }
191 
HandleTrunc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)192 static Operand *HandleTrunc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
193 {
194     DEBUG_ASSERT(expr.Opnd(0) != nullptr, "expr should not be nullptr");
195     return cgFunc.SelectTrunc(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
196 }
197 
HandleCmp(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)198 static Operand *HandleCmp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
199 {
200     // fix opnd type before select insn
201     PrimType targetPtyp = parent.GetPrimType();
202     if (kOpcodeInfo.IsCompare(parent.GetOpCode())) {
203         targetPtyp = static_cast<const CompareNode &>(parent).GetOpndType();
204     } else if (kOpcodeInfo.IsTypeCvt(parent.GetOpCode())) {
205         targetPtyp = static_cast<const TypeCvtNode &>(parent).FromType();
206     }
207     if (IsPrimitiveInteger(targetPtyp) && targetPtyp != expr.GetPrimType()) {
208         expr.SetPrimType(targetPtyp);
209     }
210     return cgFunc.SelectCmpOp(static_cast<CompareNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
211                               *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
212 }
213 
HandleIntrinOp(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)214 static Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
215 {
216     auto &intrinsicopNode = static_cast<IntrinsicopNode &>(expr);
217     switch (intrinsicopNode.GetIntrinsic()) {
218         case INTRN_C_clz32:
219         case INTRN_C_clz64:
220             return cgFunc.SelectCclz(intrinsicopNode);
221         case INTRN_HEAP_CONSTANT:
222             return cgFunc.SelectHeapConstant(intrinsicopNode, *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
223                                              *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)));
224         case INTRN_GET_HEAP_CONSTANT_TABLE:
225             return cgFunc.SelectGetHeapConstantTable(intrinsicopNode,
226                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
227                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)),
228                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnThirdOpnd)));
229         case INTRN_TAGGED_IS_HEAPOBJECT:
230             return cgFunc.SelectTaggedIsHeapObject(intrinsicopNode,
231                                                    *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
232                                                    *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)));
233         case INTRN_IS_STABLE_ELEMENTS:
234             return cgFunc.SelectIsStableElements(intrinsicopNode,
235                                                  *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
236                                                  *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)),
237                                                  *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnThirdOpnd)));
238         case INTRN_HAS_PENDING_EXCEPTION:
239             return cgFunc.SelectHasPendingException(intrinsicopNode,
240                                                     *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
241                                                     *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)),
242                                                     *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnThirdOpnd)));
243         case INTRN_TAGGED_OBJECT_IS_STRING:
244             return cgFunc.SelectTaggedObjectIsString(intrinsicopNode,
245                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
246                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)),
247                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnThirdOpnd)),
248                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFourthOpnd)),
249                                                      *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFifthOpnd)));
250         case INTRN_IS_COW_ARRAY:
251             return cgFunc.SelectIsCOWArray(intrinsicopNode,
252                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFirstOpnd)),
253                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSecondOpnd)),
254                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnThirdOpnd)),
255                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFourthOpnd)),
256                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnFifthOpnd)),
257                                            *cgFunc.HandleExpr(expr, *expr.Opnd(kInsnSixthOpnd)));
258         default:
259             DEBUG_ASSERT(false, "Should not reach here.");
260             return nullptr;
261     }
262 }
263 
264 using HandleExprFactory = FunctionFactory<Opcode, maplebe::Operand *, const BaseNode &, BaseNode &, CGFunc &>;
InitHandleExprFactory()265 void InitHandleExprFactory()
266 {
267     RegisterFactoryFunction<HandleExprFactory>(OP_dread, HandleDread);
268     RegisterFactoryFunction<HandleExprFactory>(OP_regread, HandleRegread);
269     RegisterFactoryFunction<HandleExprFactory>(OP_constval, HandleConstVal);
270     RegisterFactoryFunction<HandleExprFactory>(OP_add, HandleAdd);
271     RegisterFactoryFunction<HandleExprFactory>(OP_ashr, HandleShift);
272     RegisterFactoryFunction<HandleExprFactory>(OP_lshr, HandleShift);
273     RegisterFactoryFunction<HandleExprFactory>(OP_shl, HandleShift);
274     RegisterFactoryFunction<HandleExprFactory>(OP_mul, HandleMpy);
275     RegisterFactoryFunction<HandleExprFactory>(OP_div, HandleDiv);
276     RegisterFactoryFunction<HandleExprFactory>(OP_rem, HandleRem);
277     RegisterFactoryFunction<HandleExprFactory>(OP_iread, HandleIread);
278     RegisterFactoryFunction<HandleExprFactory>(OP_sub, HandleSub);
279     RegisterFactoryFunction<HandleExprFactory>(OP_band, HandleBand);
280     RegisterFactoryFunction<HandleExprFactory>(OP_bior, HandleBior);
281     RegisterFactoryFunction<HandleExprFactory>(OP_bxor, HandleBxor);
282     RegisterFactoryFunction<HandleExprFactory>(OP_abs, HandleAbs);
283     RegisterFactoryFunction<HandleExprFactory>(OP_bnot, HandleBnot);
284     RegisterFactoryFunction<HandleExprFactory>(OP_sext, HandleExtractBits);
285     RegisterFactoryFunction<HandleExprFactory>(OP_zext, HandleExtractBits);
286     RegisterFactoryFunction<HandleExprFactory>(OP_lnot, HandleLnot);
287     RegisterFactoryFunction<HandleExprFactory>(OP_min, HandleMin);
288     RegisterFactoryFunction<HandleExprFactory>(OP_max, HandleMax);
289     RegisterFactoryFunction<HandleExprFactory>(OP_sqrt, HandleSqrt);
290     RegisterFactoryFunction<HandleExprFactory>(OP_ceil, HandleCeil);
291     RegisterFactoryFunction<HandleExprFactory>(OP_floor, HandleFloor);
292     RegisterFactoryFunction<HandleExprFactory>(OP_retype, HandleRetype);
293     RegisterFactoryFunction<HandleExprFactory>(OP_cvt, HandleCvt);
294     RegisterFactoryFunction<HandleExprFactory>(OP_trunc, HandleTrunc);
295     RegisterFactoryFunction<HandleExprFactory>(OP_le, HandleCmp);
296     RegisterFactoryFunction<HandleExprFactory>(OP_ge, HandleCmp);
297     RegisterFactoryFunction<HandleExprFactory>(OP_gt, HandleCmp);
298     RegisterFactoryFunction<HandleExprFactory>(OP_lt, HandleCmp);
299     RegisterFactoryFunction<HandleExprFactory>(OP_ne, HandleCmp);
300     RegisterFactoryFunction<HandleExprFactory>(OP_eq, HandleCmp);
301     RegisterFactoryFunction<HandleExprFactory>(OP_intrinsicop, HandleIntrinOp);
302 }
303 
HandleLabel(StmtNode & stmt,CGFunc & cgFunc)304 static void HandleLabel(StmtNode &stmt, CGFunc &cgFunc)
305 {
306     DEBUG_ASSERT(stmt.GetOpCode() == OP_label, "error");
307     auto &label = static_cast<LabelNode &>(stmt);
308     BB *newBB = cgFunc.StartNewBBImpl(false, label);
309     newBB->AddLabel(label.GetLabelIdx());
310     if (newBB->GetId() == 1) {
311         newBB->SetFrequency(kFreqBase);
312     }
313     cgFunc.SetLab2BBMap(newBB->GetLabIdx(), *newBB);
314     cgFunc.SetCurBB(*newBB);
315 }
316 
HandleGoto(StmtNode & stmt,CGFunc & cgFunc)317 static void HandleGoto(StmtNode &stmt, CGFunc &cgFunc)
318 {
319     auto &gotoNode = static_cast<GotoNode &>(stmt);
320     cgFunc.SetCurBBKind(BB::kBBGoto);
321     cgFunc.SelectGoto(gotoNode);
322     cgFunc.SetCurBB(*cgFunc.StartNewBB(gotoNode));
323     DEBUG_ASSERT(&stmt == &gotoNode, "stmt must be same as gotoNoe");
324 
325     if ((gotoNode.GetNext() != nullptr) && (gotoNode.GetNext()->GetOpCode() != OP_label)) {
326         DEBUG_ASSERT(cgFunc.GetCurBB()->GetPrev()->GetLastStmt() == &stmt, "check the relation between BB and stmt");
327     }
328 }
329 
HandleCondbr(StmtNode & stmt,CGFunc & cgFunc)330 static void HandleCondbr(StmtNode &stmt, CGFunc &cgFunc)
331 {
332     auto &condGotoNode = static_cast<CondGotoNode &>(stmt);
333     BaseNode *condNode = condGotoNode.Opnd(0);
334     DEBUG_ASSERT(condNode != nullptr, "expect first operand of cond br");
335     Opcode condOp = condGotoNode.GetOpCode();
336     if (condNode->GetOpCode() == OP_constval) {
337         auto *constValNode = static_cast<ConstvalNode *>(condNode);
338         if ((constValNode->GetConstVal()->IsZero() && (OP_brfalse == condOp)) ||
339             (!constValNode->GetConstVal()->IsZero() && (OP_brtrue == condOp))) {
340             auto *gotoStmt = cgFunc.GetMemoryPool()->New<GotoNode>(OP_goto);
341             gotoStmt->SetOffset(condGotoNode.GetOffset());
342             HandleGoto(*gotoStmt, cgFunc);
343             auto *labelStmt = cgFunc.GetMemoryPool()->New<LabelNode>();
344             labelStmt->SetLabelIdx(cgFunc.CreateLabel());
345             HandleLabel(*labelStmt, cgFunc);
346         }
347         return;
348     }
349     cgFunc.SetCurBBKind(BB::kBBIf);
350     /* if condNode is not a cmp node, cmp it with zero. */
351     if (!kOpcodeInfo.IsCompare(condNode->GetOpCode())) {
352         Operand *opnd0 = cgFunc.HandleExpr(condGotoNode, *condNode);
353         PrimType primType = condNode->GetPrimType();
354         Operand *zeroOpnd = nullptr;
355         if (IsPrimitiveInteger(primType)) {
356             zeroOpnd = &cgFunc.CreateImmOperand(primType, 0);
357         } else {
358             DEBUG_ASSERT(((PTY_f32 == primType) || (PTY_f64 == primType)),
359                          "we don't support half-precision FP operands yet");
360             zeroOpnd = &cgFunc.CreateImmOperand(primType, 0);
361         }
362         cgFunc.SelectCondGoto(condGotoNode, *opnd0, *zeroOpnd);
363         cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
364         return;
365     }
366     /*
367      * Special case:
368      * bgt (cmp (op0, op1), 0) ==>
369      * bgt (op0, op1)
370      * but skip the case cmp(op0, 0)
371      */
372     BaseNode *op0 = condNode->Opnd(0);
373     DEBUG_ASSERT(op0 != nullptr, "get first opnd of a condNode failed");
374     BaseNode *op1 = condNode->Opnd(1);
375     DEBUG_ASSERT(op1 != nullptr, "get second opnd of a condNode failed");
376     if ((op0->GetOpCode() == OP_cmp) && (op1->GetOpCode() == OP_constval)) {
377         auto *constValNode = static_cast<ConstvalNode *>(op1);
378         MIRConst *mirConst = constValNode->GetConstVal();
379         auto *cmpNode = static_cast<CompareNode *>(op0);
380         bool skip = false;
381         if (cmpNode->Opnd(1)->GetOpCode() == OP_constval) {
382             auto *constVal = static_cast<ConstvalNode *>(cmpNode->Opnd(1))->GetConstVal();
383             if (constVal->IsZero()) {
384                 skip = true;
385             }
386         }
387         if (!skip && mirConst->IsZero()) {
388             cgFunc.SelectCondSpecialCase1(condGotoNode, *op0);
389             cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
390             return;
391         }
392     }
393 
394     Operand *opnd0 = cgFunc.HandleExpr(*condNode, *condNode->Opnd(0));
395     Operand *opnd1 = cgFunc.HandleExpr(*condNode, *condNode->Opnd(1));
396     cgFunc.SelectCondGoto(condGotoNode, *opnd0, *opnd1);
397     cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
398 }
399 
HandleReturn(StmtNode & stmt,CGFunc & cgFunc)400 static void HandleReturn(StmtNode &stmt, CGFunc &cgFunc)
401 {
402     auto &retNode = static_cast<NaryStmtNode &>(stmt);
403     DEBUG_ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1");
404     Operand *opnd = nullptr;
405     if (retNode.NumOpnds() != 0) {
406         opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0));
407     }
408     cgFunc.SelectReturn(opnd);
409     cgFunc.SetCurBBKind(BB::kBBReturn);
410     cgFunc.SetCurBB(*cgFunc.StartNewBB(retNode));
411 }
412 
HandleCall(StmtNode & stmt,CGFunc & cgFunc)413 static void HandleCall(StmtNode &stmt, CGFunc &cgFunc)
414 {
415     auto &callNode = static_cast<CallNode &>(stmt);
416     cgFunc.SelectCall(callNode);
417 }
418 
HandleICall(StmtNode & stmt,CGFunc & cgFunc)419 static void HandleICall(StmtNode &stmt, CGFunc &cgFunc)
420 {
421     auto &icallNode = static_cast<IcallNode &>(stmt);
422     cgFunc.GetCurBB()->SetHasCall();
423     cgFunc.SelectIcall(icallNode);
424 }
425 
HandleIntrinsicCall(StmtNode & stmt,CGFunc & cgFunc)426 static void HandleIntrinsicCall(StmtNode &stmt, CGFunc &cgFunc)
427 {
428     auto &call = static_cast<IntrinsiccallNode &>(stmt);
429     cgFunc.SelectIntrinsicCall(call);
430 }
431 
HandleDeoptCall(StmtNode & stmt,CGFunc & cgFunc)432 static void HandleDeoptCall(StmtNode &stmt, CGFunc &cgFunc)
433 {
434     auto &deoptCallNode = static_cast<CallNode &>(stmt);
435     cgFunc.GetCurBB()->SetKind(BB::kBBNoReturn);
436     cgFunc.PushBackNoReturnCallBBsVec(*cgFunc.GetCurBB());
437     cgFunc.SelectDeoptCall(deoptCallNode);
438     cgFunc.SetCurBB(*cgFunc.StartNewBB(deoptCallNode));
439 }
440 
HandleTailICall(StmtNode & stmt,CGFunc & cgFunc)441 static void HandleTailICall(StmtNode &stmt, CGFunc &cgFunc)
442 {
443     auto &tailIcallNode = static_cast<IcallNode&>(stmt);
444     cgFunc.GetCurBB()->SetKind(BB::kBBNoReturn);
445     cgFunc.PushBackNoReturnCallBBsVec(*cgFunc.GetCurBB());
446     cgFunc.SelectTailICall(tailIcallNode);
447     cgFunc.SetCurBB(*cgFunc.StartNewBB(tailIcallNode));
448 }
449 
HandleDassign(StmtNode & stmt,CGFunc & cgFunc)450 static void HandleDassign(StmtNode &stmt, CGFunc &cgFunc)
451 {
452     auto &dassignNode = static_cast<DassignNode &>(stmt);
453     DEBUG_ASSERT(dassignNode.GetOpCode() == OP_dassign, "expect dassign");
454     BaseNode *rhs = dassignNode.GetRHS();
455     DEBUG_ASSERT(rhs != nullptr, "get rhs of dassignNode failed");
456     bool isSaveRetvalToLocal = false;
457     if (rhs->GetOpCode() == OP_regread) {
458         isSaveRetvalToLocal = (static_cast<RegreadNode *>(rhs)->GetRegIdx() == -kSregRetval0);
459     }
460     Operand *opnd0 = cgFunc.HandleExpr(dassignNode, *rhs);
461     cgFunc.SelectDassign(dassignNode, *opnd0);
462     if (isSaveRetvalToLocal && cgFunc.GetCurBB() && cgFunc.GetCurBB()->GetLastMachineInsn()) {
463         cgFunc.GetCurBB()->GetLastMachineInsn()->MarkAsSaveRetValToLocal();
464     }
465 }
466 
HandleRegassign(StmtNode & stmt,CGFunc & cgFunc)467 static void HandleRegassign(StmtNode &stmt, CGFunc &cgFunc)
468 {
469     DEBUG_ASSERT(stmt.GetOpCode() == OP_regassign, "expect regAssign");
470     auto &regAssignNode = static_cast<RegassignNode &>(stmt);
471     bool isSaveRetvalToLocal = false;
472     BaseNode *operand = regAssignNode.Opnd(0);
473     DEBUG_ASSERT(operand != nullptr, "get operand of regassignNode failed");
474     if (operand->GetOpCode() == OP_regread) {
475         isSaveRetvalToLocal = (static_cast<RegreadNode *>(operand)->GetRegIdx() == -kSregRetval0);
476     }
477     Operand *opnd0 = cgFunc.HandleExpr(regAssignNode, *operand);
478     cgFunc.SelectRegassign(regAssignNode, *opnd0);
479     if (isSaveRetvalToLocal && cgFunc.GetCurBB() && cgFunc.GetCurBB()->GetLastMachineInsn()) {
480         cgFunc.GetCurBB()->GetLastMachineInsn()->MarkAsSaveRetValToLocal();
481     }
482 }
483 
HandleIassign(StmtNode & stmt,CGFunc & cgFunc)484 static void HandleIassign(StmtNode &stmt, CGFunc &cgFunc)
485 {
486     DEBUG_ASSERT(stmt.GetOpCode() == OP_iassign, "expect stmt");
487     auto &iassignNode = static_cast<IassignNode &>(stmt);
488     if ((iassignNode.GetRHS() != nullptr)) {
489         cgFunc.SelectIassign(iassignNode);
490     } else {
491         CHECK_FATAL(false, "NIY");
492     }
493 }
494 
HandleRangeGoto(StmtNode & stmt,CGFunc & cgFunc)495 void HandleRangeGoto(StmtNode &stmt, CGFunc &cgFunc)
496 {
497     auto &rangeGotoNode = static_cast<RangeGotoNode &>(stmt);
498     cgFunc.SetCurBBKind(BB::kBBRangeGoto);
499     cgFunc.SelectRangeGoto(rangeGotoNode, *cgFunc.HandleExpr(rangeGotoNode, *rangeGotoNode.Opnd(0)));
500     cgFunc.SetCurBB(*cgFunc.StartNewBB(rangeGotoNode));
501 }
502 
HandleComment(StmtNode & stmt,CGFunc & cgFunc)503 void HandleComment(StmtNode &stmt, CGFunc &cgFunc)
504 {
505     if (cgFunc.GetCG()->GenerateVerboseAsm() || cgFunc.GetCG()->GenerateVerboseCG()) {
506         cgFunc.SelectComment(static_cast<CommentNode &>(stmt));
507     }
508 }
509 
510 using HandleStmtFactory = FunctionFactory<Opcode, void, StmtNode &, CGFunc &>;
InitHandleStmtFactory()511 static void InitHandleStmtFactory()
512 {
513     RegisterFactoryFunction<HandleStmtFactory>(OP_label, HandleLabel);
514     RegisterFactoryFunction<HandleStmtFactory>(OP_goto, HandleGoto);
515     RegisterFactoryFunction<HandleStmtFactory>(OP_brfalse, HandleCondbr);
516     RegisterFactoryFunction<HandleStmtFactory>(OP_brtrue, HandleCondbr);
517     RegisterFactoryFunction<HandleStmtFactory>(OP_return, HandleReturn);
518     RegisterFactoryFunction<HandleStmtFactory>(OP_call, HandleCall);
519     RegisterFactoryFunction<HandleStmtFactory>(OP_icall, HandleICall);
520     RegisterFactoryFunction<HandleStmtFactory>(OP_icallproto, HandleICall);
521     RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccall, HandleIntrinsicCall);
522     RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccallassigned, HandleIntrinsicCall);
523     RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccallwithtype, HandleIntrinsicCall);
524     RegisterFactoryFunction<HandleStmtFactory>(OP_deoptcall, HandleDeoptCall);
525     RegisterFactoryFunction<HandleStmtFactory>(OP_tailicall, HandleTailICall);
526     RegisterFactoryFunction<HandleStmtFactory>(OP_dassign, HandleDassign);
527     RegisterFactoryFunction<HandleStmtFactory>(OP_regassign, HandleRegassign);
528     RegisterFactoryFunction<HandleStmtFactory>(OP_iassign, HandleIassign);
529     RegisterFactoryFunction<HandleStmtFactory>(OP_rangegoto, HandleRangeGoto);
530     RegisterFactoryFunction<HandleStmtFactory>(OP_comment, HandleComment);
531 }
532 
CGFunc(MIRModule & mod,CG & cg,MIRFunction & mirFunc,BECommon & beCommon,MemPool & memPool,StackMemPool & stackMp,MapleAllocator & allocator,uint32 funcId)533 CGFunc::CGFunc(MIRModule &mod, CG &cg, MIRFunction &mirFunc, BECommon &beCommon, MemPool &memPool,
534                StackMemPool &stackMp, MapleAllocator &allocator, uint32 funcId)
535     : bbVec(allocator.Adapter()),
536       referenceVirtualRegs(allocator.Adapter()),
537       pregIdx2Opnd(mirFunc.GetPregTab()->Size(), nullptr, allocator.Adapter()),
538       pRegSpillMemOperands(allocator.Adapter()),
539       spillRegMemOperands(allocator.Adapter()),
540       reuseSpillLocMem(allocator.Adapter()),
541       labelMap(std::less<LabelIdx>(), allocator.Adapter()),
542       vregsToPregsMap(std::less<regno_t>(), allocator.Adapter()),
543       stackMapInsns(allocator.Adapter()),
544       hasVLAOrAlloca(mirFunc.HasVlaOrAlloca()),
545       cg(&cg),
546       mirModule(mod),
547       memPool(&memPool),
548       stackMp(stackMp),
549       func(mirFunc),
550       exitBBVec(allocator.Adapter()),
551       noReturnCallBBVec(allocator.Adapter()),
552       extendSet(allocator.Adapter()),
553       lab2BBMap(allocator.Adapter()),
554       beCommon(beCommon),
555       funcScopeAllocator(&allocator),
556       emitStVec(allocator.Adapter()),
557       switchLabelCnt(allocator.Adapter()),
558       shortFuncName(mirFunc.GetName() + "." + std::to_string(funcId), &memPool)
559 {
560     mirModule.SetCurFunction(&func);
561     dummyBB = CreateNewBB();
562     vReg.SetCount(static_cast<uint32>(kBaseVirtualRegNO + func.GetPregTab()->Size()));
563     firstNonPregVRegNO = vReg.GetCount();
564     /* maximum register count initial be increased by 1024 */
565     SetMaxRegNum(vReg.GetCount() + 1024);
566 
567     maplebe::VregInfo::vRegOperandTable.clear();
568 
569     insnBuilder = memPool.New<InsnBuilder>(memPool);
570     opndBuilder = memPool.New<OperandBuilder>(memPool, func.GetPregTab()->Size());
571 
572     vReg.VRegTableResize(GetMaxRegNum());
573     /* func.GetPregTab()->_preg_table[0] is nullptr, so skip it */
574     DEBUG_ASSERT(func.GetPregTab()->PregFromPregIdx(0) == nullptr, "PregFromPregIdx(0) must be nullptr");
575     for (size_t i = 1; i < func.GetPregTab()->Size(); ++i) {
576         PrimType primType = func.GetPregTab()->PregFromPregIdx(i)->GetPrimType();
577         uint32 byteLen = GetPrimTypeSize(primType);
578         if (byteLen < k4ByteSize) {
579             byteLen = k4ByteSize;
580         }
581         new (&GetVirtualRegNodeFromPseudoRegIdx(i)) VirtualRegNode(GetRegTyFromPrimTy(primType), byteLen);
582     }
583     lSymSize = 0;
584     if (func.GetSymTab()) {
585         lSymSize = func.GetSymTab()->GetSymbolTableSize();
586     }
587     callingConventionKind = CCImpl::GetCallConvKind(mirFunc);
588 }
589 
~CGFunc()590 CGFunc::~CGFunc()
591 {
592     mirModule.SetCurFunction(nullptr);
593 }
594 
HandleExpr(const BaseNode & parent,BaseNode & expr)595 Operand *CGFunc::HandleExpr(const BaseNode &parent, BaseNode &expr)
596 {
597     auto function = CreateProductFunction<HandleExprFactory>(expr.GetOpCode());
598     CHECK_FATAL(function != nullptr, "unsupported %d opCode in HandleExpr()", expr.GetOpCode());
599     return function(parent, expr, *this);
600 }
601 
HandleFirstStmt()602 StmtNode *CGFunc::HandleFirstStmt()
603 {
604     BlockNode *block = func.GetBody();
605 
606     DEBUG_ASSERT(block != nullptr, "get func body block failed in CGFunc::GenerateInstruction");
607     StmtNode *stmt = block->GetFirst();
608     if (stmt == nullptr) {
609         return nullptr;
610     }
611     DEBUG_ASSERT(stmt->GetOpCode() == OP_label, "The first statement should be a label");
612     HandleLabel(*stmt, *this);
613     firstBB = curBB;
614     stmt = stmt->GetNext();
615     if (stmt == nullptr) {
616         return nullptr;
617     }
618     curBB = StartNewBBImpl(false, *stmt);
619     return stmt;
620 }
621 
RemoveUnreachableBB()622 void CGFunc::RemoveUnreachableBB()
623 {
624     OptimizationPattern *pattern = memPool->New<UnreachBBPattern>(*this);
625     for (BB *bb = firstBB; bb != nullptr; bb = bb->GetNext()) {
626         (void)pattern->Optimize(*bb);
627     }
628 }
629 
GenerateInstruction()630 void CGFunc::GenerateInstruction()
631 {
632     InitHandleExprFactory();
633     InitHandleStmtFactory();
634     StmtNode *secondStmt = HandleFirstStmt();
635 
636     std::set<uint32> bbFreqSet;
637     for (StmtNode *stmt = secondStmt; stmt != nullptr; stmt = stmt->GetNext()) {
638         GetInsnBuilder()->SetDebugComment(stmt->GetDebugComment());
639         auto function = CreateProductFunction<HandleStmtFactory>(stmt->GetOpCode());
640         CHECK_FATAL(function != nullptr, "unsupported opCode or has been lowered before");
641         function(*stmt, *this);
642         GetInsnBuilder()->ClearDebugComment();
643     }
644 
645     /* Set lastbb's frequency */
646     BlockNode *block = func.GetBody();
647     DEBUG_ASSERT(block != nullptr, "get func body block failed in CGFunc::GenerateInstruction");
648     curBB->SetLastStmt(*block->GetLast());
649     lastBB = curBB;
650 }
651 
CreateLabel()652 LabelIdx CGFunc::CreateLabel()
653 {
654     MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
655     DEBUG_ASSERT(funcSt != nullptr, "Get func failed at CGFunc::CreateLabel");
656     std::string funcName = funcSt->GetName();
657     std::string labelStr = funcName += std::to_string(labelIdx++);
658     return func.GetOrCreateLableIdxFromName(labelStr);
659 }
660 
ProcessExitBBVec()661 void CGFunc::ProcessExitBBVec()
662 {
663     if (exitBBVec.empty()) {
664         BB *retBB = CreateNewBB();
665         retBB->SetKind(BB::kBBReturn);
666         SetLab2BBMap(retBB->GetLabIdx(), *retBB);
667         GetLastBB()->PrependBB(*retBB);
668         exitBBVec.emplace_back(retBB);
669         return;
670     }
671     /* split an empty exitBB */
672     BB *bb = exitBBVec[0];
673     if (bb->NumInsn() > 0) {
674         BB *retBBPart = CreateNewBB(false, BB::kBBFallthru, bb->GetFrequency());
675         DEBUG_ASSERT(retBBPart != nullptr, "retBBPart should not be nullptr");
676         LabelIdx retBBPartLabelIdx = bb->GetLabIdx();
677         if (retBBPartLabelIdx != MIRLabelTable::GetDummyLabel()) {
678             retBBPart->AddLabel(retBBPartLabelIdx);
679             lab2BBMap[retBBPartLabelIdx] = retBBPart;
680         }
681         Insn *insn = bb->GetFirstInsn();
682         while (insn != nullptr) {
683             bb->RemoveInsn(*insn);
684             retBBPart->AppendInsn(*insn);
685             insn = bb->GetFirstInsn();
686         }
687         bb->PrependBB(*retBBPart);
688         LabelIdx newLabelIdx = CreateLabel();
689         bb->AddLabel(newLabelIdx);
690         lab2BBMap[newLabelIdx] = bb;
691     }
692 }
693 
AddCommonExitBB()694 void CGFunc::AddCommonExitBB()
695 {
696     if (commonExitBB != nullptr) {
697         return;
698     }
699     // create fake commonExitBB
700     commonExitBB = CreateNewBB(true, BB::kBBFallthru, 0);
701     DEBUG_ASSERT(commonExitBB != nullptr, "cannot create fake commonExitBB");
702     for (BB *cgbb : exitBBVec) {
703         if (!cgbb->IsUnreachable()) {
704             commonExitBB->PushBackPreds(*cgbb);
705         }
706     }
707 }
708 
HandleFunction()709 void CGFunc::HandleFunction()
710 {
711     /* select instruction */
712     GenerateInstruction();
713     /* merge multi return */
714     MergeReturn();
715     ProcessExitBBVec();
716     /* build control flow graph */
717     theCFG = memPool->New<CGCFG>(*this);
718     theCFG->BuildCFG();
719     RemoveUnreachableBB();
720     AddCommonExitBB();
721     theCFG->UnreachCodeAnalysis();
722     EraseUnreachableStackMapInsns();
723 }
724 
DumpCFG() const725 void CGFunc::DumpCFG() const
726 {
727 #ifdef ARK_LITECG_DEBUG
728     MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
729     DEBUG_ASSERT(funcSt != nullptr, "null ptr check");
730     LogInfo::MapleLogger() << "\n****** CFG built by CG for " << funcSt->GetName() << " *******\n";
731     FOR_ALL_BB_CONST(bb, this)
732     {
733         LogInfo::MapleLogger() << "=== BB ( " << std::hex << bb << std::dec << " ) <" << bb->GetKindName() << "> ===\n";
734         LogInfo::MapleLogger() << "BB id:" << bb->GetId() << "\n";
735         if (!bb->GetPreds().empty()) {
736             LogInfo::MapleLogger() << " pred [ ";
737             for (auto *pred : bb->GetPreds()) {
738                 LogInfo::MapleLogger() << pred->GetId() << " ";
739             }
740             LogInfo::MapleLogger() << "]\n";
741         }
742         if (!bb->GetSuccs().empty()) {
743             LogInfo::MapleLogger() << " succ [ ";
744             for (auto *succ : bb->GetSuccs()) {
745                 LogInfo::MapleLogger() << succ->GetId() << " ";
746             }
747             LogInfo::MapleLogger() << "]\n";
748         }
749         const StmtNode *stmt = bb->GetFirstStmt();
750         if (stmt != nullptr) {
751             bool done = false;
752             do {
753                 done = stmt == bb->GetLastStmt();
754                 stmt->Dump(1);
755                 LogInfo::MapleLogger() << "\n";
756                 stmt = stmt->GetNext();
757             } while (!done);
758         } else {
759             LogInfo::MapleLogger() << "<empty BB>\n";
760         }
761     }
762 #endif
763 }
764 
DumpBBInfo(const BB * bb) const765 void CGFunc::DumpBBInfo(const BB *bb) const
766 {
767 #ifdef ARK_LITECG_DEBUG
768     LogInfo::MapleLogger() << "=== BB " << " <" << bb->GetKindName();
769     if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) {
770         LogInfo::MapleLogger() << "[labeled with " << bb->GetLabIdx();
771         LogInfo::MapleLogger() << " ==> @" << func.GetLabelName(bb->GetLabIdx()) << "]";
772     }
773 
774     LogInfo::MapleLogger() << "> <" << bb->GetId() << "> ";
775     if (bb->IsCleanup()) {
776         LogInfo::MapleLogger() << "[is_cleanup] ";
777     }
778     if (bb->IsUnreachable()) {
779         LogInfo::MapleLogger() << "[unreachable] ";
780     }
781     if (!bb->GetSuccs().empty()) {
782         LogInfo::MapleLogger() << "succs: ";
783         for (auto *succBB : bb->GetSuccs()) {
784             LogInfo::MapleLogger() << succBB->GetId() << " ";
785         }
786     }
787     if (!bb->GetPreds().empty()) {
788         LogInfo::MapleLogger() << "preds: ";
789         for (auto *predBB : bb->GetPreds()) {
790             LogInfo::MapleLogger() << predBB->GetId() << " ";
791         }
792     }
793     LogInfo::MapleLogger() << "===\n";
794     LogInfo::MapleLogger() << "frequency:" << bb->GetFrequency() << "\n";
795 #endif
796 }
797 
DumpCGIR() const798 void CGFunc::DumpCGIR() const
799 {
800 #ifdef ARK_LITECG_DEBUG
801     MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
802     DEBUG_ASSERT(funcSt != nullptr, "null ptr check");
803     LogInfo::MapleLogger() << "\n******  CGIR for " << funcSt->GetName() << " *******\n";
804     FOR_ALL_BB_CONST(bb, this)
805     {
806         if (bb->IsUnreachable()) {
807             continue;
808         }
809         DumpBBInfo(bb);
810         FOR_BB_INSNS_CONST(insn, bb)
811         {
812             insn->Dump();
813         }
814     }
815 #endif
816 }
817 
818 // Cgirverify phase function: all insns will be verified before cgemit.
VerifyAllInsn()819 void CGFunc::VerifyAllInsn()
820 {
821 #ifdef ARK_LITECG_DEBUG
822     FOR_ALL_BB(bb, this)
823     {
824         FOR_BB_INSNS(insn, bb)
825         {
826             if (VERIFY_INSN(insn) && insn->CheckMD()) {
827                 continue;
828             }
829             LogInfo::MapleLogger() << "Illegal insn is:\n";
830             insn->Dump();
831             LogInfo::MapleLogger() << "Function name is:\n" << GetName() << "\n";
832             CHECK_FATAL_FALSE("The problem is illegal insn, info is above.");
833         }
834     }
835 #endif
836 }
837 
PhaseRun(maplebe::CGFunc & f)838 bool CgHandleFunction::PhaseRun(maplebe::CGFunc &f)
839 {
840     f.HandleFunction();
841     return false;
842 }
MAPLE_TRANSFORM_PHASE_REGISTER(CgHandleFunction,handlefunction)843 MAPLE_TRANSFORM_PHASE_REGISTER(CgHandleFunction, handlefunction)
844 
845 bool CgVerify::PhaseRun(maplebe::CGFunc &f)
846 {
847 #ifdef ARK_LITECG_DEBUG
848     f.VerifyAllInsn();
849     if (!f.GetCG()->GetCGOptions().DoEmitCode() || f.GetCG()->GetCGOptions().DoDumpCFG()) {
850         f.DumpCFG();
851     }
852 #endif
853     return false;
854 }
855 MAPLE_TRANSFORM_PHASE_REGISTER(CgVerify, cgirverify)
856 } /* namespace maplebe */
857