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 #include <iomanip>
19 #endif
20 #include "cg.h"
21 #include "insn.h"
22 #include "loop.h"
23 #include "mir_builder.h"
24 #include "factory.h"
25 #include "debug_info.h"
26 #include "optimize_common.h"
27
28 namespace maplebe {
29 using namespace maple;
30
31 #define JAVALANG (GetMirModule().IsJavaModule())
32
HandleDread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)33 Operand *HandleDread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
34 {
35 auto &dreadNode = static_cast<AddrofNode &>(expr);
36 return cgFunc.SelectDread(parent, dreadNode);
37 }
38
HandleRegread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)39 Operand *HandleRegread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
40 {
41 (void)parent;
42 auto ®ReadNode = static_cast<RegreadNode &>(expr);
43 if (regReadNode.GetRegIdx() == -kSregRetval0 || regReadNode.GetRegIdx() == -kSregRetval1) {
44 return &cgFunc.ProcessReturnReg(regReadNode.GetPrimType(), -(regReadNode.GetRegIdx()));
45 }
46 return cgFunc.SelectRegread(regReadNode);
47 }
48
HandleConstVal(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)49 Operand *HandleConstVal(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
50 {
51 auto &constValNode = static_cast<ConstvalNode &>(expr);
52 MIRConst *mirConst = constValNode.GetConstVal();
53 DEBUG_ASSERT(mirConst != nullptr, "get constval of constvalnode failed");
54 if (mirConst->GetKind() == kConstInt) {
55 auto *mirIntConst = safe_cast<MIRIntConst>(mirConst);
56 return cgFunc.SelectIntConst(*mirIntConst);
57 } else if (mirConst->GetKind() == kConstFloatConst) {
58 auto *mirFloatConst = safe_cast<MIRFloatConst>(mirConst);
59 return cgFunc.SelectFloatConst(*mirFloatConst, parent);
60 } else if (mirConst->GetKind() == kConstDoubleConst) {
61 auto *mirDoubleConst = safe_cast<MIRDoubleConst>(mirConst);
62 return cgFunc.SelectDoubleConst(*mirDoubleConst, parent);
63 } else {
64 CHECK_FATAL(false, "NYI");
65 }
66 return nullptr;
67 }
68
HandleConstStr(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)69 Operand *HandleConstStr(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
70 {
71 (void)parent;
72 auto &constStrNode = static_cast<ConststrNode &>(expr);
73 #if TARGAARCH64 || TARGRISCV64
74 if (CGOptions::IsArm64ilp32()) {
75 return cgFunc.SelectStrConst(*cgFunc.GetMemoryPool()->New<MIRStrConst>(
76 constStrNode.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_a32))));
77 } else {
78 return cgFunc.SelectStrConst(*cgFunc.GetMemoryPool()->New<MIRStrConst>(
79 constStrNode.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_a64))));
80 }
81 #else
82 return cgFunc.SelectStrConst(*cgFunc.GetMemoryPool()->New<MIRStrConst>(
83 constStrNode.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)PTY_a32)));
84 #endif
85 }
86
HandleConstStr16(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)87 Operand *HandleConstStr16(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
88 {
89 (void)parent;
90 auto &constStr16Node = static_cast<Conststr16Node &>(expr);
91 #if TARGAARCH64 || TARGRISCV64
92 if (CGOptions::IsArm64ilp32()) {
93 return cgFunc.SelectStr16Const(*cgFunc.GetMemoryPool()->New<MIRStr16Const>(
94 constStr16Node.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_a32))));
95 } else {
96 return cgFunc.SelectStr16Const(*cgFunc.GetMemoryPool()->New<MIRStr16Const>(
97 constStr16Node.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_a64))));
98 }
99 #else
100 return cgFunc.SelectStr16Const(*cgFunc.GetMemoryPool()->New<MIRStr16Const>(
101 constStr16Node.GetStrIdx(), *GlobalTables::GetTypeTable().GetTypeFromTyIdx((TyIdx)PTY_a32)));
102 #endif
103 }
104
HandleAdd(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)105 Operand *HandleAdd(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
106 {
107 if (Globals::GetInstance()->GetOptimLevel() >= CGOptions::kLevel2 && expr.Opnd(0)->GetOpCode() == OP_mul &&
108 !IsPrimitiveVector(expr.GetPrimType()) && !IsPrimitiveFloat(expr.GetPrimType()) &&
109 expr.Opnd(0)->Opnd(0)->GetOpCode() != OP_constval && expr.Opnd(0)->Opnd(1)->GetOpCode() != OP_constval) {
110 return cgFunc.SelectMadd(
111 static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(*expr.Opnd(0), *expr.Opnd(0)->Opnd(0)),
112 *cgFunc.HandleExpr(*expr.Opnd(0), *expr.Opnd(0)->Opnd(1)), *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
113 } else if (Globals::GetInstance()->GetOptimLevel() >= CGOptions::kLevel2 && expr.Opnd(1)->GetOpCode() == OP_mul &&
114 !IsPrimitiveVector(expr.GetPrimType()) && !IsPrimitiveFloat(expr.GetPrimType()) &&
115 expr.Opnd(1)->Opnd(0)->GetOpCode() != OP_constval && expr.Opnd(1)->Opnd(1)->GetOpCode() != OP_constval) {
116 return cgFunc.SelectMadd(
117 static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(*expr.Opnd(0), *expr.Opnd(1)->Opnd(0)),
118 *cgFunc.HandleExpr(*expr.Opnd(0), *expr.Opnd(1)->Opnd(1)), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
119 } else {
120 return cgFunc.SelectAdd(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
121 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
122 }
123 }
124
HandleCGArrayElemAdd(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)125 Operand *HandleCGArrayElemAdd(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
126 {
127 return &cgFunc.SelectCGArrayElemAdd(static_cast<BinaryNode &>(expr), parent);
128 }
129
IsConstantInVectorFromScalar(BaseNode * expr)130 BaseNode *IsConstantInVectorFromScalar(BaseNode *expr)
131 {
132 if (expr->op != OP_intrinsicop) {
133 return nullptr;
134 }
135 IntrinsicopNode *intrn = static_cast<IntrinsicopNode *>(expr);
136 switch (intrn->GetIntrinsic()) {
137 case INTRN_vector_from_scalar_v8u8:
138 case INTRN_vector_from_scalar_v8i8:
139 case INTRN_vector_from_scalar_v4u16:
140 case INTRN_vector_from_scalar_v4i16:
141 case INTRN_vector_from_scalar_v2u32:
142 case INTRN_vector_from_scalar_v2i32:
143 case INTRN_vector_from_scalar_v1u64:
144 case INTRN_vector_from_scalar_v1i64:
145 case INTRN_vector_from_scalar_v16u8:
146 case INTRN_vector_from_scalar_v16i8:
147 case INTRN_vector_from_scalar_v8u16:
148 case INTRN_vector_from_scalar_v8i16:
149 case INTRN_vector_from_scalar_v4u32:
150 case INTRN_vector_from_scalar_v4i32:
151 case INTRN_vector_from_scalar_v2u64:
152 case INTRN_vector_from_scalar_v2i64: {
153 if (intrn->Opnd(0) != nullptr && intrn->Opnd(0)->op == OP_constval) {
154 return intrn->Opnd(0);
155 }
156 break;
157 }
158 default:
159 break;
160 }
161 return nullptr;
162 }
163
HandleShift(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)164 Operand *HandleShift(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
165 {
166 BaseNode *cExpr = IsConstantInVectorFromScalar(expr.Opnd(1));
167 if (cExpr == nullptr) {
168 return cgFunc.SelectShift(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
169 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
170 } else {
171 return cgFunc.SelectShift(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
172 *cgFunc.HandleExpr(*expr.Opnd(1), *cExpr), parent);
173 }
174 }
175
HandleRor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)176 Operand *HandleRor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
177 {
178 return cgFunc.SelectRor(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
179 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
180 }
181
HandleMpy(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)182 Operand *HandleMpy(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
183 {
184 return cgFunc.SelectMpy(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
185 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
186 }
187
HandleDiv(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)188 Operand *HandleDiv(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
189 {
190 return cgFunc.SelectDiv(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
191 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
192 }
193
HandleRem(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)194 Operand *HandleRem(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
195 {
196 return cgFunc.SelectRem(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
197 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
198 }
199
HandleAddrof(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)200 Operand *HandleAddrof(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
201 {
202 auto &addrofNode = static_cast<AddrofNode &>(expr);
203 return cgFunc.SelectAddrof(addrofNode, parent, false);
204 }
205
HandleAddrofoff(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)206 Operand *HandleAddrofoff(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
207 {
208 auto &addrofoffNode = static_cast<AddrofoffNode &>(expr);
209 return cgFunc.SelectAddrofoff(addrofoffNode, parent);
210 }
211
HandleAddroffunc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)212 Operand *HandleAddroffunc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
213 {
214 auto &addroffuncNode = static_cast<AddroffuncNode &>(expr);
215 return &cgFunc.SelectAddrofFunc(addroffuncNode, parent);
216 }
217
HandleAddrofLabel(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)218 Operand *HandleAddrofLabel(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
219 {
220 auto &addrofLabelNode = static_cast<AddroflabelNode &>(expr);
221 return &cgFunc.SelectAddrofLabel(addrofLabelNode, parent);
222 }
223
HandleIread(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)224 Operand *HandleIread(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
225 {
226 auto &ireadNode = static_cast<IreadNode &>(expr);
227 return cgFunc.SelectIread(parent, ireadNode);
228 }
229
HandleIreadoff(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)230 Operand *HandleIreadoff(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
231 {
232 auto &ireadNode = static_cast<IreadoffNode &>(expr);
233 return cgFunc.SelectIreadoff(parent, ireadNode);
234 }
235
HandleIreadfpoff(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)236 Operand *HandleIreadfpoff(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
237 {
238 auto &ireadNode = static_cast<IreadFPoffNode &>(expr);
239 return cgFunc.SelectIreadfpoff(parent, ireadNode);
240 }
241
HandleSub(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)242 Operand *HandleSub(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
243 {
244 return cgFunc.SelectSub(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
245 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
246 }
247
HandleBand(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)248 Operand *HandleBand(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
249 {
250 return cgFunc.SelectBand(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
251 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
252 }
253
HandleBior(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)254 Operand *HandleBior(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
255 {
256 return cgFunc.SelectBior(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
257 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
258 }
259
HandleBxor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)260 Operand *HandleBxor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
261 {
262 return cgFunc.SelectBxor(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
263 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
264 }
265
HandleAbs(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)266 Operand *HandleAbs(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
267 {
268 (void)parent;
269 return cgFunc.SelectAbs(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
270 }
271
HandleBnot(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)272 Operand *HandleBnot(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
273 {
274 return cgFunc.SelectBnot(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
275 }
276
HandleExtractBits(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)277 Operand *HandleExtractBits(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
278 {
279 ExtractbitsNode &node = static_cast<ExtractbitsNode &>(expr);
280 uint8 bitOffset = node.GetBitsOffset();
281 uint8 bitSize = node.GetBitsSize();
282 if (!CGOptions::IsBigEndian() && (bitSize == k8BitSize || bitSize == k16BitSize) &&
283 GetPrimTypeBitSize(node.GetPrimType()) != k64BitSize &&
284 (bitOffset == 0 || bitOffset == k8BitSize || bitOffset == k16BitSize || bitOffset == k24BitSize) &&
285 expr.Opnd(0)->GetOpCode() == OP_iread && node.GetOpCode() == OP_extractbits) {
286 return cgFunc.SelectRegularBitFieldLoad(node, parent);
287 }
288 return cgFunc.SelectExtractbits(static_cast<ExtractbitsNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
289 parent);
290 }
291
HandleDepositBits(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)292 Operand *HandleDepositBits(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
293 {
294 return cgFunc.SelectDepositBits(static_cast<DepositbitsNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
295 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
296 }
297
HandleLnot(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)298 Operand *HandleLnot(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
299 {
300 return cgFunc.SelectLnot(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
301 }
302
HandleLand(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)303 Operand *HandleLand(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
304 {
305 return cgFunc.SelectLand(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
306 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
307 }
308
HandleLor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)309 Operand *HandleLor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
310 {
311 if (parent.IsCondBr()) {
312 return cgFunc.SelectLor(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
313 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent, true);
314 } else {
315 return cgFunc.SelectLor(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
316 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
317 }
318 }
319
HandleMin(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)320 Operand *HandleMin(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
321 {
322 return cgFunc.SelectMin(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
323 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
324 }
325
HandleMax(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)326 Operand *HandleMax(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
327 {
328 return cgFunc.SelectMax(static_cast<BinaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
329 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
330 }
331
HandleNeg(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)332 Operand *HandleNeg(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
333 {
334 return cgFunc.SelectNeg(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
335 }
336
HandleRecip(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)337 Operand *HandleRecip(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
338 {
339 return cgFunc.SelectRecip(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
340 }
341
HandleSqrt(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)342 Operand *HandleSqrt(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
343 {
344 return cgFunc.SelectSqrt(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
345 }
346
HandleCeil(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)347 Operand *HandleCeil(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
348 {
349 return cgFunc.SelectCeil(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
350 }
351
HandleFloor(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)352 Operand *HandleFloor(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
353 {
354 return cgFunc.SelectFloor(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
355 }
356
HandleRetype(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)357 Operand *HandleRetype(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
358 {
359 (void)parent;
360 return cgFunc.SelectRetype(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
361 }
362
HandleCvt(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)363 Operand *HandleCvt(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
364 {
365 return cgFunc.SelectCvt(parent, static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
366 }
367
HandleRound(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)368 Operand *HandleRound(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
369 {
370 return cgFunc.SelectRound(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
371 }
372
HandleTrunc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)373 Operand *HandleTrunc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
374 {
375 return cgFunc.SelectTrunc(static_cast<TypeCvtNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
376 }
377
HasCompare(const BaseNode * expr)378 static bool HasCompare(const BaseNode *expr)
379 {
380 if (kOpcodeInfo.IsCompare(expr->GetOpCode())) {
381 return true;
382 }
383 for (size_t i = 0; i < expr->GetNumOpnds(); ++i) {
384 if (HasCompare(expr->Opnd(i))) {
385 return true;
386 }
387 }
388 return false;
389 }
390
HandleSelect(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)391 Operand *HandleSelect(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
392 {
393 /* 0,1,2 represent the first opnd and the second opnd and the third opnd of expr */
394 bool hasCompare = false;
395 if (HasCompare(expr.Opnd(kSecondOpnd)) || HasCompare(expr.Opnd(kThirdOpnd))) {
396 hasCompare = true;
397 }
398 Operand &trueOpnd = *cgFunc.HandleExpr(expr, *expr.Opnd(1));
399 Operand &falseOpnd = *cgFunc.HandleExpr(expr, *expr.Opnd(2));
400 Operand *cond = cgFunc.HandleExpr(expr, *expr.Opnd(0));
401 return cgFunc.SelectSelect(static_cast<TernaryNode &>(expr), *cond, trueOpnd, falseOpnd, parent, hasCompare);
402 }
403
HandleCmp(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)404 Operand *HandleCmp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
405 {
406 // fix opnd type before select insn
407 PrimType targetPtyp = parent.GetPrimType();
408 if (kOpcodeInfo.IsCompare(parent.GetOpCode())) {
409 targetPtyp = static_cast<const CompareNode &>(parent).GetOpndType();
410 } else if (kOpcodeInfo.IsTypeCvt(parent.GetOpCode())) {
411 targetPtyp = static_cast<const TypeCvtNode &>(parent).FromType();
412 }
413 if (IsPrimitiveInteger(targetPtyp) && targetPtyp != expr.GetPrimType()) {
414 expr.SetPrimType(targetPtyp);
415 }
416 return cgFunc.SelectCmpOp(static_cast<CompareNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)),
417 *cgFunc.HandleExpr(expr, *expr.Opnd(1)), parent);
418 }
419
HandleAlloca(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)420 Operand *HandleAlloca(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
421 {
422 (void)parent;
423 return cgFunc.SelectAlloca(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
424 }
425
HandleMalloc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)426 Operand *HandleMalloc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
427 {
428 (void)parent;
429 return cgFunc.SelectMalloc(static_cast<UnaryNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
430 }
431
HandleGCMalloc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)432 Operand *HandleGCMalloc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
433 {
434 (void)parent;
435 return cgFunc.SelectGCMalloc(static_cast<GCMallocNode &>(expr));
436 }
437
HandleJarrayMalloc(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)438 Operand *HandleJarrayMalloc(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
439 {
440 (void)parent;
441 return cgFunc.SelectJarrayMalloc(static_cast<JarrayMallocNode &>(expr), *cgFunc.HandleExpr(expr, *expr.Opnd(0)));
442 }
443
444 /* Neon intrinsic handling */
HandleVectorAddLong(const BaseNode & expr,CGFunc & cgFunc,bool isLow)445 Operand *HandleVectorAddLong(const BaseNode &expr, CGFunc &cgFunc, bool isLow)
446 {
447 Operand *o1 = cgFunc.HandleExpr(expr, *expr.Opnd(0));
448 Operand *o2 = cgFunc.HandleExpr(expr, *expr.Opnd(1));
449 return cgFunc.SelectVectorAddLong(expr.GetPrimType(), o1, o2, expr.Opnd(0)->GetPrimType(), isLow);
450 }
451
HandleVectorAddWiden(const BaseNode & expr,CGFunc & cgFunc,bool isLow)452 Operand *HandleVectorAddWiden(const BaseNode &expr, CGFunc &cgFunc, bool isLow)
453 {
454 Operand *o1 = cgFunc.HandleExpr(expr, *expr.Opnd(0));
455 Operand *o2 = cgFunc.HandleExpr(expr, *expr.Opnd(1));
456 return cgFunc.SelectVectorAddWiden(o1, expr.Opnd(0)->GetPrimType(), o2, expr.Opnd(1)->GetPrimType(), isLow);
457 }
458
HandleVectorFromScalar(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)459 Operand *HandleVectorFromScalar(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
460 {
461 return cgFunc.SelectVectorFromScalar(intrnNode.GetPrimType(), cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)),
462 intrnNode.Opnd(0)->GetPrimType());
463 }
464
HandleVectorAbsSubL(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow)465 Operand *HandleVectorAbsSubL(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow)
466 {
467 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand 1 */
468 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector operand 2 */
469 return cgFunc.SelectVectorAbsSubL(intrnNode.GetPrimType(), opnd1, opnd2, intrnNode.Opnd(0)->GetPrimType(), isLow);
470 }
471
HandleVectorMerge(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)472 Operand *HandleVectorMerge(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
473 {
474 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand1 */
475 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector operand2 */
476 BaseNode *index = intrnNode.Opnd(2); /* index operand */
477 int32 iNum = 0;
478 if (index->GetOpCode() == OP_constval) {
479 MIRConst *mirConst = static_cast<ConstvalNode *>(index)->GetConstVal();
480 iNum = static_cast<int32>(safe_cast<MIRIntConst>(mirConst)->GetExtValue());
481 PrimType ty = intrnNode.Opnd(0)->GetPrimType();
482 if (!IsPrimitiveVector(ty)) {
483 iNum = 0;
484 } else {
485 iNum *= GetPrimTypeSize(ty) / GetVecLanes(ty); /* 64x2: 0-1 -> 0-8 */
486 }
487 } else { /* 32x4: 0-3 -> 0-12 */
488 CHECK_FATAL(0, "VectorMerge does not have const index");
489 }
490 return cgFunc.SelectVectorMerge(intrnNode.GetPrimType(), opnd1, opnd2, iNum);
491 }
492
HandleVectorGetHigh(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)493 Operand *HandleVectorGetHigh(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
494 {
495 PrimType rType = intrnNode.GetPrimType(); /* result operand */
496 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand */
497 return cgFunc.SelectVectorDup(rType, opnd1, false);
498 }
499
HandleVectorGetLow(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)500 Operand *HandleVectorGetLow(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
501 {
502 PrimType rType = intrnNode.GetPrimType(); /* result operand */
503 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand */
504 return cgFunc.SelectVectorDup(rType, opnd1, true);
505 }
506
HandleVectorGetElement(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)507 Operand *HandleVectorGetElement(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
508 {
509 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand */
510 PrimType o1Type = intrnNode.Opnd(0)->GetPrimType();
511 Operand *opndLane = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1));
512 int32 laneNum = -1;
513 if (opndLane->IsConstImmediate()) {
514 MIRConst *mirConst = static_cast<ConstvalNode *>(intrnNode.Opnd(1))->GetConstVal();
515 laneNum = static_cast<int32>(safe_cast<MIRIntConst>(mirConst)->GetExtValue());
516 } else {
517 CHECK_FATAL(0, "VectorGetElement does not have lane const");
518 }
519 return cgFunc.SelectVectorGetElement(intrnNode.GetPrimType(), opnd1, o1Type, laneNum);
520 }
521
HandleVectorPairwiseAdd(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)522 Operand *HandleVectorPairwiseAdd(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
523 {
524 Operand *src = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector src operand */
525 PrimType sType = intrnNode.Opnd(0)->GetPrimType();
526 return cgFunc.SelectVectorPairwiseAdd(intrnNode.GetPrimType(), src, sType);
527 }
528
HandleVectorPairwiseAdalp(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)529 Operand *HandleVectorPairwiseAdalp(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
530 {
531 BaseNode *arg1 = intrnNode.Opnd(0);
532 BaseNode *arg2 = intrnNode.Opnd(1);
533 Operand *src1 = cgFunc.HandleExpr(intrnNode, *arg1); /* vector src operand 1 */
534 Operand *src2 = cgFunc.HandleExpr(intrnNode, *arg2); /* vector src operand 2 */
535 return cgFunc.SelectVectorPairwiseAdalp(src1, arg1->GetPrimType(), src2, arg2->GetPrimType());
536 }
537
HandleVectorSetElement(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)538 Operand *HandleVectorSetElement(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
539 {
540 BaseNode *arg0 = intrnNode.Opnd(0); /* uint32_t operand */
541 Operand *opnd0 = cgFunc.HandleExpr(intrnNode, *arg0);
542 PrimType aType = arg0->GetPrimType();
543
544 BaseNode *arg1 = intrnNode.Opnd(1); /* vector operand == result */
545 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *arg1);
546 PrimType vType = arg1->GetPrimType();
547
548 BaseNode *arg2 = intrnNode.Opnd(2); /* lane const operand */
549 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *arg2);
550 int32 laneNum = -1;
551 if (opnd2->IsConstImmediate()) {
552 MIRConst *mirConst = static_cast<ConstvalNode *>(arg2)->GetConstVal();
553 laneNum = static_cast<int32>(safe_cast<MIRIntConst>(mirConst)->GetExtValue());
554 } else {
555 CHECK_FATAL(0, "VectorSetElement does not have lane const");
556 }
557 return cgFunc.SelectVectorSetElement(opnd0, aType, opnd1, vType, laneNum);
558 }
559
HandleVectorReverse(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,uint32 size)560 Operand *HandleVectorReverse(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, uint32 size)
561 {
562 BaseNode *argExpr = intrnNode.Opnd(0); /* src operand */
563 Operand *src = cgFunc.HandleExpr(intrnNode, *argExpr);
564 MIRType *type = intrnNode.GetIntrinDesc().GetReturnType();
565 DEBUG_ASSERT(type != nullptr, "null ptr check");
566 auto revVecType = type->GetPrimType();
567 return cgFunc.SelectVectorReverse(revVecType, src, revVecType, size);
568 }
569
HandleVectorShiftNarrow(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow)570 Operand *HandleVectorShiftNarrow(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow)
571 {
572 PrimType rType = intrnNode.GetPrimType(); /* vector result */
573 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand */
574 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* shift const */
575 if (!opnd2->IsConstImmediate()) {
576 CHECK_FATAL(0, "VectorShiftNarrow does not have shift const");
577 }
578 return cgFunc.SelectVectorShiftRNarrow(rType, opnd1, intrnNode.Opnd(0)->GetPrimType(), opnd2, isLow);
579 }
580
HandleVectorSubWiden(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow,bool isWide)581 Operand *HandleVectorSubWiden(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow, bool isWide)
582 {
583 PrimType resType = intrnNode.GetPrimType(); /* uint32_t result */
584 Operand *o1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0));
585 Operand *o2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1));
586 return cgFunc.SelectVectorSubWiden(resType, o1, intrnNode.Opnd(0)->GetPrimType(), o2,
587 intrnNode.Opnd(1)->GetPrimType(), isLow, isWide);
588 }
589
HandleVectorSum(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)590 Operand *HandleVectorSum(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
591 {
592 PrimType resType = intrnNode.GetPrimType(); /* uint32_t result */
593 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand */
594 return cgFunc.SelectVectorSum(resType, opnd1, intrnNode.Opnd(0)->GetPrimType());
595 }
596
HandleVectorTableLookup(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)597 Operand *HandleVectorTableLookup(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
598 {
599 PrimType rType = intrnNode.GetPrimType(); /* result operand */
600 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand 1 */
601 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector operand 2 */
602 return cgFunc.SelectVectorTableLookup(rType, opnd1, opnd2);
603 }
604
HandleVectorMadd(const IntrinsicopNode & intrnNode,CGFunc & cgFunc)605 Operand *HandleVectorMadd(const IntrinsicopNode &intrnNode, CGFunc &cgFunc)
606 {
607 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand 1 */
608 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector operand 2 */
609 Operand *opnd3 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(2)); /* vector operand 3 */
610 PrimType oTyp1 = intrnNode.Opnd(0)->GetPrimType();
611 PrimType oTyp2 = intrnNode.Opnd(1)->GetPrimType();
612 PrimType oTyp3 = intrnNode.Opnd(2)->GetPrimType();
613 return cgFunc.SelectVectorMadd(opnd1, oTyp1, opnd2, oTyp2, opnd3, oTyp3);
614 }
615
HandleVectorMull(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow)616 Operand *HandleVectorMull(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow)
617 {
618 PrimType rType = intrnNode.GetPrimType(); /* result operand */
619 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector operand 1 */
620 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector operand 2 */
621 PrimType oTyp1 = intrnNode.Opnd(0)->GetPrimType();
622 PrimType oTyp2 = intrnNode.Opnd(1)->GetPrimType();
623 return cgFunc.SelectVectorMull(rType, opnd1, oTyp1, opnd2, oTyp2, isLow);
624 }
625
HandleVectorNarrow(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow)626 Operand *HandleVectorNarrow(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow)
627 {
628 PrimType rType = intrnNode.GetPrimType(); /* result operand */
629 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector opnd 1 */
630 if (isLow) {
631 return cgFunc.SelectVectorNarrow(rType, opnd1, intrnNode.Opnd(0)->GetPrimType());
632 } else {
633 Operand *opnd2 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(1)); /* vector opnd 2 */
634 return cgFunc.SelectVectorNarrow2(rType, opnd1, intrnNode.Opnd(0)->GetPrimType(), opnd2,
635 intrnNode.Opnd(1)->GetPrimType());
636 }
637 }
638
HandleVectorWiden(const IntrinsicopNode & intrnNode,CGFunc & cgFunc,bool isLow)639 Operand *HandleVectorWiden(const IntrinsicopNode &intrnNode, CGFunc &cgFunc, bool isLow)
640 {
641 PrimType rType = intrnNode.GetPrimType(); /* result operand */
642 Operand *opnd1 = cgFunc.HandleExpr(intrnNode, *intrnNode.Opnd(0)); /* vector opnd 1 */
643 return cgFunc.SelectVectorWiden(rType, opnd1, intrnNode.Opnd(0)->GetPrimType(), isLow);
644 }
645
HandleIntrinOp(const BaseNode & parent,BaseNode & expr,CGFunc & cgFunc)646 Operand *HandleIntrinOp(const BaseNode &parent, BaseNode &expr, CGFunc &cgFunc)
647 {
648 auto &intrinsicopNode = static_cast<IntrinsicopNode &>(expr);
649 switch (intrinsicopNode.GetIntrinsic()) {
650 case INTRN_MPL_READ_OVTABLE_ENTRY_LAZY: {
651 Operand *srcOpnd = cgFunc.HandleExpr(intrinsicopNode, *intrinsicopNode.Opnd(0));
652 return cgFunc.SelectLazyLoad(*srcOpnd, intrinsicopNode.GetPrimType());
653 }
654 case INTRN_MPL_READ_STATIC_OFFSET_TAB: {
655 auto addrOfNode = static_cast<AddrofNode *>(intrinsicopNode.Opnd(0));
656 MIRSymbol *st = cgFunc.GetMirModule().CurFunction()->GetLocalOrGlobalSymbol(addrOfNode->GetStIdx());
657 auto constNode = static_cast<ConstvalNode *>(intrinsicopNode.Opnd(1));
658 CHECK_FATAL(constNode != nullptr, "null ptr check");
659 auto mirIntConst = static_cast<MIRIntConst *>(constNode->GetConstVal());
660 return cgFunc.SelectLazyLoadStatic(*st, mirIntConst->GetExtValue(), intrinsicopNode.GetPrimType());
661 }
662 case INTRN_MPL_READ_ARRAYCLASS_CACHE_ENTRY: {
663 auto addrOfNode = static_cast<AddrofNode *>(intrinsicopNode.Opnd(0));
664 MIRSymbol *st = cgFunc.GetMirModule().CurFunction()->GetLocalOrGlobalSymbol(addrOfNode->GetStIdx());
665 auto constNode = static_cast<ConstvalNode *>(intrinsicopNode.Opnd(1));
666 CHECK_FATAL(constNode != nullptr, "null ptr check");
667 auto mirIntConst = static_cast<MIRIntConst *>(constNode->GetConstVal());
668 return cgFunc.SelectLoadArrayClassCache(*st, mirIntConst->GetExtValue(), intrinsicopNode.GetPrimType());
669 }
670 // double
671 case INTRN_C_sin:
672 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "sin");
673 case INTRN_C_sinh:
674 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "sinh");
675 case INTRN_C_asin:
676 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "asin");
677 case INTRN_C_cos:
678 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "cos");
679 case INTRN_C_cosh:
680 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "cosh");
681 case INTRN_C_acos:
682 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "acos");
683 case INTRN_C_atan:
684 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "atan");
685 case INTRN_C_exp:
686 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "exp");
687 case INTRN_C_log:
688 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "log");
689 case INTRN_C_log10:
690 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "log10");
691 // float
692 case INTRN_C_sinf:
693 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "sinf");
694 case INTRN_C_sinhf:
695 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "sinhf");
696 case INTRN_C_asinf:
697 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "asinf");
698 case INTRN_C_cosf:
699 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "cosf");
700 case INTRN_C_coshf:
701 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "coshf");
702 case INTRN_C_acosf:
703 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "acosf");
704 case INTRN_C_atanf:
705 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "atanf");
706 case INTRN_C_expf:
707 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "expf");
708 case INTRN_C_logf:
709 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "logf");
710 case INTRN_C_log10f:
711 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "log10f");
712 // int
713 case INTRN_C_ffs:
714 return cgFunc.SelectIntrinsicOpWithOneParam(intrinsicopNode, "ffs");
715 // libc mem* and str* functions as intrinsicops
716 case INTRN_C_memcmp:
717 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "memcmp");
718 case INTRN_C_strlen:
719 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_u64, "strlen");
720 case INTRN_C_strcmp:
721 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "strcmp");
722 case INTRN_C_strncmp:
723 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_i32, "strncmp");
724 case INTRN_C_strchr:
725 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "strchr");
726 case INTRN_C_strrchr:
727 return cgFunc.SelectIntrinsicOpWithNParams(intrinsicopNode, PTY_a64, "strrchr");
728
729 case INTRN_C_rev16_2:
730 case INTRN_C_rev_4:
731 case INTRN_C_rev_8:
732 return cgFunc.SelectBswap(intrinsicopNode, *cgFunc.HandleExpr(expr, *expr.Opnd(0)), parent);
733
734 case INTRN_C_clz32:
735 case INTRN_C_clz64:
736 return cgFunc.SelectCclz(intrinsicopNode);
737 case INTRN_C_ctz32:
738 case INTRN_C_ctz64:
739 return cgFunc.SelectCctz(intrinsicopNode);
740 case INTRN_C_popcount32:
741 case INTRN_C_popcount64:
742 return cgFunc.SelectCpopcount(intrinsicopNode);
743 case INTRN_C_parity32:
744 case INTRN_C_parity64:
745 return cgFunc.SelectCparity(intrinsicopNode);
746 case INTRN_C_clrsb32:
747 case INTRN_C_clrsb64:
748 return cgFunc.SelectCclrsb(intrinsicopNode);
749 case INTRN_C_isaligned:
750 return cgFunc.SelectCisaligned(intrinsicopNode);
751 case INTRN_C_alignup:
752 return cgFunc.SelectCalignup(intrinsicopNode);
753 case INTRN_C_aligndown:
754 return cgFunc.SelectCaligndown(intrinsicopNode);
755 case INTRN_C___sync_add_and_fetch_1:
756 case INTRN_C___sync_add_and_fetch_2:
757 case INTRN_C___sync_add_and_fetch_4:
758 case INTRN_C___sync_add_and_fetch_8:
759 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_add, false);
760 case INTRN_C___sync_sub_and_fetch_1:
761 case INTRN_C___sync_sub_and_fetch_2:
762 case INTRN_C___sync_sub_and_fetch_4:
763 case INTRN_C___sync_sub_and_fetch_8:
764 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_sub, false);
765 case INTRN_C___sync_fetch_and_add_1:
766 case INTRN_C___sync_fetch_and_add_2:
767 case INTRN_C___sync_fetch_and_add_4:
768 case INTRN_C___sync_fetch_and_add_8:
769 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_add, true);
770 case INTRN_C___sync_fetch_and_sub_1:
771 case INTRN_C___sync_fetch_and_sub_2:
772 case INTRN_C___sync_fetch_and_sub_4:
773 case INTRN_C___sync_fetch_and_sub_8:
774 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_sub, true);
775 case INTRN_C___sync_bool_compare_and_swap_1:
776 case INTRN_C___sync_bool_compare_and_swap_2:
777 case INTRN_C___sync_bool_compare_and_swap_4:
778 case INTRN_C___sync_bool_compare_and_swap_8:
779 return cgFunc.SelectCSyncBoolCmpSwap(intrinsicopNode);
780 case INTRN_C___sync_val_compare_and_swap_1:
781 case INTRN_C___sync_val_compare_and_swap_2:
782 case INTRN_C___sync_val_compare_and_swap_4:
783 case INTRN_C___sync_val_compare_and_swap_8:
784 return cgFunc.SelectCSyncValCmpSwap(intrinsicopNode);
785 case INTRN_C___sync_lock_test_and_set_1:
786 return cgFunc.SelectCSyncLockTestSet(intrinsicopNode, PTY_i8);
787 case INTRN_C___sync_lock_test_and_set_2:
788 return cgFunc.SelectCSyncLockTestSet(intrinsicopNode, PTY_i16);
789 case INTRN_C___sync_lock_test_and_set_4:
790 return cgFunc.SelectCSyncLockTestSet(intrinsicopNode, PTY_i32);
791 case INTRN_C___sync_lock_test_and_set_8:
792 return cgFunc.SelectCSyncLockTestSet(intrinsicopNode, PTY_i64);
793 case INTRN_C___sync_fetch_and_and_1:
794 case INTRN_C___sync_fetch_and_and_2:
795 case INTRN_C___sync_fetch_and_and_4:
796 case INTRN_C___sync_fetch_and_and_8:
797 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_band, true);
798 case INTRN_C___sync_and_and_fetch_1:
799 case INTRN_C___sync_and_and_fetch_2:
800 case INTRN_C___sync_and_and_fetch_4:
801 case INTRN_C___sync_and_and_fetch_8:
802 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_band, false);
803 case INTRN_C___sync_fetch_and_or_1:
804 case INTRN_C___sync_fetch_and_or_2:
805 case INTRN_C___sync_fetch_and_or_4:
806 case INTRN_C___sync_fetch_and_or_8:
807 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_bior, true);
808 case INTRN_C___sync_or_and_fetch_1:
809 case INTRN_C___sync_or_and_fetch_2:
810 case INTRN_C___sync_or_and_fetch_4:
811 case INTRN_C___sync_or_and_fetch_8:
812 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_bior, false);
813 case INTRN_C___sync_fetch_and_xor_1:
814 case INTRN_C___sync_fetch_and_xor_2:
815 case INTRN_C___sync_fetch_and_xor_4:
816 case INTRN_C___sync_fetch_and_xor_8:
817 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_bxor, true);
818 case INTRN_C___sync_xor_and_fetch_1:
819 case INTRN_C___sync_xor_and_fetch_2:
820 case INTRN_C___sync_xor_and_fetch_4:
821 case INTRN_C___sync_xor_and_fetch_8:
822 return cgFunc.SelectCSyncFetch(intrinsicopNode, OP_bxor, false);
823 case INTRN_C___sync_synchronize:
824 return cgFunc.SelectCSyncSynchronize(intrinsicopNode);
825 case INTRN_C___atomic_load_n:
826 return cgFunc.SelectCAtomicLoadN(intrinsicopNode);
827 case INTRN_C___atomic_exchange_n:
828 return cgFunc.SelectCAtomicExchangeN(intrinsicopNode);
829 case INTRN_C__builtin_return_address:
830 case INTRN_C__builtin_extract_return_addr:
831 return cgFunc.SelectCReturnAddress(intrinsicopNode);
832
833 case INTRN_vector_abs_v8i8:
834 case INTRN_vector_abs_v4i16:
835 case INTRN_vector_abs_v2i32:
836 case INTRN_vector_abs_v1i64:
837 case INTRN_vector_abs_v16i8:
838 case INTRN_vector_abs_v8i16:
839 case INTRN_vector_abs_v4i32:
840 case INTRN_vector_abs_v2i64:
841 return HandleAbs(parent, intrinsicopNode, cgFunc);
842
843 case INTRN_vector_addl_low_v8i8:
844 case INTRN_vector_addl_low_v8u8:
845 case INTRN_vector_addl_low_v4i16:
846 case INTRN_vector_addl_low_v4u16:
847 case INTRN_vector_addl_low_v2i32:
848 case INTRN_vector_addl_low_v2u32:
849 return HandleVectorAddLong(intrinsicopNode, cgFunc, true);
850
851 case INTRN_vector_addl_high_v8i8:
852 case INTRN_vector_addl_high_v8u8:
853 case INTRN_vector_addl_high_v4i16:
854 case INTRN_vector_addl_high_v4u16:
855 case INTRN_vector_addl_high_v2i32:
856 case INTRN_vector_addl_high_v2u32:
857 return HandleVectorAddLong(intrinsicopNode, cgFunc, false);
858
859 case INTRN_vector_addw_low_v8i8:
860 case INTRN_vector_addw_low_v8u8:
861 case INTRN_vector_addw_low_v4i16:
862 case INTRN_vector_addw_low_v4u16:
863 case INTRN_vector_addw_low_v2i32:
864 case INTRN_vector_addw_low_v2u32:
865 return HandleVectorAddWiden(intrinsicopNode, cgFunc, true);
866
867 case INTRN_vector_addw_high_v8i8:
868 case INTRN_vector_addw_high_v8u8:
869 case INTRN_vector_addw_high_v4i16:
870 case INTRN_vector_addw_high_v4u16:
871 case INTRN_vector_addw_high_v2i32:
872 case INTRN_vector_addw_high_v2u32:
873 return HandleVectorAddWiden(intrinsicopNode, cgFunc, false);
874
875 case INTRN_vector_sum_v8u8:
876 case INTRN_vector_sum_v8i8:
877 case INTRN_vector_sum_v4u16:
878 case INTRN_vector_sum_v4i16:
879 case INTRN_vector_sum_v2u32:
880 case INTRN_vector_sum_v2i32:
881 case INTRN_vector_sum_v16u8:
882 case INTRN_vector_sum_v16i8:
883 case INTRN_vector_sum_v8u16:
884 case INTRN_vector_sum_v8i16:
885 case INTRN_vector_sum_v4u32:
886 case INTRN_vector_sum_v4i32:
887 case INTRN_vector_sum_v2u64:
888 case INTRN_vector_sum_v2i64:
889 return HandleVectorSum(intrinsicopNode, cgFunc);
890
891 case INTRN_vector_from_scalar_v8u8:
892 case INTRN_vector_from_scalar_v8i8:
893 case INTRN_vector_from_scalar_v4u16:
894 case INTRN_vector_from_scalar_v4i16:
895 case INTRN_vector_from_scalar_v2u32:
896 case INTRN_vector_from_scalar_v2i32:
897 case INTRN_vector_from_scalar_v1u64:
898 case INTRN_vector_from_scalar_v1i64:
899 case INTRN_vector_from_scalar_v16u8:
900 case INTRN_vector_from_scalar_v16i8:
901 case INTRN_vector_from_scalar_v8u16:
902 case INTRN_vector_from_scalar_v8i16:
903 case INTRN_vector_from_scalar_v4u32:
904 case INTRN_vector_from_scalar_v4i32:
905 case INTRN_vector_from_scalar_v2u64:
906 case INTRN_vector_from_scalar_v2i64:
907 return HandleVectorFromScalar(intrinsicopNode, cgFunc);
908
909 case INTRN_vector_labssub_low_v8u8:
910 case INTRN_vector_labssub_low_v8i8:
911 case INTRN_vector_labssub_low_v4u16:
912 case INTRN_vector_labssub_low_v4i16:
913 case INTRN_vector_labssub_low_v2u32:
914 case INTRN_vector_labssub_low_v2i32:
915 return HandleVectorAbsSubL(intrinsicopNode, cgFunc, true);
916
917 case INTRN_vector_labssub_high_v8u8:
918 case INTRN_vector_labssub_high_v8i8:
919 case INTRN_vector_labssub_high_v4u16:
920 case INTRN_vector_labssub_high_v4i16:
921 case INTRN_vector_labssub_high_v2u32:
922 case INTRN_vector_labssub_high_v2i32:
923 return HandleVectorAbsSubL(intrinsicopNode, cgFunc, false);
924
925 case INTRN_vector_merge_v8u8:
926 case INTRN_vector_merge_v8i8:
927 case INTRN_vector_merge_v4u16:
928 case INTRN_vector_merge_v4i16:
929 case INTRN_vector_merge_v2u32:
930 case INTRN_vector_merge_v2i32:
931 case INTRN_vector_merge_v1u64:
932 case INTRN_vector_merge_v1i64:
933 case INTRN_vector_merge_v16u8:
934 case INTRN_vector_merge_v16i8:
935 case INTRN_vector_merge_v8u16:
936 case INTRN_vector_merge_v8i16:
937 case INTRN_vector_merge_v4u32:
938 case INTRN_vector_merge_v4i32:
939 case INTRN_vector_merge_v2u64:
940 case INTRN_vector_merge_v2i64:
941 return HandleVectorMerge(intrinsicopNode, cgFunc);
942
943 case INTRN_vector_set_element_v8u8:
944 case INTRN_vector_set_element_v8i8:
945 case INTRN_vector_set_element_v4u16:
946 case INTRN_vector_set_element_v4i16:
947 case INTRN_vector_set_element_v2u32:
948 case INTRN_vector_set_element_v2i32:
949 case INTRN_vector_set_element_v1u64:
950 case INTRN_vector_set_element_v1i64:
951 case INTRN_vector_set_element_v16u8:
952 case INTRN_vector_set_element_v16i8:
953 case INTRN_vector_set_element_v8u16:
954 case INTRN_vector_set_element_v8i16:
955 case INTRN_vector_set_element_v4u32:
956 case INTRN_vector_set_element_v4i32:
957 case INTRN_vector_set_element_v2u64:
958 case INTRN_vector_set_element_v2i64:
959 return HandleVectorSetElement(intrinsicopNode, cgFunc);
960
961 case INTRN_vector_get_high_v16u8:
962 case INTRN_vector_get_high_v16i8:
963 case INTRN_vector_get_high_v8u16:
964 case INTRN_vector_get_high_v8i16:
965 case INTRN_vector_get_high_v4u32:
966 case INTRN_vector_get_high_v4i32:
967 case INTRN_vector_get_high_v2u64:
968 case INTRN_vector_get_high_v2i64:
969 return HandleVectorGetHigh(intrinsicopNode, cgFunc);
970
971 case INTRN_vector_get_low_v16u8:
972 case INTRN_vector_get_low_v16i8:
973 case INTRN_vector_get_low_v8u16:
974 case INTRN_vector_get_low_v8i16:
975 case INTRN_vector_get_low_v4u32:
976 case INTRN_vector_get_low_v4i32:
977 case INTRN_vector_get_low_v2u64:
978 case INTRN_vector_get_low_v2i64:
979 return HandleVectorGetLow(intrinsicopNode, cgFunc);
980
981 case INTRN_vector_get_element_v8u8:
982 case INTRN_vector_get_element_v8i8:
983 case INTRN_vector_get_element_v4u16:
984 case INTRN_vector_get_element_v4i16:
985 case INTRN_vector_get_element_v2u32:
986 case INTRN_vector_get_element_v2i32:
987 case INTRN_vector_get_element_v1u64:
988 case INTRN_vector_get_element_v1i64:
989 case INTRN_vector_get_element_v16u8:
990 case INTRN_vector_get_element_v16i8:
991 case INTRN_vector_get_element_v8u16:
992 case INTRN_vector_get_element_v8i16:
993 case INTRN_vector_get_element_v4u32:
994 case INTRN_vector_get_element_v4i32:
995 case INTRN_vector_get_element_v2u64:
996 case INTRN_vector_get_element_v2i64:
997 return HandleVectorGetElement(intrinsicopNode, cgFunc);
998
999 case INTRN_vector_pairwise_adalp_v8i8:
1000 case INTRN_vector_pairwise_adalp_v4i16:
1001 case INTRN_vector_pairwise_adalp_v2i32:
1002 case INTRN_vector_pairwise_adalp_v8u8:
1003 case INTRN_vector_pairwise_adalp_v4u16:
1004 case INTRN_vector_pairwise_adalp_v2u32:
1005 case INTRN_vector_pairwise_adalp_v16i8:
1006 case INTRN_vector_pairwise_adalp_v8i16:
1007 case INTRN_vector_pairwise_adalp_v4i32:
1008 case INTRN_vector_pairwise_adalp_v16u8:
1009 case INTRN_vector_pairwise_adalp_v8u16:
1010 case INTRN_vector_pairwise_adalp_v4u32:
1011 return HandleVectorPairwiseAdalp(intrinsicopNode, cgFunc);
1012
1013 case INTRN_vector_pairwise_add_v8u8:
1014 case INTRN_vector_pairwise_add_v8i8:
1015 case INTRN_vector_pairwise_add_v4u16:
1016 case INTRN_vector_pairwise_add_v4i16:
1017 case INTRN_vector_pairwise_add_v2u32:
1018 case INTRN_vector_pairwise_add_v2i32:
1019 case INTRN_vector_pairwise_add_v16u8:
1020 case INTRN_vector_pairwise_add_v16i8:
1021 case INTRN_vector_pairwise_add_v8u16:
1022 case INTRN_vector_pairwise_add_v8i16:
1023 case INTRN_vector_pairwise_add_v4u32:
1024 case INTRN_vector_pairwise_add_v4i32:
1025 return HandleVectorPairwiseAdd(intrinsicopNode, cgFunc);
1026
1027 case INTRN_vector_madd_v8u8:
1028 case INTRN_vector_madd_v8i8:
1029 case INTRN_vector_madd_v4u16:
1030 case INTRN_vector_madd_v4i16:
1031 case INTRN_vector_madd_v2u32:
1032 case INTRN_vector_madd_v2i32:
1033 return HandleVectorMadd(intrinsicopNode, cgFunc);
1034
1035 case INTRN_vector_mull_low_v8u8:
1036 case INTRN_vector_mull_low_v8i8:
1037 case INTRN_vector_mull_low_v4u16:
1038 case INTRN_vector_mull_low_v4i16:
1039 case INTRN_vector_mull_low_v2u32:
1040 case INTRN_vector_mull_low_v2i32:
1041 return HandleVectorMull(intrinsicopNode, cgFunc, true);
1042
1043 case INTRN_vector_mull_high_v8u8:
1044 case INTRN_vector_mull_high_v8i8:
1045 case INTRN_vector_mull_high_v4u16:
1046 case INTRN_vector_mull_high_v4i16:
1047 case INTRN_vector_mull_high_v2u32:
1048 case INTRN_vector_mull_high_v2i32:
1049 return HandleVectorMull(intrinsicopNode, cgFunc, false);
1050
1051 case INTRN_vector_narrow_low_v8u16:
1052 case INTRN_vector_narrow_low_v8i16:
1053 case INTRN_vector_narrow_low_v4u32:
1054 case INTRN_vector_narrow_low_v4i32:
1055 case INTRN_vector_narrow_low_v2u64:
1056 case INTRN_vector_narrow_low_v2i64:
1057 return HandleVectorNarrow(intrinsicopNode, cgFunc, true);
1058
1059 case INTRN_vector_narrow_high_v8u16:
1060 case INTRN_vector_narrow_high_v8i16:
1061 case INTRN_vector_narrow_high_v4u32:
1062 case INTRN_vector_narrow_high_v4i32:
1063 case INTRN_vector_narrow_high_v2u64:
1064 case INTRN_vector_narrow_high_v2i64:
1065 return HandleVectorNarrow(intrinsicopNode, cgFunc, false);
1066
1067 case INTRN_vector_reverse_v8u8:
1068 case INTRN_vector_reverse_v8i8:
1069 case INTRN_vector_reverse_v4u16:
1070 case INTRN_vector_reverse_v4i16:
1071 case INTRN_vector_reverse_v16u8:
1072 case INTRN_vector_reverse_v16i8:
1073 case INTRN_vector_reverse_v8u16:
1074 case INTRN_vector_reverse_v8i16:
1075 return HandleVectorReverse(intrinsicopNode, cgFunc, k32BitSize);
1076
1077 case INTRN_vector_reverse16_v16u8:
1078 case INTRN_vector_reverse16_v16i8:
1079 case INTRN_vector_reverse16_v8u8:
1080 case INTRN_vector_reverse16_v8i8:
1081 return HandleVectorReverse(intrinsicopNode, cgFunc, k16BitSize);
1082
1083 case INTRN_vector_reverse64_v16u8:
1084 case INTRN_vector_reverse64_v16i8:
1085 case INTRN_vector_reverse64_v8u8:
1086 case INTRN_vector_reverse64_v8i8:
1087 case INTRN_vector_reverse64_v8u16:
1088 case INTRN_vector_reverse64_v8i16:
1089 case INTRN_vector_reverse64_v4u16:
1090 case INTRN_vector_reverse64_v4i16:
1091 case INTRN_vector_reverse64_v4u32:
1092 case INTRN_vector_reverse64_v4i32:
1093 case INTRN_vector_reverse64_v2u32:
1094 case INTRN_vector_reverse64_v2i32:
1095 return HandleVectorReverse(intrinsicopNode, cgFunc, k64BitSize);
1096
1097 case INTRN_vector_shr_narrow_low_v8u16:
1098 case INTRN_vector_shr_narrow_low_v8i16:
1099 case INTRN_vector_shr_narrow_low_v4u32:
1100 case INTRN_vector_shr_narrow_low_v4i32:
1101 case INTRN_vector_shr_narrow_low_v2u64:
1102 case INTRN_vector_shr_narrow_low_v2i64:
1103 return HandleVectorShiftNarrow(intrinsicopNode, cgFunc, true);
1104
1105 case INTRN_vector_subl_low_v8i8:
1106 case INTRN_vector_subl_low_v8u8:
1107 case INTRN_vector_subl_low_v4i16:
1108 case INTRN_vector_subl_low_v4u16:
1109 case INTRN_vector_subl_low_v2i32:
1110 case INTRN_vector_subl_low_v2u32:
1111 return HandleVectorSubWiden(intrinsicopNode, cgFunc, true, false);
1112
1113 case INTRN_vector_subl_high_v8i8:
1114 case INTRN_vector_subl_high_v8u8:
1115 case INTRN_vector_subl_high_v4i16:
1116 case INTRN_vector_subl_high_v4u16:
1117 case INTRN_vector_subl_high_v2i32:
1118 case INTRN_vector_subl_high_v2u32:
1119 return HandleVectorSubWiden(intrinsicopNode, cgFunc, false, false);
1120
1121 case INTRN_vector_subw_low_v8i8:
1122 case INTRN_vector_subw_low_v8u8:
1123 case INTRN_vector_subw_low_v4i16:
1124 case INTRN_vector_subw_low_v4u16:
1125 case INTRN_vector_subw_low_v2i32:
1126 case INTRN_vector_subw_low_v2u32:
1127 return HandleVectorSubWiden(intrinsicopNode, cgFunc, true, true);
1128
1129 case INTRN_vector_subw_high_v8i8:
1130 case INTRN_vector_subw_high_v8u8:
1131 case INTRN_vector_subw_high_v4i16:
1132 case INTRN_vector_subw_high_v4u16:
1133 case INTRN_vector_subw_high_v2i32:
1134 case INTRN_vector_subw_high_v2u32:
1135 return HandleVectorSubWiden(intrinsicopNode, cgFunc, false, true);
1136
1137 case INTRN_vector_table_lookup_v8u8:
1138 case INTRN_vector_table_lookup_v8i8:
1139 case INTRN_vector_table_lookup_v16u8:
1140 case INTRN_vector_table_lookup_v16i8:
1141 return HandleVectorTableLookup(intrinsicopNode, cgFunc);
1142
1143 case INTRN_vector_widen_low_v8u8:
1144 case INTRN_vector_widen_low_v8i8:
1145 case INTRN_vector_widen_low_v4u16:
1146 case INTRN_vector_widen_low_v4i16:
1147 case INTRN_vector_widen_low_v2u32:
1148 case INTRN_vector_widen_low_v2i32:
1149 return HandleVectorWiden(intrinsicopNode, cgFunc, true);
1150
1151 case INTRN_vector_widen_high_v8u8:
1152 case INTRN_vector_widen_high_v8i8:
1153 case INTRN_vector_widen_high_v4u16:
1154 case INTRN_vector_widen_high_v4i16:
1155 case INTRN_vector_widen_high_v2u32:
1156 case INTRN_vector_widen_high_v2i32:
1157 return HandleVectorWiden(intrinsicopNode, cgFunc, false);
1158
1159 default:
1160 DEBUG_ASSERT(false, "Should not reach here.");
1161 return nullptr;
1162 }
1163 }
1164
1165 using HandleExprFactory = FunctionFactory<Opcode, maplebe::Operand *, const BaseNode &, BaseNode &, CGFunc &>;
InitHandleExprFactory()1166 void InitHandleExprFactory()
1167 {
1168 RegisterFactoryFunction<HandleExprFactory>(OP_dread, HandleDread);
1169 RegisterFactoryFunction<HandleExprFactory>(OP_regread, HandleRegread);
1170 RegisterFactoryFunction<HandleExprFactory>(OP_constval, HandleConstVal);
1171 RegisterFactoryFunction<HandleExprFactory>(OP_conststr, HandleConstStr);
1172 RegisterFactoryFunction<HandleExprFactory>(OP_conststr16, HandleConstStr16);
1173 RegisterFactoryFunction<HandleExprFactory>(OP_add, HandleAdd);
1174 RegisterFactoryFunction<HandleExprFactory>(OP_CG_array_elem_add, HandleCGArrayElemAdd);
1175 RegisterFactoryFunction<HandleExprFactory>(OP_ashr, HandleShift);
1176 RegisterFactoryFunction<HandleExprFactory>(OP_lshr, HandleShift);
1177 RegisterFactoryFunction<HandleExprFactory>(OP_shl, HandleShift);
1178 RegisterFactoryFunction<HandleExprFactory>(OP_ror, HandleRor);
1179 RegisterFactoryFunction<HandleExprFactory>(OP_mul, HandleMpy);
1180 RegisterFactoryFunction<HandleExprFactory>(OP_div, HandleDiv);
1181 RegisterFactoryFunction<HandleExprFactory>(OP_rem, HandleRem);
1182 RegisterFactoryFunction<HandleExprFactory>(OP_addrof, HandleAddrof);
1183 RegisterFactoryFunction<HandleExprFactory>(OP_addrofoff, HandleAddrofoff);
1184 RegisterFactoryFunction<HandleExprFactory>(OP_addroffunc, HandleAddroffunc);
1185 RegisterFactoryFunction<HandleExprFactory>(OP_addroflabel, HandleAddrofLabel);
1186 RegisterFactoryFunction<HandleExprFactory>(OP_iread, HandleIread);
1187 RegisterFactoryFunction<HandleExprFactory>(OP_ireadoff, HandleIreadoff);
1188 RegisterFactoryFunction<HandleExprFactory>(OP_ireadfpoff, HandleIreadfpoff);
1189 RegisterFactoryFunction<HandleExprFactory>(OP_sub, HandleSub);
1190 RegisterFactoryFunction<HandleExprFactory>(OP_band, HandleBand);
1191 RegisterFactoryFunction<HandleExprFactory>(OP_bior, HandleBior);
1192 RegisterFactoryFunction<HandleExprFactory>(OP_bxor, HandleBxor);
1193 RegisterFactoryFunction<HandleExprFactory>(OP_abs, HandleAbs);
1194 RegisterFactoryFunction<HandleExprFactory>(OP_bnot, HandleBnot);
1195 RegisterFactoryFunction<HandleExprFactory>(OP_sext, HandleExtractBits);
1196 RegisterFactoryFunction<HandleExprFactory>(OP_zext, HandleExtractBits);
1197 RegisterFactoryFunction<HandleExprFactory>(OP_extractbits, HandleExtractBits);
1198 RegisterFactoryFunction<HandleExprFactory>(OP_depositbits, HandleDepositBits);
1199 RegisterFactoryFunction<HandleExprFactory>(OP_lnot, HandleLnot);
1200 RegisterFactoryFunction<HandleExprFactory>(OP_land, HandleLand);
1201 RegisterFactoryFunction<HandleExprFactory>(OP_lior, HandleLor);
1202 RegisterFactoryFunction<HandleExprFactory>(OP_min, HandleMin);
1203 RegisterFactoryFunction<HandleExprFactory>(OP_max, HandleMax);
1204 RegisterFactoryFunction<HandleExprFactory>(OP_neg, HandleNeg);
1205 RegisterFactoryFunction<HandleExprFactory>(OP_recip, HandleRecip);
1206 RegisterFactoryFunction<HandleExprFactory>(OP_sqrt, HandleSqrt);
1207 RegisterFactoryFunction<HandleExprFactory>(OP_ceil, HandleCeil);
1208 RegisterFactoryFunction<HandleExprFactory>(OP_floor, HandleFloor);
1209 RegisterFactoryFunction<HandleExprFactory>(OP_retype, HandleRetype);
1210 RegisterFactoryFunction<HandleExprFactory>(OP_cvt, HandleCvt);
1211 RegisterFactoryFunction<HandleExprFactory>(OP_round, HandleRound);
1212 RegisterFactoryFunction<HandleExprFactory>(OP_trunc, HandleTrunc);
1213 RegisterFactoryFunction<HandleExprFactory>(OP_select, HandleSelect);
1214 RegisterFactoryFunction<HandleExprFactory>(OP_le, HandleCmp);
1215 RegisterFactoryFunction<HandleExprFactory>(OP_ge, HandleCmp);
1216 RegisterFactoryFunction<HandleExprFactory>(OP_gt, HandleCmp);
1217 RegisterFactoryFunction<HandleExprFactory>(OP_lt, HandleCmp);
1218 RegisterFactoryFunction<HandleExprFactory>(OP_ne, HandleCmp);
1219 RegisterFactoryFunction<HandleExprFactory>(OP_eq, HandleCmp);
1220 RegisterFactoryFunction<HandleExprFactory>(OP_cmp, HandleCmp);
1221 RegisterFactoryFunction<HandleExprFactory>(OP_cmpl, HandleCmp);
1222 RegisterFactoryFunction<HandleExprFactory>(OP_cmpg, HandleCmp);
1223 RegisterFactoryFunction<HandleExprFactory>(OP_alloca, HandleAlloca);
1224 RegisterFactoryFunction<HandleExprFactory>(OP_malloc, HandleMalloc);
1225 RegisterFactoryFunction<HandleExprFactory>(OP_gcmalloc, HandleGCMalloc);
1226 RegisterFactoryFunction<HandleExprFactory>(OP_gcpermalloc, HandleGCMalloc);
1227 RegisterFactoryFunction<HandleExprFactory>(OP_gcmallocjarray, HandleJarrayMalloc);
1228 RegisterFactoryFunction<HandleExprFactory>(OP_gcpermallocjarray, HandleJarrayMalloc);
1229 RegisterFactoryFunction<HandleExprFactory>(OP_intrinsicop, HandleIntrinOp);
1230 }
1231
HandleLabel(StmtNode & stmt,CGFunc & cgFunc)1232 void HandleLabel(StmtNode &stmt, CGFunc &cgFunc)
1233 {
1234 DEBUG_ASSERT(stmt.GetOpCode() == OP_label, "error");
1235 auto &label = static_cast<LabelNode &>(stmt);
1236 BB *newBB = cgFunc.StartNewBBImpl(false, label);
1237 newBB->AddLabel(label.GetLabelIdx());
1238 if (newBB->GetId() == 1) {
1239 newBB->SetFrequency(kFreqBase);
1240 }
1241 cgFunc.SetLab2BBMap(newBB->GetLabIdx(), *newBB);
1242 cgFunc.SetCurBB(*newBB);
1243 }
1244
HandleGoto(StmtNode & stmt,CGFunc & cgFunc)1245 void HandleGoto(StmtNode &stmt, CGFunc &cgFunc)
1246 {
1247 cgFunc.UpdateFrequency(stmt);
1248 auto &gotoNode = static_cast<GotoNode &>(stmt);
1249 cgFunc.SetCurBBKind(BB::kBBGoto);
1250 cgFunc.SelectGoto(gotoNode);
1251 cgFunc.SetCurBB(*cgFunc.StartNewBB(gotoNode));
1252 DEBUG_ASSERT(&stmt == &gotoNode, "stmt must be same as gotoNoe");
1253
1254 if ((gotoNode.GetNext() != nullptr) && (gotoNode.GetNext()->GetOpCode() != OP_label)) {
1255 DEBUG_ASSERT(cgFunc.GetCurBB()->GetPrev()->GetLastStmt() == &stmt, "check the relation between BB and stmt");
1256 }
1257 }
1258
HandleIgoto(StmtNode & stmt,CGFunc & cgFunc)1259 void HandleIgoto(StmtNode &stmt, CGFunc &cgFunc)
1260 {
1261 auto &igotoNode = static_cast<UnaryStmtNode &>(stmt);
1262 Operand *targetOpnd = cgFunc.HandleExpr(stmt, *igotoNode.Opnd(0));
1263 cgFunc.SelectIgoto(targetOpnd);
1264 cgFunc.SetCurBB(*cgFunc.StartNewBB(igotoNode));
1265 }
1266
HandleCondbr(StmtNode & stmt,CGFunc & cgFunc)1267 void HandleCondbr(StmtNode &stmt, CGFunc &cgFunc)
1268 {
1269 cgFunc.UpdateFrequency(stmt);
1270 auto &condGotoNode = static_cast<CondGotoNode &>(stmt);
1271 BaseNode *condNode = condGotoNode.Opnd(0);
1272 DEBUG_ASSERT(condNode != nullptr, "expect first operand of cond br");
1273 Opcode condOp = condGotoNode.GetOpCode();
1274 if (condNode->GetOpCode() == OP_constval) {
1275 auto *constValNode = static_cast<ConstvalNode *>(condNode);
1276 if ((constValNode->GetConstVal()->IsZero() && (OP_brfalse == condOp)) ||
1277 (!constValNode->GetConstVal()->IsZero() && (OP_brtrue == condOp))) {
1278 auto *gotoStmt = cgFunc.GetMemoryPool()->New<GotoNode>(OP_goto);
1279 gotoStmt->SetOffset(condGotoNode.GetOffset());
1280 HandleGoto(*gotoStmt, cgFunc);
1281 auto *labelStmt = cgFunc.GetMemoryPool()->New<LabelNode>();
1282 labelStmt->SetLabelIdx(cgFunc.CreateLabel());
1283 HandleLabel(*labelStmt, cgFunc);
1284 }
1285 return;
1286 }
1287 cgFunc.SetCurBBKind(BB::kBBIf);
1288 /* if condNode is not a cmp node, cmp it with zero. */
1289 if (!kOpcodeInfo.IsCompare(condNode->GetOpCode())) {
1290 Operand *opnd0 = cgFunc.HandleExpr(condGotoNode, *condNode);
1291 PrimType primType = condNode->GetPrimType();
1292 Operand *zeroOpnd = nullptr;
1293 if (IsPrimitiveInteger(primType)) {
1294 zeroOpnd = &cgFunc.CreateImmOperand(primType, 0);
1295 } else {
1296 DEBUG_ASSERT(((PTY_f32 == primType) || (PTY_f64 == primType)),
1297 "we don't support half-precision FP operands yet");
1298 zeroOpnd = &cgFunc.CreateImmOperand(primType, 0);
1299 }
1300 cgFunc.SelectCondGoto(condGotoNode, *opnd0, *zeroOpnd);
1301 cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
1302 return;
1303 }
1304 /*
1305 * Special case:
1306 * bgt (cmp (op0, op1), 0) ==>
1307 * bgt (op0, op1)
1308 * but skip the case cmp(op0, 0)
1309 */
1310 BaseNode *op0 = condNode->Opnd(0);
1311 DEBUG_ASSERT(op0 != nullptr, "get first opnd of a condNode failed");
1312 BaseNode *op1 = condNode->Opnd(1);
1313 DEBUG_ASSERT(op1 != nullptr, "get second opnd of a condNode failed");
1314 if ((op0->GetOpCode() == OP_cmp) && (op1->GetOpCode() == OP_constval)) {
1315 auto *constValNode = static_cast<ConstvalNode *>(op1);
1316 MIRConst *mirConst = constValNode->GetConstVal();
1317 auto *cmpNode = static_cast<CompareNode *>(op0);
1318 bool skip = false;
1319 if (cmpNode->Opnd(1)->GetOpCode() == OP_constval) {
1320 auto *constVal = static_cast<ConstvalNode *>(cmpNode->Opnd(1))->GetConstVal();
1321 if (constVal->IsZero()) {
1322 skip = true;
1323 }
1324 }
1325 if (!skip && mirConst->IsZero()) {
1326 cgFunc.SelectCondSpecialCase1(condGotoNode, *op0);
1327 cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
1328 return;
1329 }
1330 }
1331 /*
1332 * Special case:
1333 * brfalse(ge (cmpg (op0, op1), 0) ==>
1334 * fcmp op1, op2
1335 * blo
1336 */
1337 if ((condGotoNode.GetOpCode() == OP_brfalse) && (condNode->GetOpCode() == OP_ge) && (op0->GetOpCode() == OP_cmpg) &&
1338 (op1->GetOpCode() == OP_constval)) {
1339 auto *constValNode = static_cast<ConstvalNode *>(op1);
1340 MIRConst *mirConst = constValNode->GetConstVal();
1341 if (mirConst->IsZero()) {
1342 cgFunc.SelectCondSpecialCase2(condGotoNode, *op0);
1343 cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
1344 return;
1345 }
1346 }
1347 Operand *opnd0 = cgFunc.HandleExpr(*condNode, *condNode->Opnd(0));
1348 Operand *opnd1 = cgFunc.HandleExpr(*condNode, *condNode->Opnd(1));
1349 cgFunc.SelectCondGoto(condGotoNode, *opnd0, *opnd1);
1350 cgFunc.SetCurBB(*cgFunc.StartNewBB(condGotoNode));
1351 }
1352
HandleReturn(StmtNode & stmt,CGFunc & cgFunc)1353 void HandleReturn(StmtNode &stmt, CGFunc &cgFunc)
1354 {
1355 cgFunc.UpdateFrequency(stmt);
1356 auto &retNode = static_cast<NaryStmtNode &>(stmt);
1357 cgFunc.HandleRetCleanup(retNode);
1358 DEBUG_ASSERT(retNode.NumOpnds() <= 1, "NYI return nodes number > 1");
1359 Operand *opnd = nullptr;
1360 if (retNode.NumOpnds() != 0) {
1361 if (!cgFunc.GetFunction().StructReturnedInRegs()) {
1362 opnd = cgFunc.HandleExpr(retNode, *retNode.Opnd(0));
1363 } else {
1364 cgFunc.SelectReturnSendOfStructInRegs(retNode.Opnd(0));
1365 }
1366 }
1367 cgFunc.SelectReturn(opnd);
1368 cgFunc.SetCurBBKind(BB::kBBReturn);
1369 cgFunc.SetCurBB(*cgFunc.StartNewBB(retNode));
1370 }
1371
HandleCall(StmtNode & stmt,CGFunc & cgFunc)1372 void HandleCall(StmtNode &stmt, CGFunc &cgFunc)
1373 {
1374 cgFunc.UpdateFrequency(stmt);
1375 auto &callNode = static_cast<CallNode &>(stmt);
1376 cgFunc.SelectCall(callNode);
1377 if (cgFunc.GetCurBB()->GetKind() != BB::kBBFallthru) {
1378 cgFunc.SetCurBB(*cgFunc.StartNewBB(callNode));
1379 }
1380
1381 StmtNode *prevStmt = stmt.GetPrev();
1382 if (prevStmt == nullptr || prevStmt->GetOpCode() != OP_catch) {
1383 return;
1384 }
1385 if ((stmt.GetNext() != nullptr) && (stmt.GetNext()->GetOpCode() == OP_label)) {
1386 cgFunc.SetCurBB(*cgFunc.StartNewBBImpl(true, stmt));
1387 }
1388 cgFunc.HandleCatch();
1389 }
1390
HandleICall(StmtNode & stmt,CGFunc & cgFunc)1391 void HandleICall(StmtNode &stmt, CGFunc &cgFunc)
1392 {
1393 cgFunc.UpdateFrequency(stmt);
1394 auto &icallNode = static_cast<IcallNode &>(stmt);
1395 cgFunc.GetCurBB()->SetHasCall();
1396 Operand *opnd0 = cgFunc.HandleExpr(stmt, *icallNode.GetNopndAt(0));
1397 cgFunc.SelectIcall(icallNode, *opnd0);
1398 if (cgFunc.GetCurBB()->GetKind() != BB::kBBFallthru) {
1399 cgFunc.SetCurBB(*cgFunc.StartNewBB(icallNode));
1400 }
1401 }
1402
HandleIntrinCall(StmtNode & stmt,CGFunc & cgFunc)1403 void HandleIntrinCall(StmtNode &stmt, CGFunc &cgFunc)
1404 {
1405 auto &call = static_cast<IntrinsiccallNode &>(stmt);
1406 cgFunc.SelectIntrinCall(call);
1407 }
1408
HandleDassign(StmtNode & stmt,CGFunc & cgFunc)1409 void HandleDassign(StmtNode &stmt, CGFunc &cgFunc)
1410 {
1411 auto &dassignNode = static_cast<DassignNode &>(stmt);
1412 DEBUG_ASSERT(dassignNode.GetOpCode() == OP_dassign, "expect dassign");
1413 BaseNode *rhs = dassignNode.GetRHS();
1414 DEBUG_ASSERT(rhs != nullptr, "get rhs of dassignNode failed");
1415 if (rhs->GetOpCode() == OP_malloc || rhs->GetOpCode() == OP_alloca) {
1416 UnaryStmtNode &uNode = static_cast<UnaryStmtNode &>(stmt);
1417 Operand *opnd0 = cgFunc.HandleExpr(dassignNode, *(uNode.Opnd()));
1418 cgFunc.SelectDassign(dassignNode, *opnd0);
1419 return;
1420 } else if (rhs->GetPrimType() == PTY_agg) {
1421 cgFunc.SelectAggDassign(dassignNode);
1422 return;
1423 }
1424 bool isSaveRetvalToLocal = false;
1425 if (rhs->GetOpCode() == OP_regread) {
1426 isSaveRetvalToLocal = (static_cast<RegreadNode *>(rhs)->GetRegIdx() == -kSregRetval0);
1427 }
1428 Operand *opnd0 = cgFunc.HandleExpr(dassignNode, *rhs);
1429 cgFunc.SelectDassign(dassignNode, *opnd0);
1430 if (isSaveRetvalToLocal) {
1431 cgFunc.GetCurBB()->GetLastInsn()->MarkAsSaveRetValToLocal();
1432 }
1433 }
1434
HandleDassignoff(StmtNode & stmt,CGFunc & cgFunc)1435 void HandleDassignoff(StmtNode &stmt, CGFunc &cgFunc)
1436 {
1437 auto &dassignoffNode = static_cast<DassignoffNode &>(stmt);
1438 BaseNode *rhs = dassignoffNode.GetRHS();
1439 CHECK_FATAL(rhs->GetOpCode() == OP_constval, "dassignoffNode without constval");
1440 Operand *opnd0 = cgFunc.HandleExpr(dassignoffNode, *rhs);
1441 cgFunc.SelectDassignoff(dassignoffNode, *opnd0);
1442 }
1443
HandleRegassign(StmtNode & stmt,CGFunc & cgFunc)1444 void HandleRegassign(StmtNode &stmt, CGFunc &cgFunc)
1445 {
1446 DEBUG_ASSERT(stmt.GetOpCode() == OP_regassign, "expect regAssign");
1447 auto ®AssignNode = static_cast<RegassignNode &>(stmt);
1448 bool isSaveRetvalToLocal = false;
1449 BaseNode *operand = regAssignNode.Opnd(0);
1450 DEBUG_ASSERT(operand != nullptr, "get operand of regassignNode failed");
1451 if (operand->GetOpCode() == OP_regread) {
1452 isSaveRetvalToLocal = (static_cast<RegreadNode *>(operand)->GetRegIdx() == -kSregRetval0);
1453 }
1454 Operand *opnd0 = cgFunc.HandleExpr(regAssignNode, *operand);
1455 cgFunc.SelectRegassign(regAssignNode, *opnd0);
1456 if (isSaveRetvalToLocal) {
1457 cgFunc.GetCurBB()->GetLastInsn()->MarkAsSaveRetValToLocal();
1458 }
1459 }
1460
HandleIassign(StmtNode & stmt,CGFunc & cgFunc)1461 void HandleIassign(StmtNode &stmt, CGFunc &cgFunc)
1462 {
1463 DEBUG_ASSERT(stmt.GetOpCode() == OP_iassign, "expect stmt");
1464 auto &iassignNode = static_cast<IassignNode &>(stmt);
1465 if ((iassignNode.GetRHS() != nullptr) && iassignNode.GetRHS()->GetPrimType() != PTY_agg) {
1466 cgFunc.SelectIassign(iassignNode);
1467 } else {
1468 BaseNode *addrNode = iassignNode.Opnd(0);
1469 if (addrNode == nullptr) {
1470 return;
1471 }
1472 cgFunc.SelectAggIassign(iassignNode, *cgFunc.HandleExpr(stmt, *addrNode));
1473 }
1474 }
1475
HandleIassignoff(StmtNode & stmt,CGFunc & cgFunc)1476 void HandleIassignoff(StmtNode &stmt, CGFunc &cgFunc)
1477 {
1478 DEBUG_ASSERT(stmt.GetOpCode() == OP_iassignoff, "expect iassignoff");
1479 auto &iassignoffNode = static_cast<IassignoffNode &>(stmt);
1480 cgFunc.SelectIassignoff(iassignoffNode);
1481 }
1482
HandleIassignfpoff(StmtNode & stmt,CGFunc & cgFunc)1483 void HandleIassignfpoff(StmtNode &stmt, CGFunc &cgFunc)
1484 {
1485 DEBUG_ASSERT(stmt.GetOpCode() == OP_iassignfpoff, "expect iassignfpoff");
1486 auto &iassignfpoffNode = static_cast<IassignFPoffNode &>(stmt);
1487 cgFunc.SelectIassignfpoff(iassignfpoffNode, *cgFunc.HandleExpr(stmt, *stmt.Opnd(0)));
1488 }
1489
HandleIassignspoff(StmtNode & stmt,CGFunc & cgFunc)1490 void HandleIassignspoff(StmtNode &stmt, CGFunc &cgFunc)
1491 {
1492 DEBUG_ASSERT(stmt.GetOpCode() == OP_iassignspoff, "expect iassignspoff");
1493 auto &baseNode = static_cast<IassignFPoffNode &>(stmt); /* same as FP */
1494 BaseNode *rhs = baseNode.GetRHS();
1495 DEBUG_ASSERT(rhs != nullptr, "get rhs of iassignspoffNode failed");
1496 Operand *opnd0 = cgFunc.HandleExpr(baseNode, *rhs);
1497 cgFunc.SelectIassignspoff(baseNode.GetPrimType(), baseNode.GetOffset(), *opnd0);
1498 }
1499
HandleBlkassignoff(StmtNode & stmt,CGFunc & cgFunc)1500 void HandleBlkassignoff(StmtNode &stmt, CGFunc &cgFunc)
1501 {
1502 DEBUG_ASSERT(stmt.GetOpCode() == OP_blkassignoff, "expect blkassignoff");
1503 auto &baseNode = static_cast<BlkassignoffNode &>(stmt);
1504 Operand *src = cgFunc.HandleExpr(baseNode, *baseNode.Opnd(1));
1505 cgFunc.SelectBlkassignoff(baseNode, src);
1506 }
1507
HandleEval(const StmtNode & stmt,CGFunc & cgFunc)1508 void HandleEval(const StmtNode &stmt, CGFunc &cgFunc)
1509 {
1510 (void)cgFunc.HandleExpr(stmt, *static_cast<const UnaryStmtNode &>(stmt).Opnd(0));
1511 }
1512
HandleRangeGoto(StmtNode & stmt,CGFunc & cgFunc)1513 void HandleRangeGoto(StmtNode &stmt, CGFunc &cgFunc)
1514 {
1515 cgFunc.UpdateFrequency(stmt);
1516 auto &rangeGotoNode = static_cast<RangeGotoNode &>(stmt);
1517 cgFunc.SetCurBBKind(BB::kBBRangeGoto);
1518 cgFunc.SelectRangeGoto(rangeGotoNode, *cgFunc.HandleExpr(rangeGotoNode, *rangeGotoNode.Opnd(0)));
1519 cgFunc.SetCurBB(*cgFunc.StartNewBB(rangeGotoNode));
1520 }
1521
HandleMembar(StmtNode & stmt,CGFunc & cgFunc)1522 void HandleMembar(StmtNode &stmt, CGFunc &cgFunc)
1523 {
1524 cgFunc.SelectMembar(stmt);
1525 if (stmt.GetOpCode() != OP_membarrelease) {
1526 return;
1527 }
1528 #if TARGAARCH64 || TARGRISCV64
1529 if (CGOptions::UseBarriersForVolatile()) {
1530 return;
1531 }
1532 #endif
1533 StmtNode *secondStmt = stmt.GetRealNext();
1534 if (secondStmt == nullptr || ((secondStmt->GetOpCode() != OP_iassign) && (secondStmt->GetOpCode() != OP_dassign))) {
1535 return;
1536 }
1537 StmtNode *thirdStmt = secondStmt->GetRealNext();
1538 if (thirdStmt == nullptr || thirdStmt->GetOpCode() != OP_membarstoreload) {
1539 return;
1540 }
1541 cgFunc.SetVolStore(true);
1542 cgFunc.SetVolReleaseInsn(cgFunc.GetCurBB()->GetLastInsn());
1543 }
1544
HandleComment(StmtNode & stmt,CGFunc & cgFunc)1545 void HandleComment(StmtNode &stmt, CGFunc &cgFunc)
1546 {
1547 if (cgFunc.GetCG()->GenerateVerboseAsm() || cgFunc.GetCG()->GenerateVerboseCG()) {
1548 cgFunc.SelectComment(static_cast<CommentNode &>(stmt));
1549 }
1550 }
1551
HandleCatchOp(const StmtNode & stmt,const CGFunc & cgFunc)1552 void HandleCatchOp(const StmtNode &stmt, const CGFunc &cgFunc)
1553 {
1554 (void)stmt;
1555 (void)cgFunc;
1556 DEBUG_ASSERT(stmt.GetNext()->GetOpCode() == OP_call, "The next statement of OP_catch should be OP_call.");
1557 }
1558
HandleAssertNull(StmtNode & stmt,CGFunc & cgFunc)1559 void HandleAssertNull(StmtNode &stmt, CGFunc &cgFunc)
1560 {
1561 auto &cgAssertNode = static_cast<UnaryStmtNode &>(stmt);
1562 cgFunc.SelectAssertNull(cgAssertNode);
1563 }
1564
HandleAbort(const StmtNode & stmt,CGFunc & cgFunc)1565 void HandleAbort(const StmtNode &stmt, CGFunc &cgFunc)
1566 {
1567 (void)stmt;
1568 cgFunc.SelectAbort();
1569 }
1570
HandleAsm(StmtNode & stmt,CGFunc & cgFunc)1571 void HandleAsm(StmtNode &stmt, CGFunc &cgFunc)
1572 {
1573 cgFunc.SelectAsm(static_cast<AsmNode &>(stmt));
1574 }
1575
1576 using HandleStmtFactory = FunctionFactory<Opcode, void, StmtNode &, CGFunc &>;
InitHandleStmtFactory()1577 void InitHandleStmtFactory()
1578 {
1579 RegisterFactoryFunction<HandleStmtFactory>(OP_label, HandleLabel);
1580 RegisterFactoryFunction<HandleStmtFactory>(OP_goto, HandleGoto);
1581 RegisterFactoryFunction<HandleStmtFactory>(OP_igoto, HandleIgoto);
1582 RegisterFactoryFunction<HandleStmtFactory>(OP_brfalse, HandleCondbr);
1583 RegisterFactoryFunction<HandleStmtFactory>(OP_brtrue, HandleCondbr);
1584 RegisterFactoryFunction<HandleStmtFactory>(OP_return, HandleReturn);
1585 RegisterFactoryFunction<HandleStmtFactory>(OP_call, HandleCall);
1586 RegisterFactoryFunction<HandleStmtFactory>(OP_icall, HandleICall);
1587 RegisterFactoryFunction<HandleStmtFactory>(OP_icallproto, HandleICall);
1588 RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccall, HandleIntrinCall);
1589 RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccallassigned, HandleIntrinCall);
1590 RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccallwithtype, HandleIntrinCall);
1591 RegisterFactoryFunction<HandleStmtFactory>(OP_intrinsiccallwithtypeassigned, HandleIntrinCall);
1592 RegisterFactoryFunction<HandleStmtFactory>(OP_dassign, HandleDassign);
1593 RegisterFactoryFunction<HandleStmtFactory>(OP_dassignoff, HandleDassignoff);
1594 RegisterFactoryFunction<HandleStmtFactory>(OP_regassign, HandleRegassign);
1595 RegisterFactoryFunction<HandleStmtFactory>(OP_iassign, HandleIassign);
1596 RegisterFactoryFunction<HandleStmtFactory>(OP_iassignoff, HandleIassignoff);
1597 RegisterFactoryFunction<HandleStmtFactory>(OP_iassignfpoff, HandleIassignfpoff);
1598 RegisterFactoryFunction<HandleStmtFactory>(OP_iassignspoff, HandleIassignspoff);
1599 RegisterFactoryFunction<HandleStmtFactory>(OP_blkassignoff, HandleBlkassignoff);
1600 RegisterFactoryFunction<HandleStmtFactory>(OP_eval, HandleEval);
1601 RegisterFactoryFunction<HandleStmtFactory>(OP_rangegoto, HandleRangeGoto);
1602 RegisterFactoryFunction<HandleStmtFactory>(OP_membarrelease, HandleMembar);
1603 RegisterFactoryFunction<HandleStmtFactory>(OP_membaracquire, HandleMembar);
1604 RegisterFactoryFunction<HandleStmtFactory>(OP_membarstoreload, HandleMembar);
1605 RegisterFactoryFunction<HandleStmtFactory>(OP_membarstorestore, HandleMembar);
1606 RegisterFactoryFunction<HandleStmtFactory>(OP_comment, HandleComment);
1607 RegisterFactoryFunction<HandleStmtFactory>(OP_catch, HandleCatchOp);
1608 RegisterFactoryFunction<HandleStmtFactory>(OP_abort, HandleAbort);
1609 RegisterFactoryFunction<HandleStmtFactory>(OP_assertnonnull, HandleAssertNull);
1610 RegisterFactoryFunction<HandleStmtFactory>(OP_callassertnonnull, HandleAssertNull);
1611 RegisterFactoryFunction<HandleStmtFactory>(OP_assignassertnonnull, HandleAssertNull);
1612 RegisterFactoryFunction<HandleStmtFactory>(OP_returnassertnonnull, HandleAssertNull);
1613 RegisterFactoryFunction<HandleStmtFactory>(OP_asm, HandleAsm);
1614 }
1615
CGFunc(MIRModule & mod,CG & cg,MIRFunction & mirFunc,BECommon & beCommon,MemPool & memPool,StackMemPool & stackMp,MapleAllocator & allocator,uint32 funcId)1616 CGFunc::CGFunc(MIRModule &mod, CG &cg, MIRFunction &mirFunc, BECommon &beCommon, MemPool &memPool,
1617 StackMemPool &stackMp, MapleAllocator &allocator, uint32 funcId)
1618 : vRegTable(allocator.Adapter()),
1619 bbVec(allocator.Adapter()),
1620 vRegOperandTable(allocator.Adapter()),
1621 referenceVirtualRegs(allocator.Adapter()),
1622 referenceStackSlots(allocator.Adapter()),
1623 pregIdx2Opnd(mirFunc.GetPregTab()->Size(), nullptr, allocator.Adapter()),
1624 pRegSpillMemOperands(allocator.Adapter()),
1625 spillRegMemOperands(allocator.Adapter()),
1626 reuseSpillLocMem(allocator.Adapter()),
1627 labelMap(std::less<LabelIdx>(), allocator.Adapter()),
1628 vregsToPregsMap(std::less<regno_t>(), allocator.Adapter()),
1629 stackMapInsns(allocator.Adapter()),
1630 hasVLAOrAlloca(mirFunc.HasVlaOrAlloca()),
1631 dbgCallFrameLocations(allocator.Adapter()),
1632 cg(&cg),
1633 mirModule(mod),
1634 memPool(&memPool),
1635 stackMp(stackMp),
1636 func(mirFunc),
1637 exitBBVec(allocator.Adapter()),
1638 extendSet(allocator.Adapter()),
1639 lab2BBMap(allocator.Adapter()),
1640 beCommon(beCommon),
1641 funcScopeAllocator(&allocator),
1642 emitStVec(allocator.Adapter()),
1643 switchLabelCnt(allocator.Adapter()),
1644 #if TARGARM32
1645 sortedBBs(allocator.Adapter()),
1646 lrVec(allocator.Adapter()),
1647 #endif /* TARGARM32 */
1648 loops(allocator.Adapter()),
1649 lmbcParamVec(allocator.Adapter()),
1650 shortFuncName(cg.ExtractFuncName(mirFunc.GetName()) + "." + std::to_string(funcId), &memPool)
1651 {
1652 mirModule.SetCurFunction(&func);
1653 dummyBB = CreateNewBB();
1654 vRegCount = firstMapleIrVRegNO + func.GetPregTab()->Size();
1655 firstNonPregVRegNO = vRegCount;
1656 /* maximum register count initial be increased by 1024 */
1657 maxRegCount = vRegCount + 1024;
1658
1659 insnBuilder = memPool.New<InsnBuilder>(memPool);
1660 opndBuilder = memPool.New<OperandBuilder>(memPool, func.GetPregTab()->Size());
1661
1662 vRegTable.resize(maxRegCount);
1663 /* func.GetPregTab()->_preg_table[0] is nullptr, so skip it */
1664 DEBUG_ASSERT(func.GetPregTab()->PregFromPregIdx(0) == nullptr, "PregFromPregIdx(0) must be nullptr");
1665 for (size_t i = 1; i < func.GetPregTab()->Size(); ++i) {
1666 PrimType primType = func.GetPregTab()->PregFromPregIdx(i)->GetPrimType();
1667 uint32 byteLen = GetPrimTypeSize(primType);
1668 if (byteLen < k4ByteSize) {
1669 byteLen = k4ByteSize;
1670 }
1671 if (primType == PTY_u128 || primType == PTY_i128) {
1672 byteLen = k8ByteSize;
1673 }
1674 new (&GetVirtualRegNodeFromPseudoRegIdx(i)) VirtualRegNode(GetRegTyFromPrimTy(primType), byteLen);
1675 }
1676 firstCGGenLabelIdx = func.GetLabelTab()->GetLabelTableSize();
1677 lSymSize = 0;
1678 if (func.GetSymTab()) {
1679 lSymSize = func.GetSymTab()->GetSymbolTableSize();
1680 }
1681 callingConventionKind = CCImpl::GetCallConvKind(mirFunc);
1682 }
1683
~CGFunc()1684 CGFunc::~CGFunc()
1685 {
1686 mirModule.SetCurFunction(nullptr);
1687 }
1688
HandleExpr(const BaseNode & parent,BaseNode & expr)1689 Operand *CGFunc::HandleExpr(const BaseNode &parent, BaseNode &expr)
1690 {
1691 auto function = CreateProductFunction<HandleExprFactory>(expr.GetOpCode());
1692 CHECK_FATAL(function != nullptr, "unsupported opCode in HandleExpr()");
1693 return function(parent, expr, *this);
1694 }
1695
HandleFirstStmt()1696 StmtNode *CGFunc::HandleFirstStmt()
1697 {
1698 BlockNode *block = func.GetBody();
1699
1700 DEBUG_ASSERT(block != nullptr, "get func body block failed in CGFunc::GenerateInstruction");
1701 StmtNode *stmt = block->GetFirst();
1702 if (stmt == nullptr) {
1703 return nullptr;
1704 }
1705 bool withFreqInfo = func.HasFreqMap() && !func.GetLastFreqMap().empty();
1706 if (withFreqInfo) {
1707 frequency = kFreqBase;
1708 }
1709 DEBUG_ASSERT(stmt->GetOpCode() == OP_label, "The first statement should be a label");
1710 HandleLabel(*stmt, *this);
1711 firstBB = curBB;
1712 stmt = stmt->GetNext();
1713 if (stmt == nullptr) {
1714 return nullptr;
1715 }
1716 curBB = StartNewBBImpl(false, *stmt);
1717 curBB->SetFrequency(frequency);
1718 if (JAVALANG) {
1719 HandleRCCall(true);
1720 }
1721 return stmt;
1722 }
1723
CheckSkipMembarOp(const StmtNode & stmt)1724 bool CGFunc::CheckSkipMembarOp(const StmtNode &stmt)
1725 {
1726 StmtNode *nextStmt = stmt.GetRealNext();
1727 if (nextStmt == nullptr) {
1728 return false;
1729 }
1730
1731 Opcode opCode = stmt.GetOpCode();
1732 if (((opCode == OP_membaracquire) || (opCode == OP_membarrelease)) && (nextStmt->GetOpCode() == stmt.GetOpCode())) {
1733 return true;
1734 }
1735 if ((opCode == OP_membarstorestore) && (nextStmt->GetOpCode() == OP_membarrelease)) {
1736 return true;
1737 }
1738 if ((opCode == OP_membarstorestore) && func.IsConstructor() && MemBarOpt(stmt)) {
1739 return true;
1740 ;
1741 }
1742 #if TARGAARCH64 || TARGRISCV64
1743 if ((!CGOptions::UseBarriersForVolatile()) && (nextStmt->GetOpCode() == OP_membaracquire)) {
1744 isVolLoad = true;
1745 }
1746 #endif /* TARGAARCH64 */
1747 return false;
1748 }
1749
GenerateLoc(StmtNode * stmt,unsigned & lastSrcLoc,unsigned & lastMplLoc)1750 void CGFunc::GenerateLoc(StmtNode *stmt, unsigned &lastSrcLoc, unsigned &lastMplLoc)
1751 {
1752 /* insert Insn for .loc before cg for the stmt */
1753 if (cg->GetCGOptions().WithLoc() && stmt->op != OP_label && stmt->op != OP_comment) {
1754 /* if original src file location info is availiable for this stmt,
1755 * use it and skip mpl file location info for this stmt
1756 */
1757 bool hasLoc = false;
1758 unsigned newSrcLoc = cg->GetCGOptions().WithSrc() ? stmt->GetSrcPos().LineNum() : 0;
1759 if (newSrcLoc != 0 && newSrcLoc != lastSrcLoc) {
1760 /* .loc for original src file */
1761 unsigned fileid = stmt->GetSrcPos().FileNum();
1762 Operand *o0 = CreateDbgImmOperand(fileid);
1763 Operand *o1 = CreateDbgImmOperand(newSrcLoc);
1764 Insn &loc = GetInsnBuilder()->BuildDbgInsn(mpldbg::OP_DBG_loc).AddOpndChain(*o0).AddOpndChain(*o1);
1765 curBB->AppendInsn(loc);
1766 lastSrcLoc = newSrcLoc;
1767 hasLoc = true;
1768 }
1769 /* .loc for mpl file, skip if already has .loc from src for this stmt */
1770 unsigned newMplLoc = cg->GetCGOptions().WithMpl() ? stmt->GetSrcPos().MplLineNum() : 0;
1771 if (newMplLoc != 0 && newMplLoc != lastMplLoc && !hasLoc) {
1772 unsigned fileid = 1;
1773 Operand *o0 = CreateDbgImmOperand(fileid);
1774 Operand *o1 = CreateDbgImmOperand(newMplLoc);
1775 Insn &loc = GetInsnBuilder()->BuildDbgInsn(mpldbg::OP_DBG_loc).AddOpndChain(*o0).AddOpndChain(*o1);
1776 curBB->AppendInsn(loc);
1777 lastMplLoc = newMplLoc;
1778 }
1779 }
1780 }
1781
GetFreqFromStmt(uint32 stmtId)1782 int32 CGFunc::GetFreqFromStmt(uint32 stmtId)
1783 {
1784 int32 freq = GetFunction().GetFreqFromLastStmt(stmtId);
1785 if (freq != -1) {
1786 return freq;
1787 }
1788 return GetFunction().GetFreqFromFirstStmt(stmtId);
1789 }
1790
GetLmbcFormalParamInfo(uint32 offset)1791 LmbcFormalParamInfo *CGFunc::GetLmbcFormalParamInfo(uint32 offset)
1792 {
1793 MapleVector<LmbcFormalParamInfo *> ¶mVec = GetLmbcParamVec();
1794 for (auto *param : paramVec) {
1795 uint32 paramOffset = param->GetOffset();
1796 uint32 paramSize = param->GetSize();
1797 if (paramOffset <= offset && offset < (paramOffset + paramSize)) {
1798 return param;
1799 }
1800 }
1801 return nullptr;
1802 }
1803
1804 /*
1805 * For formals of lmbc, the formal list is deleted if there is no
1806 * passing of aggregate by value.
1807 */
CreateLmbcFormalParamInfo()1808 void CGFunc::CreateLmbcFormalParamInfo()
1809 {
1810 if (GetMirModule().GetFlavor() != MIRFlavor::kFlavorLmbc) {
1811 return;
1812 }
1813 PrimType primType;
1814 uint32 offset;
1815 uint32 typeSize;
1816 MIRFunction &lmbcFunc = GetFunction();
1817 if (lmbcFunc.GetFormalCount() > 0) {
1818 /* Whenever lmbc cannot delete call type info, the prototype is available */
1819 uint32 stackOffset = 0;
1820 for (size_t idx = 0; idx < lmbcFunc.GetFormalCount(); ++idx) {
1821 MIRSymbol *sym = lmbcFunc.GetFormal(idx);
1822 MIRType *type;
1823 TyIdx tyIdx;
1824 if (sym) {
1825 tyIdx = lmbcFunc.GetFormalDefVec()[idx].formalTyIdx;
1826 type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
1827 } else {
1828 FormalDef vec =
1829 const_cast<MIRFunction *>(GetBecommon().GetMIRModule().CurFunction())->GetFormalDefAt(idx);
1830 tyIdx = vec.formalTyIdx;
1831 type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
1832 }
1833 primType = type->GetPrimType();
1834 offset = stackOffset;
1835 typeSize = static_cast<uint32>(GetBecommon().GetTypeSize(tyIdx));
1836 stackOffset += (typeSize + k7BitSize) & (kNegative8BitSize);
1837 LmbcFormalParamInfo *info = GetMemoryPool()->New<LmbcFormalParamInfo>(primType, offset, typeSize);
1838 lmbcParamVec.push_back(info);
1839 if (idx == 0 && lmbcFunc.IsFirstArgReturn()) {
1840 info->SetIsReturn();
1841 }
1842 if (type->GetKind() == kTypeStruct) {
1843 MIRStructType *structType = static_cast<MIRStructType *>(type);
1844 info->SetType(structType);
1845 uint32 fpSize;
1846 uint32 numFpRegs = FloatParamRegRequired(structType, fpSize);
1847 if (numFpRegs > 0) {
1848 info->SetIsPureFloat();
1849 info->SetNumRegs(numFpRegs);
1850 info->SetFpSize(fpSize);
1851 }
1852 }
1853 }
1854 } else {
1855 /* No aggregate pass by value here */
1856 for (StmtNode *stmt = lmbcFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) {
1857 if (stmt == nullptr) {
1858 break;
1859 }
1860 if (stmt->GetOpCode() == OP_label) {
1861 continue;
1862 }
1863 if (stmt->GetOpCode() != OP_regassign) {
1864 break;
1865 }
1866 RegassignNode *regAssignNode = static_cast<RegassignNode *>(stmt);
1867 BaseNode *operand = regAssignNode->Opnd(0);
1868 if (operand->GetOpCode() != OP_ireadfpoff) {
1869 break;
1870 }
1871 IreadFPoffNode *ireadNode = static_cast<IreadFPoffNode *>(operand);
1872 primType = ireadNode->GetPrimType();
1873 if (ireadNode->GetOffset() < 0) {
1874 continue;
1875 }
1876 offset = static_cast<uint32>(ireadNode->GetOffset());
1877 typeSize = GetPrimTypeSize(primType);
1878 CHECK_FATAL((offset % k8ByteSize) == 0, ""); /* scalar only, no struct for now */
1879 LmbcFormalParamInfo *info = GetMemoryPool()->New<LmbcFormalParamInfo>(primType, offset, typeSize);
1880 lmbcParamVec.push_back(info);
1881 }
1882 }
1883 std::sort(lmbcParamVec.begin(), lmbcParamVec.end(), [](const LmbcFormalParamInfo *x, const LmbcFormalParamInfo *y) {
1884 return x->GetOffset() < y->GetOffset();
1885 });
1886
1887 /* When a scalar param address is taken, its regassign is not in the 1st block */
1888 for (StmtNode *stmt = lmbcFunc.GetBody()->GetFirst(); stmt != nullptr; stmt = stmt->GetNext()) {
1889 if (stmt == nullptr) {
1890 break;
1891 }
1892 if (stmt->GetOpCode() == OP_label) {
1893 continue;
1894 }
1895 if (stmt->GetOpCode() != OP_regassign) {
1896 break;
1897 }
1898 RegassignNode *regAssignNode = static_cast<RegassignNode *>(stmt);
1899 BaseNode *operand = regAssignNode->Opnd(0);
1900 if (operand->GetOpCode() != OP_ireadfpoff) {
1901 break;
1902 }
1903 IreadFPoffNode *ireadNode = static_cast<IreadFPoffNode *>(operand);
1904 if (ireadNode->GetOffset() < 0) {
1905 continue;
1906 }
1907 LmbcFormalParamInfo *info = GetLmbcFormalParamInfo(static_cast<uint32>(ireadNode->GetOffset()));
1908 ASSERT_NOT_NULL(info);
1909 info->SetHasRegassign();
1910 }
1911
1912 AssignLmbcFormalParams();
1913 }
1914
GenerateInstruction()1915 void CGFunc::GenerateInstruction()
1916 {
1917 InitHandleExprFactory();
1918 InitHandleStmtFactory();
1919 StmtNode *secondStmt = HandleFirstStmt();
1920
1921 /* First Pass: Creates the doubly-linked list of BBs (next,prev) */
1922 volReleaseInsn = nullptr;
1923 unsigned lastSrcLoc = 0;
1924 unsigned lastMplLoc = 0;
1925 std::set<uint32> bbFreqSet;
1926 for (StmtNode *stmt = secondStmt; stmt != nullptr; stmt = stmt->GetNext()) {
1927 /* insert Insn for .loc before cg for the stmt */
1928 GenerateLoc(stmt, lastSrcLoc, lastMplLoc);
1929 BB *tmpBB = curBB;
1930 isVolLoad = false;
1931 if (CheckSkipMembarOp(*stmt)) {
1932 continue;
1933 }
1934 bool tempLoad = isVolLoad;
1935 auto function = CreateProductFunction<HandleStmtFactory>(stmt->GetOpCode());
1936 CHECK_FATAL(function != nullptr, "unsupported opCode or has been lowered before");
1937 function(*stmt, *this);
1938 /* skip the membar acquire if it is just after the iread. ldr + membaraquire->ldar */
1939 if (tempLoad && !isVolLoad) {
1940 stmt = stmt->GetNext();
1941 }
1942 int32 freq = GetFreqFromStmt(stmt->GetStmtID());
1943 if (freq != -1) {
1944 if (tmpBB != curBB) {
1945 if (curBB->GetFirstInsn() == nullptr && curBB->GetLabIdx() == 0 &&
1946 bbFreqSet.count(tmpBB->GetId()) == 0) {
1947 tmpBB->SetFrequency(static_cast<uint32>(freq));
1948 bbFreqSet.insert(tmpBB->GetId());
1949 } else if ((curBB->GetFirstInsn() != nullptr || curBB->GetLabIdx() != 0) &&
1950 bbFreqSet.count(curBB->GetId()) == 0) {
1951 curBB->SetFrequency(static_cast<uint32>(freq));
1952 bbFreqSet.insert(tmpBB->GetId());
1953 }
1954 } else if (bbFreqSet.count(curBB->GetId()) == 0) {
1955 curBB->SetFrequency(static_cast<uint32>(freq));
1956 bbFreqSet.insert(curBB->GetId());
1957 }
1958 }
1959
1960 /*
1961 * skip the membarstoreload if there is the pattern for volatile write( membarrelease + store + membarstoreload
1962 * ) membarrelease + store + membarstoreload -> stlr
1963 */
1964 if (volReleaseInsn != nullptr) {
1965 if ((stmt->GetOpCode() != OP_membarrelease) && (stmt->GetOpCode() != OP_comment)) {
1966 if (!isVolStore) {
1967 /* remove the generated membar release insn. */
1968 curBB->RemoveInsn(*volReleaseInsn);
1969 /* skip the membarstoreload. */
1970 stmt = stmt->GetNext();
1971 }
1972 volReleaseInsn = nullptr;
1973 isVolStore = false;
1974 }
1975 }
1976 if (curBB != tmpBB) {
1977 lastSrcLoc = 0;
1978 }
1979 }
1980
1981 /* Set lastbb's frequency */
1982 BlockNode *block = func.GetBody();
1983 DEBUG_ASSERT(block != nullptr, "get func body block failed in CGFunc::GenerateInstruction");
1984 curBB->SetLastStmt(*block->GetLast());
1985 curBB->SetFrequency(frequency);
1986 lastBB = curBB;
1987 cleanupBB = lastBB->GetPrev();
1988 /* All stmts are handled */
1989 frequency = 0;
1990 }
1991
CreateLabel()1992 LabelIdx CGFunc::CreateLabel()
1993 {
1994 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
1995 DEBUG_ASSERT(funcSt != nullptr, "Get func failed at CGFunc::CreateLabel");
1996 std::string funcName = funcSt->GetName();
1997 std::string labelStr = funcName += std::to_string(labelIdx++);
1998 return func.GetOrCreateLableIdxFromName(labelStr);
1999 }
2000
GetRetRefSymbol(BaseNode & expr)2001 MIRSymbol *CGFunc::GetRetRefSymbol(BaseNode &expr)
2002 {
2003 Opcode opcode = expr.GetOpCode();
2004 if (opcode != OP_dread) {
2005 return nullptr;
2006 }
2007 auto &retExpr = static_cast<AddrofNode &>(expr);
2008 MIRSymbol *symbol = mirModule.CurFunction()->GetLocalOrGlobalSymbol(retExpr.GetStIdx());
2009 DEBUG_ASSERT(symbol != nullptr, "get symbol in mirmodule failed");
2010 if (symbol->IsRefType()) {
2011 MIRSymbol *sym = nullptr;
2012 for (uint32 i = 0; i < func.GetFormalCount(); i++) {
2013 sym = func.GetFormal(i);
2014 if (sym == symbol) {
2015 return nullptr;
2016 }
2017 }
2018 return symbol;
2019 }
2020 return nullptr;
2021 }
2022
GenerateCfiPrologEpilog()2023 void CGFunc::GenerateCfiPrologEpilog()
2024 {
2025 if (GenCfi() == false) {
2026 return;
2027 }
2028 Insn &ipoint = GetInsnBuilder()->BuildCfiInsn(cfi::OP_CFI_startproc);
2029 /* prolog */
2030 if (firstBB->GetFirstInsn() != nullptr) {
2031 firstBB->InsertInsnBefore(*firstBB->GetFirstInsn(), ipoint);
2032 } else {
2033 firstBB->AppendInsn(ipoint);
2034 }
2035
2036 #if !defined(TARGARM32)
2037 /*
2038 * always generate ".cfi_personality 155, DW.ref.__mpl_personality_v0" for Java methods.
2039 * we depend on this to tell whether it is a java method.
2040 */
2041 if (mirModule.IsJavaModule() && func.IsJava()) {
2042 Insn &personality = GetInsnBuilder()
2043 ->BuildCfiInsn(cfi::OP_CFI_personality_symbol)
2044 .AddOpndChain(CreateCfiImmOperand(EHFunc::kTypeEncoding, k8BitSize))
2045 .AddOpndChain(CreateCfiStrOperand("DW.ref.__mpl_personality_v0"));
2046 firstBB->InsertInsnAfter(ipoint, personality);
2047 }
2048 #endif
2049
2050 /* epilog */
2051 lastBB->AppendInsn(GetInsnBuilder()->BuildCfiInsn(cfi::OP_CFI_endproc));
2052 }
2053
TraverseAndClearCatchMark(BB & bb)2054 void CGFunc::TraverseAndClearCatchMark(BB &bb)
2055 {
2056 /* has bb been visited */
2057 if (bb.GetInternalFlag3()) {
2058 return;
2059 }
2060 bb.SetIsCatch(false);
2061 bb.SetInternalFlag3(1);
2062 for (auto succBB : bb.GetSuccs()) {
2063 TraverseAndClearCatchMark(*succBB);
2064 }
2065 }
2066
2067 /*
2068 * Two types of successor edges, normal and eh. Any bb which is not
2069 * reachable by a normal successor edge is considered to be in a
2070 * catch block.
2071 * Marking it as a catch block does not automatically make it into
2072 * a catch block. Unreachables can be marked as such too.
2073 */
MarkCatchBBs()2074 void CGFunc::MarkCatchBBs()
2075 {
2076 /* First, suspect all bb to be in catch */
2077 FOR_ALL_BB(bb, this) {
2078 bb->SetIsCatch(true);
2079 bb->SetInternalFlag3(0); /* mark as not visited */
2080 }
2081 /* Eliminate cleanup section from catch */
2082 FOR_ALL_BB(bb, this) {
2083 if (bb->GetFirstStmt() == cleanupLabel) {
2084 bb->SetIsCatch(false);
2085 DEBUG_ASSERT(bb->GetSuccs().size() <= 1, "MarkCatchBBs incorrect cleanup label");
2086 BB *succ = nullptr;
2087 if (!bb->GetSuccs().empty()) {
2088 succ = bb->GetSuccs().front();
2089 } else {
2090 continue;
2091 }
2092 DEBUG_ASSERT(succ != nullptr, "Get front succsBB failed");
2093 while (1) {
2094 DEBUG_ASSERT(succ->GetSuccs().size() <= 1, "MarkCatchBBs incorrect cleanup label");
2095 succ->SetIsCatch(false);
2096 if (!succ->GetSuccs().empty()) {
2097 succ = succ->GetSuccs().front();
2098 } else {
2099 break;
2100 }
2101 }
2102 }
2103 }
2104 /* Unmark all normally reachable bb as NOT catch. */
2105 TraverseAndClearCatchMark(*firstBB);
2106 }
2107
2108 /*
2109 * Mark CleanupEntryBB
2110 * Note: Cleanup bbs and func body bbs are seperated, no edges between them.
2111 * No ehSuccs or eh_prevs between cleanup bbs.
2112 */
MarkCleanupEntryBB()2113 void CGFunc::MarkCleanupEntryBB()
2114 {
2115 BB *cleanupEntry = nullptr;
2116 FOR_ALL_BB(bb, this) {
2117 bb->SetIsCleanup(0); /* Use to mark cleanup bb */
2118 bb->SetInternalFlag3(0); /* Use to mark if visited. */
2119 if (bb->GetFirstStmt() == this->cleanupLabel) {
2120 cleanupEntry = bb;
2121 }
2122 }
2123 /* If a function without cleanup bb, return. */
2124 if (cleanupEntry == nullptr) {
2125 return;
2126 }
2127 /* after merge bb, update cleanupBB. */
2128 if (cleanupEntry->GetSuccs().empty()) {
2129 this->cleanupBB = cleanupEntry;
2130 }
2131 SetCleanupLabel(*cleanupEntry);
2132 DEBUG_ASSERT(cleanupEntry->GetEhSuccs().empty(), "CG internal error. Cleanup bb should not have ehSuccs.");
2133 #if DEBUG /* Please don't remove me. */
2134 /* Check if all of the cleanup bb is at bottom of the function. */
2135 bool isCleanupArea = true;
2136 if (!mirModule.IsCModule()) {
2137 FOR_ALL_BB_REV(bb, this) {
2138 if (isCleanupArea) {
2139 DEBUG_ASSERT(bb->IsCleanup(),
2140 "CG internal error, cleanup BBs should be at the bottom of the function.");
2141 } else {
2142 DEBUG_ASSERT(!bb->IsCleanup(),
2143 "CG internal error, cleanup BBs should be at the bottom of the function.");
2144 }
2145
2146 if (bb == cleanupEntry) {
2147 isCleanupArea = false;
2148 }
2149 }
2150 }
2151 #endif /* DEBUG */
2152 this->cleanupEntryBB = cleanupEntry;
2153 }
2154
2155 /* Tranverse from current bb's successor and set isCleanup true. */
SetCleanupLabel(BB & cleanupEntry)2156 void CGFunc::SetCleanupLabel(BB &cleanupEntry)
2157 {
2158 /* If bb hasn't been visited, return. */
2159 if (cleanupEntry.GetInternalFlag3()) {
2160 return;
2161 }
2162 cleanupEntry.SetInternalFlag3(1);
2163 cleanupEntry.SetIsCleanup(1);
2164 for (auto tmpBB : cleanupEntry.GetSuccs()) {
2165 if (tmpBB->GetKind() != BB::kBBReturn) {
2166 SetCleanupLabel(*tmpBB);
2167 } else {
2168 DEBUG_ASSERT(ExitbbNotInCleanupArea(cleanupEntry), "exitBB created in cleanupArea.");
2169 }
2170 }
2171 }
2172
ExitbbNotInCleanupArea(const BB & bb) const2173 bool CGFunc::ExitbbNotInCleanupArea(const BB &bb) const
2174 {
2175 for (const BB *nextBB = bb.GetNext(); nextBB != nullptr; nextBB = nextBB->GetNext()) {
2176 if (nextBB->GetKind() == BB::kBBReturn) {
2177 return false;
2178 }
2179 }
2180 return true;
2181 }
2182
2183 /*
2184 * Do mem barrier optimization for constructor funcs as follow:
2185 * membarstorestore
2186 * write field of this_ ==> write field of this_
2187 * membarrelease membarrelease.
2188 */
MemBarOpt(const StmtNode & membar)2189 bool CGFunc::MemBarOpt(const StmtNode &membar)
2190 {
2191 if (func.GetFormalCount() == 0) {
2192 return false;
2193 }
2194 MIRSymbol *thisSym = func.GetFormal(0);
2195 if (thisSym == nullptr) {
2196 return false;
2197 }
2198 StmtNode *stmt = membar.GetNext();
2199 for (; stmt != nullptr; stmt = stmt->GetNext()) {
2200 BaseNode *base = nullptr;
2201 if (stmt->GetOpCode() == OP_comment) {
2202 continue;
2203 } else if (stmt->GetOpCode() == OP_iassign) {
2204 base = static_cast<IassignNode *>(stmt)->Opnd(0);
2205 } else if (stmt->GetOpCode() == OP_call) {
2206 auto *callNode = static_cast<CallNode *>(stmt);
2207 MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(callNode->GetPUIdx());
2208 MIRSymbol *fsym = GetMirModule().CurFunction()->GetLocalOrGlobalSymbol(fn->GetStIdx(), false);
2209 DEBUG_ASSERT(fsym != nullptr, "null ptr check");
2210 if (fsym->GetName() == "MCC_WriteRefFieldNoDec") {
2211 base = callNode->Opnd(0);
2212 }
2213 }
2214 if (base != nullptr) {
2215 Opcode op = base->GetOpCode();
2216 if (op == OP_regread && thisSym->IsPreg() &&
2217 thisSym->GetPreg()->GetPregNo() == static_cast<RegreadNode *>(base)->GetRegIdx()) {
2218 continue;
2219 }
2220 if ((op == OP_dread || op == OP_addrof) && !thisSym->IsPreg() &&
2221 static_cast<AddrofNode *>(base)->GetStIdx() == thisSym->GetStIdx()) {
2222 continue;
2223 }
2224 }
2225 break;
2226 }
2227
2228 CHECK_NULL_FATAL(stmt);
2229 return stmt->GetOpCode() == OP_membarrelease;
2230 }
2231
ProcessExitBBVec()2232 void CGFunc::ProcessExitBBVec()
2233 {
2234 if (exitBBVec.empty()) {
2235 LabelIdx newLabelIdx = CreateLabel();
2236 BB *retBB = CreateNewBB(newLabelIdx, cleanupBB->IsUnreachable(), BB::kBBReturn, cleanupBB->GetFrequency());
2237 cleanupBB->PrependBB(*retBB);
2238 exitBBVec.emplace_back(retBB);
2239 return;
2240 }
2241 /* split an empty exitBB */
2242 BB *bb = exitBBVec[0];
2243 if (bb->NumInsn() > 0) {
2244 BB *retBBPart = CreateNewBB(false, BB::kBBFallthru, bb->GetFrequency());
2245 DEBUG_ASSERT(retBBPart != nullptr, "retBBPart should not be nullptr");
2246 LabelIdx retBBPartLabelIdx = bb->GetLabIdx();
2247 if (retBBPartLabelIdx != MIRLabelTable::GetDummyLabel()) {
2248 retBBPart->AddLabel(retBBPartLabelIdx);
2249 lab2BBMap[retBBPartLabelIdx] = retBBPart;
2250 }
2251 Insn *insn = bb->GetFirstInsn();
2252 while (insn != nullptr) {
2253 bb->RemoveInsn(*insn);
2254 retBBPart->AppendInsn(*insn);
2255 insn = bb->GetFirstInsn();
2256 }
2257 bb->PrependBB(*retBBPart);
2258 LabelIdx newLabelIdx = CreateLabel();
2259 bb->AddLabel(newLabelIdx);
2260 lab2BBMap[newLabelIdx] = bb;
2261 }
2262 }
2263
AddCommonExitBB()2264 void CGFunc::AddCommonExitBB()
2265 {
2266 uint32 i = 0;
2267 while (exitBBVec[i]->IsUnreachable() && i < exitBBVec.size()) {
2268 i++;
2269 }
2270 DEBUG_ASSERT(i < exitBBVec.size(), "all exit BBs are unreachable");
2271 // create fake commonExitBB
2272 commonExitBB = CreateNewBB(true, BB::kBBFallthru, 0);
2273 DEBUG_ASSERT(commonExitBB != nullptr, "cannot create fake commonExitBB");
2274 for (BB *cgbb : exitBBVec) {
2275 if (!cgbb->IsUnreachable()) {
2276 commonExitBB->PushBackPreds(*cgbb);
2277 }
2278 }
2279 }
2280
UpdateCallBBFrequency()2281 void CGFunc::UpdateCallBBFrequency()
2282 {
2283 if (!func.HasFreqMap() || func.GetLastFreqMap().empty()) {
2284 return;
2285 }
2286 FOR_ALL_BB(bb, this) {
2287 if (bb->GetKind() != BB::kBBFallthru || !bb->HasCall()) {
2288 continue;
2289 }
2290 DEBUG_ASSERT(bb->GetSuccs().size() <= 1, "fallthru BB has only one successor.");
2291 if (!bb->GetSuccs().empty()) {
2292 bb->SetFrequency((*(bb->GetSuccsBegin()))->GetFrequency());
2293 }
2294 }
2295 }
2296
HandleFunction()2297 void CGFunc::HandleFunction()
2298 {
2299 /* select instruction */
2300 GenerateInstruction();
2301 /* merge multi return */
2302 if (!func.GetModule()->IsCModule() || CGOptions::DoRetMerge() || CGOptions::OptimizeForSize()) {
2303 MergeReturn();
2304 }
2305 if (func.IsJava()) {
2306 DEBUG_ASSERT(exitBBVec.size() <= 1, "there are more than one BB_return in func");
2307 }
2308 ProcessExitBBVec();
2309 LmbcGenSaveSpForAlloca();
2310
2311 if (func.IsJava()) {
2312 GenerateCleanupCodeForExtEpilog(*cleanupBB);
2313 } else if (!func.GetModule()->IsCModule()) {
2314 GenerateCleanupCode(*cleanupBB);
2315 }
2316 GenSaveMethodInfoCode(*firstBB);
2317 /* build control flow graph */
2318 theCFG = memPool->New<CGCFG>(*this);
2319 theCFG->BuildCFG();
2320 AddCommonExitBB();
2321 if (mirModule.GetSrcLang() != kSrcLangC) {
2322 MarkCatchBBs();
2323 }
2324 MarkCleanupEntryBB();
2325 DetermineReturnTypeofCall();
2326 theCFG->MarkLabelTakenBB();
2327 theCFG->UnreachCodeAnalysis();
2328 EraseUnreachableStackMapInsns();
2329 if (mirModule.GetSrcLang() == kSrcLangC) {
2330 theCFG->WontExitAnalysis();
2331 }
2332 if (CGOptions::IsLazyBinding() && !GetCG()->IsLibcore()) {
2333 ProcessLazyBinding();
2334 }
2335 if (GetCG()->DoPatchLongBranch()) {
2336 PatchLongBranch();
2337 }
2338 if (CGOptions::DoEnableHotColdSplit()) {
2339 theCFG->CheckCFGFreq();
2340 }
2341 }
2342
AddDIESymbolLocation(const MIRSymbol * sym,SymbolAlloc * loc)2343 void CGFunc::AddDIESymbolLocation(const MIRSymbol *sym, SymbolAlloc *loc)
2344 {
2345 DEBUG_ASSERT(debugInfo != nullptr, "debugInfo is null!");
2346 DEBUG_ASSERT(loc->GetMemSegment() != nullptr, "only support those variable that locate at stack now");
2347 DBGDie *sdie = debugInfo->GetLocalDie(&func, sym->GetNameStrIdx());
2348 if (sdie == nullptr) {
2349 return;
2350 }
2351
2352 DBGExprLoc *exprloc = sdie->GetExprLoc();
2353 CHECK_FATAL(exprloc != nullptr, "exprloc is null in CGFunc::AddDIESymbolLocation");
2354 exprloc->SetSymLoc(loc);
2355
2356 GetDbgCallFrameLocations().push_back(exprloc);
2357 }
2358
DumpCFG() const2359 void CGFunc::DumpCFG() const
2360 {
2361 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
2362 DEBUG_ASSERT(funcSt != nullptr, "null ptr check");
2363 LogInfo::MapleLogger() << "\n****** CFG built by CG for " << funcSt->GetName() << " *******\n";
2364 FOR_ALL_BB_CONST(bb, this) {
2365 LogInfo::MapleLogger() << "=== BB ( " << std::hex << bb << std::dec << " ) <" << bb->GetKindName() << "> ===\n";
2366 LogInfo::MapleLogger() << "BB id:" << bb->GetId() << "\n";
2367 if (!bb->GetPreds().empty()) {
2368 LogInfo::MapleLogger() << " pred [ ";
2369 for (auto *pred : bb->GetPreds()) {
2370 LogInfo::MapleLogger() << pred->GetId() << " ";
2371 }
2372 LogInfo::MapleLogger() << "]\n";
2373 }
2374 if (!bb->GetSuccs().empty()) {
2375 LogInfo::MapleLogger() << " succ [ ";
2376 for (auto *succ : bb->GetSuccs()) {
2377 LogInfo::MapleLogger() << succ->GetId() << " ";
2378 }
2379 LogInfo::MapleLogger() << "]\n";
2380 }
2381 const StmtNode *stmt = bb->GetFirstStmt();
2382 if (stmt != nullptr) {
2383 bool done = false;
2384 do {
2385 done = stmt == bb->GetLastStmt();
2386 stmt->Dump(1);
2387 LogInfo::MapleLogger() << "\n";
2388 stmt = stmt->GetNext();
2389 } while (!done);
2390 } else {
2391 LogInfo::MapleLogger() << "<empty BB>\n";
2392 }
2393 }
2394 }
2395
DumpCGIR() const2396 void CGFunc::DumpCGIR() const
2397 {
2398 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func.GetStIdx().Idx());
2399 DEBUG_ASSERT(funcSt != nullptr, "null ptr check");
2400 LogInfo::MapleLogger() << "\n****** CGIR for " << funcSt->GetName() << " *******\n";
2401 FOR_ALL_BB_CONST(bb, this) {
2402 if (bb->IsUnreachable()) {
2403 continue;
2404 }
2405 LogInfo::MapleLogger() << "=== BB "
2406 << " <" << bb->GetKindName();
2407 if (bb->GetLabIdx() != MIRLabelTable::GetDummyLabel()) {
2408 LogInfo::MapleLogger() << "[labeled with " << bb->GetLabIdx();
2409 LogInfo::MapleLogger() << " ==> @" << func.GetLabelName(bb->GetLabIdx()) << "]";
2410 }
2411
2412 LogInfo::MapleLogger() << "> <" << bb->GetId() << "> ";
2413 if (bb->GetLoop()) {
2414 LogInfo::MapleLogger() << "[Loop level " << bb->GetLoop()->GetLoopLevel();
2415 LogInfo::MapleLogger() << ", head BB " << bb->GetLoop()->GetHeader()->GetId() << "]";
2416 }
2417 if (bb->IsCleanup()) {
2418 LogInfo::MapleLogger() << "[is_cleanup] ";
2419 }
2420 if (bb->IsUnreachable()) {
2421 LogInfo::MapleLogger() << "[unreachable] ";
2422 }
2423 if (bb->GetFirstStmt() == cleanupLabel) {
2424 LogInfo::MapleLogger() << "cleanup ";
2425 }
2426 if (!bb->GetSuccs().empty()) {
2427 LogInfo::MapleLogger() << "succs: ";
2428 for (auto *succBB : bb->GetSuccs()) {
2429 LogInfo::MapleLogger() << succBB->GetId() << " ";
2430 }
2431 }
2432 if (!bb->GetPreds().empty()) {
2433 LogInfo::MapleLogger() << "preds: ";
2434 for (auto *predBB : bb->GetPreds()) {
2435 LogInfo::MapleLogger() << predBB->GetId() << " ";
2436 }
2437 }
2438 if (!bb->GetEhSuccs().empty()) {
2439 LogInfo::MapleLogger() << "eh_succs: ";
2440 for (auto *ehSuccBB : bb->GetEhSuccs()) {
2441 LogInfo::MapleLogger() << ehSuccBB->GetId() << " ";
2442 }
2443 }
2444 if (!bb->GetEhPreds().empty()) {
2445 LogInfo::MapleLogger() << "eh_preds: ";
2446 for (auto *ehPredBB : bb->GetEhPreds()) {
2447 LogInfo::MapleLogger() << ehPredBB->GetId() << " ";
2448 }
2449 }
2450 LogInfo::MapleLogger() << "===\n";
2451 LogInfo::MapleLogger() << "frequency:" << bb->GetFrequency() << "\n";
2452
2453 FOR_BB_INSNS_CONST(insn, bb) {
2454 insn->Dump();
2455 }
2456 }
2457 }
2458
DumpLoop() const2459 void CGFunc::DumpLoop() const
2460 {
2461 for (const auto *lp : loops) {
2462 lp->PrintLoops(*lp);
2463 }
2464 }
2465
ClearLoopInfo()2466 void CGFunc::ClearLoopInfo()
2467 {
2468 loops.clear();
2469 loops.shrink_to_fit();
2470 FOR_ALL_BB(bb, this) {
2471 bb->ClearLoopPreds();
2472 bb->ClearLoopSuccs();
2473 }
2474 }
2475
DumpCFGToDot(const std::string & fileNamePrefix)2476 void CGFunc::DumpCFGToDot(const std::string &fileNamePrefix)
2477 {
2478 std::ofstream file(fileNamePrefix + GetName());
2479 file << "digraph {" << std::endl;
2480 for (auto *bb : GetAllBBs()) {
2481 if (bb == nullptr) {
2482 continue;
2483 }
2484 auto &succs = bb->GetSuccs();
2485 if (succs.empty()) {
2486 continue;
2487 }
2488 file << " " << bb->GetId() << "->{";
2489 for (auto *succ : succs) {
2490 file << succ->GetId() << " ";
2491 }
2492 file << "};";
2493 }
2494 file << "}" << std::endl;
2495 }
2496
PatchLongBranch()2497 void CGFunc::PatchLongBranch()
2498 {
2499 for (BB *bb = firstBB->GetNext(); bb != nullptr; bb = bb->GetNext()) {
2500 bb->SetInternalFlag1(bb->GetInternalFlag1() + bb->GetPrev()->GetInternalFlag1());
2501 }
2502 BB *next = nullptr;
2503 for (BB *bb = firstBB; bb != nullptr; bb = next) {
2504 next = bb->GetNext();
2505 if (bb->GetKind() != BB::kBBIf && bb->GetKind() != BB::kBBGoto) {
2506 continue;
2507 }
2508 Insn *insn = bb->GetLastInsn();
2509 while (insn->IsImmaterialInsn()) {
2510 insn = insn->GetPrev();
2511 }
2512 BB *tbb = GetBBFromLab2BBMap(GetLabelInInsn(*insn));
2513 if ((tbb->GetInternalFlag1() - bb->GetInternalFlag1()) < MaxCondBranchDistance()) {
2514 continue;
2515 }
2516 InsertJumpPad(insn);
2517 }
2518 }
2519
UpdateAllRegisterVregMapping(MapleMap<regno_t,PregIdx> & newMap)2520 void CGFunc::UpdateAllRegisterVregMapping(MapleMap<regno_t, PregIdx> &newMap)
2521 {
2522 vregsToPregsMap.clear();
2523 for (auto it : newMap) {
2524 vregsToPregsMap[it.first] = it.second;
2525 }
2526 }
2527
PhaseRun(maplebe::CGFunc & f)2528 bool CgHandleFunction::PhaseRun(maplebe::CGFunc &f)
2529 {
2530 f.HandleFunction();
2531 return false;
2532 }
MAPLE_TRANSFORM_PHASE_REGISTER(CgHandleFunction,handlefunction)2533 MAPLE_TRANSFORM_PHASE_REGISTER(CgHandleFunction, handlefunction)
2534
2535 bool CgFixCFLocOsft::PhaseRun(maplebe::CGFunc &f)
2536 {
2537 if (f.GetCG()->GetCGOptions().WithDwarf()) {
2538 f.DBGFixCallFrameLocationOffsets();
2539 }
2540 return false;
2541 }
2542 MAPLE_TRANSFORM_PHASE_REGISTER(CgFixCFLocOsft, dbgfixcallframeoffsets)
2543 } /* namespace maplebe */
2544