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 ®ReadNode = 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 ®AssignNode = 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