1 /*
2 * Copyright (c) 2021 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 "ecmascript/compiler/argument_accessor.h"
17 #include "ecmascript/compiler/circuit_builder.h"
18 #include "ecmascript/compiler/gate_accessor.h"
19 #include "ecmascript/compiler/graph_editor.h"
20 #include "ecmascript/js_tagged_value.h"
21
22 namespace panda::ecmascript::kungfu {
23 using UseIterator = GateAccessor::UseIterator;
24
GetNumIns(GateRef gate) const25 size_t GateAccessor::GetNumIns(GateRef gate) const
26 {
27 Gate *gatePtr = circuit_->LoadGatePtr(gate);
28 return gatePtr->GetNumIns();
29 }
30
GetMark(GateRef gate) const31 MarkCode GateAccessor::GetMark(GateRef gate) const
32 {
33 return circuit_->GetMark(gate);
34 }
35
SetMark(GateRef gate,MarkCode mark)36 void GateAccessor::SetMark(GateRef gate, MarkCode mark)
37 {
38 circuit_->SetMark(gate, mark);
39 }
40
IsFinished(GateRef gate) const41 bool GateAccessor::IsFinished(GateRef gate) const
42 {
43 return GetMark(gate) == MarkCode::FINISHED;
44 }
45
IsVisited(GateRef gate) const46 bool GateAccessor::IsVisited(GateRef gate) const
47 {
48 return GetMark(gate) == MarkCode::VISITED;
49 }
50
IsPrevisit(GateRef gate) const51 bool GateAccessor::IsPrevisit(GateRef gate) const
52 {
53 return GetMark(gate) == MarkCode::PREVISIT;
54 }
55
IsNotMarked(GateRef gate) const56 bool GateAccessor::IsNotMarked(GateRef gate) const
57 {
58 return GetMark(gate) == MarkCode::NO_MARK;
59 }
60
SetFinished(GateRef gate)61 void GateAccessor::SetFinished(GateRef gate)
62 {
63 SetMark(gate, MarkCode::FINISHED);
64 }
65
SetVisited(GateRef gate)66 void GateAccessor::SetVisited(GateRef gate)
67 {
68 SetMark(gate, MarkCode::VISITED);
69 }
70
SetPrevisit(GateRef gate)71 void GateAccessor::SetPrevisit(GateRef gate)
72 {
73 SetMark(gate, MarkCode::PREVISIT);
74 }
75
GetOpCode(GateRef gate) const76 OpCode GateAccessor::GetOpCode(GateRef gate) const
77 {
78 Gate *gatePtr = circuit_->LoadGatePtr(gate);
79 return gatePtr->GetOpCode();
80 }
81
TryGetValue(GateRef gate) const82 BitField GateAccessor::TryGetValue(GateRef gate) const
83 {
84 Gate *gatePtr = circuit_->LoadGatePtr(gate);
85 return gatePtr->TryGetValue();
86 }
87
GetICmpCondition(GateRef gate) const88 ICmpCondition GateAccessor::GetICmpCondition(GateRef gate) const
89 {
90 ASSERT(GetOpCode(gate) == OpCode::ICMP);
91 Gate *gatePtr = circuit_->LoadGatePtr(gate);
92 return static_cast<ICmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
93 }
94
GetFCmpCondition(GateRef gate) const95 FCmpCondition GateAccessor::GetFCmpCondition(GateRef gate) const
96 {
97 ASSERT(GetOpCode(gate) == OpCode::FCMP);
98 Gate *gatePtr = circuit_->LoadGatePtr(gate);
99 return static_cast<FCmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
100 }
101
GetOffset(GateRef gate) const102 size_t GateAccessor::GetOffset(GateRef gate) const
103 {
104 ASSERT(GetOpCode(gate) == OpCode::LOAD_CONST_OFFSET ||
105 GetOpCode(gate) == OpCode::STORE_CONST_OFFSET);
106 Gate *gatePtr = circuit_->LoadGatePtr(gate);
107 auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
108 return accessor.GetOffset();
109 }
110
GetTrueWeight(GateRef gate) const111 uint32_t GateAccessor::GetTrueWeight(GateRef gate) const
112 {
113 ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
114 Gate *gatePtr = circuit_->LoadGatePtr(gate);
115 auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
116 return accessor.GetTrueWeight();
117 }
118
GetFalseWeight(GateRef gate) const119 uint32_t GateAccessor::GetFalseWeight(GateRef gate) const
120 {
121 ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
122 Gate *gatePtr = circuit_->LoadGatePtr(gate);
123 auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
124 return accessor.GetFalseWeight();
125 }
126
GetMemoryOrder(GateRef gate) const127 MemoryOrder GateAccessor::GetMemoryOrder(GateRef gate) const
128 {
129 auto op = GetOpCode(gate);
130 Gate *gatePtr = circuit_->LoadGatePtr(gate);
131 switch (op) {
132 case OpCode::LOAD:
133 case OpCode::STORE: {
134 auto accessor = LoadStoreAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
135 return accessor.GetMemoryOrder();
136 }
137 case OpCode::LOAD_CONST_OFFSET:
138 case OpCode::STORE_CONST_OFFSET: {
139 auto accessor = LoadStoreConstOffsetAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
140 return accessor.GetMemoryOrder();
141 }
142 default: {
143 UNREACHABLE();
144 break;
145 }
146 }
147 return MemoryOrder::Default();
148 }
149
HasBranchWeight(GateRef gate) const150 bool GateAccessor::HasBranchWeight(GateRef gate) const
151 {
152 ASSERT(GetOpCode(gate) == OpCode::IF_BRANCH);
153 Gate *gatePtr = circuit_->LoadGatePtr(gate);
154 auto accessor = BranchAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
155 return (accessor.GetTrueWeight() != 0) || (accessor.GetFalseWeight() != 0);
156 }
157
GetIndex(GateRef gate) const158 size_t GateAccessor::GetIndex(GateRef gate) const
159 {
160 ASSERT(GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ_HCLASS ||
161 GetOpCode(gate) == OpCode::GET_GLOBAL_CONSTANT_VALUE ||
162 GetOpCode(gate) == OpCode::GET_GLOBAL_ENV_OBJ ||
163 GetOpCode(gate) == OpCode::LOAD_HCLASS_FROM_CONSTPOOL ||
164 GetOpCode(gate) == OpCode::LOAD_BUILTIN_OBJECT);
165 Gate *gatePtr = circuit_->LoadGatePtr(gate);
166 return gatePtr->GetOneParameterMetaData()->GetValue();
167 }
168
GetJSType(GateRef gate) const169 size_t GateAccessor::GetJSType(GateRef gate) const
170 {
171 ASSERT(GetOpCode(gate) == OpCode::IS_SPECIFIC_OBJECT_TYPE);
172 Gate *gatePtr = circuit_->LoadGatePtr(gate);
173 return gatePtr->GetOneParameterMetaData()->GetValue();
174 }
175
GetArraySize(GateRef gate) const176 uint32_t GateAccessor::GetArraySize(GateRef gate) const
177 {
178 ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
179 GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
180 Gate *gatePtr = circuit_->LoadGatePtr(gate);
181 auto array = gatePtr->GetOneParameterMetaData()->GetValue();
182 return ArrayMetaDataAccessor(array).GetArrayLength();
183 }
184
SetArraySize(GateRef gate,uint32_t size)185 void GateAccessor::SetArraySize(GateRef gate, uint32_t size)
186 {
187 ASSERT(GetOpCode(gate) == OpCode::CREATE_ARRAY ||
188 GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
189 uint32_t curSize = GetArraySize(gate);
190 if (curSize != size) {
191 Gate *gatePtr = circuit_->LoadGatePtr(gate);
192 ArrayMetaDataAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
193 accessor.SetArrayLength(size);
194 if (GetOpCode(gate) == OpCode::CREATE_ARRAY) {
195 auto meta = circuit_->CreateArray(accessor.ToValue());
196 SetMetaData(gate, meta);
197 } else {
198 auto meta = circuit_->CreateArrayWithBuffer(accessor.ToValue());
199 SetMetaData(gate, meta);
200 }
201 }
202 }
203
GetStringStatus(GateRef gate) const204 uint32_t GateAccessor::GetStringStatus(GateRef gate) const
205 {
206 ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
207 Gate *gatePtr = circuit_->LoadGatePtr(gate);
208 StringStatusAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
209 return accessor.GetStringStatus();
210 }
211
SetStringStatus(GateRef gate,uint32_t type)212 void GateAccessor::SetStringStatus(GateRef gate, uint32_t type)
213 {
214 ASSERT(GetOpCode(gate) == OpCode::STRING_ADD);
215 uint32_t curStatus = GetStringStatus(gate);
216 if (curStatus != type) {
217 StringStatusAccessor accessor(static_cast<uint64_t>(type));
218 auto meta = circuit_->StringAdd(accessor.ToValue());
219 SetMetaData(gate, meta);
220 }
221 }
222
GetTypedUnAccessor(GateRef gate) const223 TypedUnaryAccessor GateAccessor::GetTypedUnAccessor(GateRef gate) const
224 {
225 ASSERT((GetOpCode(gate) == OpCode::TYPED_UNARY_OP));
226 Gate *gatePtr = circuit_->LoadGatePtr(gate);
227 return TypedUnaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
228 }
229
GetTypedBinaryAccessor(GateRef gate) const230 TypedBinaryAccessor GateAccessor::GetTypedBinaryAccessor(GateRef gate) const
231 {
232 Gate *gatePtr = circuit_->LoadGatePtr(gate);
233 return TypedBinaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
234 }
235
GetTypedJumpAccessor(GateRef gate) const236 TypedJumpAccessor GateAccessor::GetTypedJumpAccessor(GateRef gate) const
237 {
238 ASSERT(GetOpCode(gate) == OpCode::TYPED_CONDITION_JUMP);
239 Gate *gatePtr = circuit_->LoadGatePtr(gate);
240 return TypedJumpAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
241 }
242
GetArrayMetaDataAccessor(GateRef gate) const243 ArrayMetaDataAccessor GateAccessor::GetArrayMetaDataAccessor(GateRef gate) const
244 {
245 ASSERT(GetOpCode(gate) == OpCode::STABLE_ARRAY_CHECK ||
246 GetOpCode(gate) == OpCode::HCLASS_STABLE_ARRAY_CHECK ||
247 GetOpCode(gate) == OpCode::CREATE_ARRAY ||
248 GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER);
249 Gate *gatePtr = circuit_->LoadGatePtr(gate);
250 return ArrayMetaDataAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
251 }
252
GetObjectTypeAccessor(GateRef gate) const253 ObjectTypeAccessor GateAccessor::GetObjectTypeAccessor(GateRef gate) const
254 {
255 ASSERT(GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK ||
256 GetOpCode(gate) == OpCode::OBJECT_TYPE_COMPARE);
257 Gate *gatePtr = circuit_->LoadGatePtr(gate);
258 return ObjectTypeAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
259 }
260
GetBuiltinHClassAccessor(GateRef gate) const261 BuiltinPrototypeHClassAccessor GateAccessor::GetBuiltinHClassAccessor(GateRef gate) const
262 {
263 ASSERT(GetOpCode(gate) == OpCode::BUILTIN_PROTOTYPE_HCLASS_CHECK);
264 Gate *gatePtr = circuit_->LoadGatePtr(gate);
265 return BuiltinPrototypeHClassAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
266 }
267
GetTypedArrayMetaDateAccessor(GateRef gate) const268 TypedArrayMetaDateAccessor GateAccessor::GetTypedArrayMetaDateAccessor(GateRef gate) const
269 {
270 ASSERT(GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK || GetOpCode(gate) == OpCode::LOAD_TYPED_ARRAY_LENGTH);
271 Gate *gatePtr = circuit_->LoadGatePtr(gate);
272 return TypedArrayMetaDateAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
273 }
274
GetLoadElementAccessor(GateRef gate) const275 LoadElementAccessor GateAccessor::GetLoadElementAccessor(GateRef gate) const
276 {
277 ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
278 Gate *gatePtr = circuit_->LoadGatePtr(gate);
279 return LoadElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
280 }
281
GetStoreElementAccessor(GateRef gate) const282 StoreElementAccessor GateAccessor::GetStoreElementAccessor(GateRef gate) const
283 {
284 ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
285 Gate *gatePtr = circuit_->LoadGatePtr(gate);
286 return StoreElementAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
287 }
288
TypedOpIsTypedArray(GateRef gate,TypedOpKind kind) const289 bool GateAccessor::TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const
290 {
291 switch (kind) {
292 case TypedOpKind::TYPED_LOAD_OP: {
293 TypedLoadOp op = GetTypedLoadOp(gate);
294 return TypedLoadOp::TYPED_ARRAY_FIRST <= op && op <=TypedLoadOp::TYPED_ARRAY_LAST;
295 }
296 case TypedOpKind::TYPED_STORE_OP: {
297 TypedStoreOp op = GetTypedStoreOp(gate);
298 return TypedStoreOp::TYPED_ARRAY_FIRST <= op && op <= TypedStoreOp::TYPED_ARRAY_LAST;
299 }
300 default:
301 LOG_ECMA(FATAL) << "this branch is unreachable";
302 UNREACHABLE();
303 }
304 }
305
GetReceiverType(GateRef gate) const306 GateType GateAccessor::GetReceiverType([[maybe_unused]]GateRef gate) const
307 {
308 return GateType::Empty();
309 }
310
GetHolderType(GateRef gate) const311 GateType GateAccessor::GetHolderType([[maybe_unused]]GateRef gate) const
312 {
313 return GateType::Empty();
314 }
315
GetNewHolderType(GateRef gate) const316 GateType GateAccessor::GetNewHolderType([[maybe_unused]]GateRef gate) const
317 {
318 return GateType::Empty();
319 }
320
GetTypedLoadOp(GateRef gate) const321 TypedLoadOp GateAccessor::GetTypedLoadOp(GateRef gate) const
322 {
323 ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
324 Gate *gatePtr = circuit_->LoadGatePtr(gate);
325 return static_cast<TypedLoadOp>(gatePtr->GetOneParameterMetaData()->GetValue());
326 }
327
GetTypedStoreOp(GateRef gate) const328 TypedStoreOp GateAccessor::GetTypedStoreOp(GateRef gate) const
329 {
330 ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
331 Gate *gatePtr = circuit_->LoadGatePtr(gate);
332 return static_cast<TypedStoreOp>(gatePtr->GetOneParameterMetaData()->GetValue());
333 }
334
GetTypedCallTargetCheckOp(GateRef gate) const335 TypedCallTargetCheckOp GateAccessor::GetTypedCallTargetCheckOp(GateRef gate) const
336 {
337 ASSERT(GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP);
338 Gate *gatePtr = circuit_->LoadGatePtr(gate);
339 return gatePtr->GetTypedCallTargetCheckMetaData()->GetTypedCallTargetCheckOp();
340 }
341
GetMemoryType(GateRef gate) const342 MemoryType GateAccessor::GetMemoryType(GateRef gate) const
343 {
344 ASSERT(GetOpCode(gate) == OpCode::STORE_MEMORY);
345 Gate *gatePtr = circuit_->LoadGatePtr(gate);
346 return static_cast<MemoryType>(gatePtr->GetOneParameterMetaData()->GetValue());
347 }
348
GetHClassIndex(GateRef gate) const349 uint32_t GateAccessor::GetHClassIndex(GateRef gate) const
350 {
351 ASSERT(GetOpCode(gate) == OpCode::STORE_PROPERTY ||
352 GetOpCode(gate) == OpCode::PROTOTYPE_CHECK);
353 Gate *gatePtr = circuit_->LoadGatePtr(gate);
354 return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
355 }
356
GetTypedBinaryOp(GateRef gate) const357 TypedBinOp GateAccessor::GetTypedBinaryOp(GateRef gate) const
358 {
359 ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
360 Gate *gatePtr = circuit_->LoadGatePtr(gate);
361 return gatePtr->GetTypedBinaryMetaData()->GetTypedBinaryOp();
362 }
363
GetTypedBinaryType(GateRef gate) const364 PGOTypeRef GateAccessor::GetTypedBinaryType(GateRef gate) const
365 {
366 ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
367 Gate *gatePtr = circuit_->LoadGatePtr(gate);
368 return gatePtr->GetTypedBinaryMetaData()->GetType();
369 }
370
HasNumberType(GateRef gate) const371 bool GateAccessor::HasNumberType(GateRef gate) const
372 {
373 auto sampleType = GetTypedBinaryType(gate).GetPGOSampleType();
374 if (sampleType->IsNumber()) {
375 return true;
376 }
377 if (sampleType->IsNone()) {
378 GateType leftType = GetLeftType(gate);
379 GateType rightType = GetRightType(gate);
380 if (leftType.IsNumberType() && rightType.IsNumberType()) {
381 return true;
382 }
383 }
384 return false;
385 }
386
HasStringType(GateRef gate) const387 bool GateAccessor::HasStringType(GateRef gate) const
388 {
389 GateType leftType = GetLeftType(gate);
390 GateType rightType = GetRightType(gate);
391 const PGOSampleType *sampleType = TryGetPGOType(gate).GetPGOSampleType();
392 if (sampleType->IsString()) {
393 return true;
394 } else if (sampleType->IsNone() && leftType.IsStringType() && rightType.IsStringType()) {
395 return true;
396 }
397 return false;
398 }
399
400 // Include number, undefined, null and boolean type.
HasPrimitiveNumberType(GateRef gate) const401 bool GateAccessor::HasPrimitiveNumberType(GateRef gate) const
402 {
403 auto sampleType = GetTypedBinaryType(gate).GetPGOSampleType();
404 if (sampleType->IsNumber()) {
405 return true;
406 }
407 if (sampleType->IsNone()) {
408 GateType leftType = GetLeftType(gate);
409 GateType rightType = GetRightType(gate);
410 if (leftType.IsPrimitiveNumberType() && rightType.IsPrimitiveNumberType()) {
411 return true;
412 }
413 }
414 return false;
415 }
416
GetFuncGT(GateRef gate) const417 GlobalTSTypeRef GateAccessor::GetFuncGT(GateRef gate) const
418 {
419 ASSERT(GetOpCode(gate) == OpCode::JSINLINETARGET_TYPE_CHECK);
420 Gate *gatePtr = circuit_->LoadGatePtr(gate);
421 auto value = static_cast<uint32_t>((gatePtr->GetOneParameterMetaData()->GetValue()));
422 return GlobalTSTypeRef(value);
423 }
424
GetParamGateType(GateRef gate) const425 GateType GateAccessor::GetParamGateType(GateRef gate) const
426 {
427 ASSERT(GetOpCode(gate) == OpCode::PRIMITIVE_TYPE_CHECK ||
428 GetOpCode(gate) == OpCode::INDEX_CHECK ||
429 GetOpCode(gate) == OpCode::TYPED_CALLTARGETCHECK_OP ||
430 GetOpCode(gate) == OpCode::CREATE_ARRAY_WITH_BUFFER ||
431 GetOpCode(gate) == OpCode::TYPE_OF_CHECK ||
432 GetOpCode(gate) == OpCode::TYPE_OF);
433 Gate *gatePtr = circuit_->LoadGatePtr(gate);
434 GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
435 return accessor.GetGateType();
436 }
437
IsConvertSupport(GateRef gate) const438 bool GateAccessor::IsConvertSupport(GateRef gate) const
439 {
440 ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
441 GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
442 Gate *gatePtr = circuit_->LoadGatePtr(gate);
443 ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
444 return accessor.IsConvertSupport();
445 }
446
GetSrcType(GateRef gate) const447 ValueType GateAccessor::GetSrcType(GateRef gate) const
448 {
449 ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
450 GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
451 Gate *gatePtr = circuit_->LoadGatePtr(gate);
452 ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
453 return accessor.GetSrcType();
454 }
455
GetDstType(GateRef gate) const456 ValueType GateAccessor::GetDstType(GateRef gate) const
457 {
458 ASSERT(GetOpCode(gate) == OpCode::CONVERT ||
459 GetOpCode(gate) == OpCode::CHECK_AND_CONVERT);
460 Gate *gatePtr = circuit_->LoadGatePtr(gate);
461 ValuePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
462 return accessor.GetDstType();
463 }
464
GetLeftType(GateRef gate) const465 GateType GateAccessor::GetLeftType(GateRef gate) const
466 {
467 ASSERT(GetOpCode(gate) == OpCode::TYPED_UNARY_OP ||
468 GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
469 GetOpCode(gate) == OpCode::TYPE_CONVERT);
470 Gate *gatePtr = circuit_->LoadGatePtr(gate);
471 GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
472 return accessor.GetLeftType();
473 }
474
GetRightType(GateRef gate) const475 GateType GateAccessor::GetRightType(GateRef gate) const
476 {
477 ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
478 GetOpCode(gate) == OpCode::TYPE_CONVERT);
479 Gate *gatePtr = circuit_->LoadGatePtr(gate);
480 GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
481 return accessor.GetRightType();
482 }
483
GetFirstValue(GateRef gate) const484 uint32_t GateAccessor::GetFirstValue(GateRef gate) const
485 {
486 ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
487 Gate *gatePtr = circuit_->LoadGatePtr(gate);
488 UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
489 return accessor.GetFirstValue();
490 }
491
GetSecondValue(GateRef gate) const492 uint32_t GateAccessor::GetSecondValue(GateRef gate) const
493 {
494 ASSERT(GetOpCode(gate) == OpCode::RANGE_GUARD);
495 Gate *gatePtr = circuit_->LoadGatePtr(gate);
496 UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
497 return accessor.GetSecondValue();
498 }
499
GetVirtualRegisterIndex(GateRef gate) const500 size_t GateAccessor::GetVirtualRegisterIndex(GateRef gate) const
501 {
502 ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER ||
503 GetOpCode(gate) == OpCode::RESTORE_REGISTER);
504 Gate *gatePtr = circuit_->LoadGatePtr(gate);
505 return static_cast<size_t>(gatePtr->GetOneParameterMetaData()->GetValue());
506 }
507
GetConstantValue(GateRef gate) const508 uint64_t GateAccessor::GetConstantValue(GateRef gate) const
509 {
510 ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
511 Gate *gatePtr = circuit_->LoadGatePtr(gate);
512 return gatePtr->GetOneParameterMetaData()->GetValue();
513 }
514
GetConstantString(GateRef gate) const515 const ChunkVector<char>& GateAccessor::GetConstantString(GateRef gate) const
516 {
517 ASSERT(GetOpCode(gate) == OpCode::CONSTSTRING);
518 Gate *gatePtr = circuit_->LoadGatePtr(gate);
519 return gatePtr->GetStringMetaData()->GetString();
520 }
521
IsVtable(GateRef gate) const522 bool GateAccessor::IsVtable(GateRef gate) const
523 {
524 ASSERT(GetOpCode(gate) == OpCode::LOAD_PROPERTY);
525 Gate *gatePtr = circuit_->LoadGatePtr(gate);
526 return gatePtr->GetBoolMetaData()->GetBool();
527 }
528
GetNoGCFlag(GateRef gate) const529 bool GateAccessor::GetNoGCFlag(GateRef gate) const
530 {
531 if (gate == Circuit::NullGate()) {
532 return false;
533 }
534 OpCode op = GetOpCode(gate);
535 if (op != OpCode::TYPEDCALL && op != OpCode::TYPEDFASTCALL) {
536 return false;
537 }
538 return TypedCallIsNoGC(gate);
539 }
540
TypedCallIsNoGC(GateRef gate) const541 bool GateAccessor::TypedCallIsNoGC(GateRef gate) const
542 {
543 ASSERT(GetOpCode(gate) == OpCode::TYPEDCALL || GetOpCode(gate) == OpCode::TYPEDFASTCALL);
544 Gate *gatePtr = circuit_->LoadGatePtr(gate);
545 return gatePtr->GetTypedCallMetaData()->IsNoGC();
546 }
547
IsNoGC(GateRef gate) const548 bool GateAccessor::IsNoGC(GateRef gate) const
549 {
550 ASSERT(GetOpCode(gate) == OpCode::CALL_OPTIMIZED || GetOpCode(gate) == OpCode::FAST_CALL_OPTIMIZED);
551 Gate *gatePtr = circuit_->LoadGatePtr(gate);
552 return gatePtr->GetBoolMetaData()->GetBool();
553 }
554
TryGetPcOffset(GateRef gate) const555 uint32_t GateAccessor::TryGetPcOffset(GateRef gate) const
556 {
557 Gate *gatePtr = circuit_->LoadGatePtr(gate);
558 OpCode op = GetOpCode(gate);
559 switch (op) {
560 case OpCode::JS_BYTECODE:
561 return gatePtr->GetJSBytecodeMetaData()->GetPcOffset();
562 case OpCode::TYPED_CALL_BUILTIN:
563 case OpCode::CONSTRUCT:
564 case OpCode::CALL_GETTER:
565 case OpCode::CALL_SETTER:
566 return static_cast<uint32_t>(gatePtr->GetOneParameterMetaData()->GetValue());
567 case OpCode::TYPEDCALL:
568 case OpCode::TYPEDFASTCALL:
569 return static_cast<uint32_t>(gatePtr->GetTypedCallMetaData()->GetValue());
570 case OpCode::FRAME_STATE: {
571 UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
572 return accessor.GetFirstValue();
573 }
574 default:
575 break;
576 }
577 return 0;
578 }
579
TryGetBcIndex(GateRef gate) const580 uint32_t GateAccessor::TryGetBcIndex(GateRef gate) const
581 {
582 Gate *gatePtr = circuit_->LoadGatePtr(gate);
583 OpCode op = GetOpCode(gate);
584 switch (op) {
585 case OpCode::JS_BYTECODE:
586 return gatePtr->GetJSBytecodeMetaData()->GetBcIndex();
587 default:
588 break;
589 }
590 return INVALID_BC_INDEX;
591 }
592
TryGetMethodOffset(GateRef gate) const593 uint32_t GateAccessor::TryGetMethodOffset(GateRef gate) const
594 {
595 Gate *gatePtr = circuit_->LoadGatePtr(gate);
596 OpCode op = GetOpCode(gate);
597 switch (op) {
598 case OpCode::FRAME_ARGS: {
599 UInt32PairAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
600 return accessor.GetFirstValue();
601 }
602 case OpCode::JS_BYTECODE: {
603 return gatePtr->GetJSBytecodeMetaData()->GetMethodId();
604 }
605 default:
606 break;
607 }
608 return 0;
609 }
610
GetFrameArgs(GateRef gate) const611 GateRef GateAccessor::GetFrameArgs(GateRef gate) const
612 {
613 if (!HasFrameState(gate)) {
614 return Circuit::NullGate();
615 }
616 if (GetOpCode(gate) == OpCode::FRAME_STATE) {
617 return GetValueIn(gate, 0); // 0: frame args
618 }
619 GateRef frameState = GetFrameState(gate);
620 OpCode op = GetOpCode(frameState);
621 if (op == OpCode::FRAME_ARGS) {
622 return frameState;
623 }
624 if (op == OpCode::FRAME_STATE) {
625 return GetValueIn(frameState, 0); // 0: frame args
626 }
627 return Circuit::NullGate();
628 }
629
UpdateMethodOffset(GateRef gate,uint32_t methodOffset)630 void GateAccessor::UpdateMethodOffset(GateRef gate, uint32_t methodOffset)
631 {
632 ASSERT(GetOpCode(gate) == OpCode::FRAME_ARGS);
633 Gate *gatePtr = circuit_->LoadGatePtr(gate);
634 UInt32PairAccessor accessor(methodOffset, 0);
635 const_cast<OneParameterMetaData *>(gatePtr->GetOneParameterMetaData())->SetValue(accessor.ToValue());
636 }
637
TryGetPGOType(GateRef gate) const638 PGOTypeRef GateAccessor::TryGetPGOType(GateRef gate) const
639 {
640 Gate *gatePtr = circuit_->LoadGatePtr(gate);
641 OpCode op = GetOpCode(gate);
642 if (op == OpCode::JS_BYTECODE) {
643 return gatePtr->GetJSBytecodeMetaData()->GetType();
644 }
645 if (op == OpCode::TYPED_BINARY_OP) {
646 return GetTypedBinaryType(gate);
647 }
648 return PGOTypeRef::NoneType();
649 }
650
TrySetPGOType(GateRef gate,PGOTypeRef type)651 void GateAccessor::TrySetPGOType(GateRef gate, PGOTypeRef type)
652 {
653 Gate *gatePtr = circuit_->LoadGatePtr(gate);
654 OpCode op = GetOpCode(gate);
655 if (op == OpCode::JS_BYTECODE) {
656 const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetType(type);
657 }
658 }
659
TryGetArrayElementsLength(GateRef gate) const660 uint32_t GateAccessor::TryGetArrayElementsLength(GateRef gate) const
661 {
662 Gate *gatePtr = circuit_->LoadGatePtr(gate);
663 OpCode op = GetOpCode(gate);
664 if (op == OpCode::JS_BYTECODE) {
665 return gatePtr->GetJSBytecodeMetaData()->GetElementsLength();
666 }
667 return 0;
668 }
669
TrySetArrayElementsLength(GateRef gate,uint32_t length)670 void GateAccessor::TrySetArrayElementsLength(GateRef gate, uint32_t length)
671 {
672 Gate *gatePtr = circuit_->LoadGatePtr(gate);
673 OpCode op = GetOpCode(gate);
674 if (op == OpCode::JS_BYTECODE) {
675 const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsLength(length);
676 }
677 }
678
TryGetElementsKind(GateRef gate) const679 ElementsKind GateAccessor::TryGetElementsKind(GateRef gate) const
680 {
681 Gate *gatePtr = circuit_->LoadGatePtr(gate);
682 OpCode op = GetOpCode(gate);
683 if (op == OpCode::JS_BYTECODE) {
684 return Elements::FixElementsKind(gatePtr->GetJSBytecodeMetaData()->GetElementsKind());
685 }
686 return ElementsKind::GENERIC;
687 }
688
TryGetArrayElementsKind(GateRef gate) const689 ElementsKind GateAccessor::TryGetArrayElementsKind(GateRef gate) const
690 {
691 Gate *gatePtr = circuit_->LoadGatePtr(gate);
692 OpCode op = GetOpCode(gate);
693 if (op == OpCode::JS_BYTECODE) {
694 ElementsKind kind = gatePtr->GetJSBytecodeMetaData()->GetElementsKind();
695 if (Elements::IsGeneric(kind)) {
696 return kind;
697 }
698 std::vector<ElementsKind> kinds = gatePtr->GetJSBytecodeMetaData()->GetElementsKinds();
699 for (auto &x : kinds) {
700 kind = Elements::MergeElementsKind(kind, x);
701 }
702 return kind;
703 }
704 return ElementsKind::GENERIC;
705 }
706
TrySetElementsKind(GateRef gate,ElementsKind kind)707 void GateAccessor::TrySetElementsKind(GateRef gate, ElementsKind kind)
708 {
709 Gate *gatePtr = circuit_->LoadGatePtr(gate);
710 OpCode op = GetOpCode(gate);
711 if (op == OpCode::JS_BYTECODE) {
712 const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetElementsKind(kind);
713 }
714 }
715
TrySetOnHeapMode(GateRef gate,OnHeapMode onHeapMode) const716 void GateAccessor::TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const
717 {
718 Gate *gatePtr = circuit_->LoadGatePtr(gate);
719 OpCode op = GetOpCode(gate);
720 if (op == OpCode::JS_BYTECODE) {
721 const_cast<JSBytecodeMetaData *>(gatePtr->GetJSBytecodeMetaData())->SetOnHeapMode(onHeapMode);
722 }
723 }
724
TryGetOnHeapMode(GateRef gate) const725 OnHeapMode GateAccessor::TryGetOnHeapMode(GateRef gate) const
726 {
727 Gate *gatePtr = circuit_->LoadGatePtr(gate);
728 OpCode op = GetOpCode(gate);
729 if (op == OpCode::JS_BYTECODE) {
730 return gatePtr->GetJSBytecodeMetaData()->GetOnHeapMode();
731 }
732 return OnHeapMode::NONE;
733 }
734
GetByteCodeOpcode(GateRef gate) const735 EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
736 {
737 ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
738 Gate *gatePtr = circuit_->LoadGatePtr(gate);
739 return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
740 }
741
Print(GateRef gate) const742 void GateAccessor::Print(GateRef gate) const
743 {
744 Gate *gatePtr = circuit_->LoadGatePtr(gate);
745 gatePtr->Print();
746 }
747
748 #ifndef NDEBUG
PrintById(size_t id) const749 void GateAccessor::PrintById(size_t id) const
750 {
751 GateRef gate = circuit_->GetGateRefById(id);
752 if (gate != Circuit::NullGate()) {
753 Gate *gatePtr = circuit_->LoadGatePtr(gate);
754 gatePtr->PrintWithBytecode();
755 } else {
756 LOG_COMPILER(INFO) << "id overflow!";
757 }
758 }
759 #endif
760
PrintWithBytecode(GateRef gate) const761 void GateAccessor::PrintWithBytecode(GateRef gate) const
762 {
763 Gate *gatePtr = circuit_->LoadGatePtr(gate);
764 gatePtr->PrintWithBytecode();
765 }
766
ShortPrint(GateRef gate) const767 void GateAccessor::ShortPrint(GateRef gate) const
768 {
769 Gate *gatePtr = circuit_->LoadGatePtr(gate);
770 gatePtr->ShortPrint();
771 }
772
GetId(GateRef gate) const773 GateId GateAccessor::GetId(GateRef gate) const
774 {
775 Gate *gatePtr = circuit_->LoadGatePtr(gate);
776 return gatePtr->GetId();
777 }
778
GetInValueStarts(GateRef gate) const779 size_t GateAccessor::GetInValueStarts(GateRef gate) const
780 {
781 Gate *gatePtr = circuit_->LoadGatePtr(gate);
782 return gatePtr->GetInValueStarts();
783 }
784
GetValueIn(GateRef gate,size_t idx) const785 GateRef GateAccessor::GetValueIn(GateRef gate, size_t idx) const
786 {
787 Gate *gatePtr = circuit_->LoadGatePtr(gate);
788 ASSERT(idx < gatePtr->GetInValueCount());
789 size_t valueIndex = gatePtr->GetInValueStarts();
790 return circuit_->GetIn(gate, valueIndex + idx);
791 }
792
GetNumValueIn(GateRef gate) const793 size_t GateAccessor::GetNumValueIn(GateRef gate) const
794 {
795 Gate *gatePtr = circuit_->LoadGatePtr(gate);
796 return gatePtr->GetInValueCount();
797 }
798
IsGCRelated(GateRef gate) const799 bool GateAccessor::IsGCRelated(GateRef gate) const
800 {
801 return GetGateType(gate).IsGCRelated();
802 }
803
GetIn(GateRef gate,size_t idx) const804 GateRef GateAccessor::GetIn(GateRef gate, size_t idx) const
805 {
806 return circuit_->GetIn(gate, idx);
807 }
808
GetState(GateRef gate,size_t idx) const809 GateRef GateAccessor::GetState(GateRef gate, size_t idx) const
810 {
811 ASSERT(idx < circuit_->LoadGatePtr(gate)->GetStateCount());
812 return circuit_->GetIn(gate, idx);
813 }
814
GetInStates(GateRef gate,std::vector<GateRef> & ins) const815 void GateAccessor::GetInStates(GateRef gate, std::vector<GateRef>& ins) const
816 {
817 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
818 for (size_t idx = 0; idx < curGate->GetStateCount(); idx++) {
819 ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
820 }
821 }
822
GetIns(GateRef gate,std::vector<GateRef> & ins) const823 void GateAccessor::GetIns(GateRef gate, std::vector<GateRef>& ins) const
824 {
825 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
826 for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
827 ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
828 }
829 }
830
GetOuts(GateRef gate,std::vector<GateRef> & outs) const831 void GateAccessor::GetOuts(GateRef gate, std::vector<GateRef>& outs) const
832 {
833 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
834 if (!curGate->IsFirstOutNull()) {
835 const Out *curOut = curGate->GetFirstOutConst();
836 GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
837 outs.push_back(ref);
838 while (!curOut->IsNextOutNull()) {
839 curOut = curOut->GetNextOutConst();
840 ref = circuit_->GetGateRef(curOut->GetGateConst());
841 outs.push_back(ref);
842 }
843 }
844 }
845
HasOuts(GateRef gate) const846 bool GateAccessor::HasOuts(GateRef gate) const
847 {
848 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
849 return !curGate->IsFirstOutNull();
850 }
851
DeleteGateIfNoUse(GateRef gate)852 void GateAccessor::DeleteGateIfNoUse(GateRef gate)
853 {
854 if (!HasOuts(gate)) {
855 DeleteGate(gate);
856 }
857 }
858
GetOutStates(GateRef gate,std::vector<GateRef> & outStates) const859 void GateAccessor::GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const
860 {
861 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
862 if (!curGate->IsFirstOutNull()) {
863 const Out *curOut = curGate->GetFirstOutConst();
864 GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
865 if (GetMetaData(ref)->IsState()) {
866 outStates.push_back(ref);
867 }
868 while (!curOut->IsNextOutNull()) {
869 curOut = curOut->GetNextOutConst();
870 ref = circuit_->GetGateRef(curOut->GetGateConst());
871 if (GetMetaData(ref)->IsState()) {
872 outStates.push_back(ref);
873 }
874 }
875 }
876 }
877
GetStateUses(GateRef gate,std::vector<GateRef> & stateUses)878 void GateAccessor::GetStateUses(GateRef gate, std::vector<GateRef> &stateUses)
879 {
880 stateUses.clear();
881 auto uses = Uses(gate);
882 for (auto it = uses.begin(); it != uses.end(); it++) {
883 if (IsStateIn(it)) {
884 stateUses.emplace_back(*it);
885 }
886 }
887 }
888
GetDependUses(GateRef gate,std::vector<GateRef> & dependUses)889 void GateAccessor::GetDependUses(GateRef gate, std::vector<GateRef> &dependUses)
890 {
891 dependUses.clear();
892 auto uses = Uses(gate);
893 for (auto it = uses.begin(); it != uses.end(); it++) {
894 if (IsDependIn(it)) {
895 dependUses.emplace_back(*it);
896 }
897 }
898 }
899
GetValueUses(GateRef gate,std::vector<GateRef> & valueUses)900 void GateAccessor::GetValueUses(GateRef gate, std::vector<GateRef> &valueUses)
901 {
902 valueUses.clear();
903 auto uses = Uses(gate);
904 for (auto it = uses.begin(); it != uses.end(); it++) {
905 if (IsValueIn(it)) {
906 valueUses.emplace_back(*it);
907 }
908 }
909 }
910
GetAllGates(std::vector<GateRef> & gates) const911 void GateAccessor::GetAllGates(std::vector<GateRef>& gates) const
912 {
913 circuit_->GetAllGates(gates);
914 }
915
IsInGateNull(GateRef gate,size_t idx) const916 bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const
917 {
918 return circuit_->IsInGateNull(gate, idx);
919 }
920
IsValueSelector(GateRef g) const921 bool GateAccessor::IsValueSelector(GateRef g) const
922 {
923 return GetOpCode(g) == OpCode::VALUE_SELECTOR;
924 }
925
IsSelector(GateRef g) const926 bool GateAccessor::IsSelector(GateRef g) const
927 {
928 auto op = GetOpCode(g);
929 return (op == OpCode::VALUE_SELECTOR) || (op == OpCode::DEPEND_SELECTOR);
930 }
931
IsFrameValues(GateRef g) const932 bool GateAccessor::IsFrameValues(GateRef g) const
933 {
934 auto op = GetOpCode(g);
935 return op == OpCode::FRAME_VALUES;
936 }
937
IsIn(GateRef g,GateRef in) const938 bool GateAccessor::IsIn(GateRef g, GateRef in) const
939 {
940 size_t n = GetNumIns(g);
941 for (size_t id = 0; id < n; id++) {
942 GateRef i = GetIn(g, id);
943 if (i == in) {
944 return true;
945 }
946 }
947 return false;
948 }
949
IsSimpleState(GateRef g) const950 bool GateAccessor::IsSimpleState(GateRef g) const
951 {
952 auto op = GetOpCode(g);
953 return (op == OpCode::IF_TRUE ||
954 op == OpCode::IF_FALSE ||
955 op == OpCode::SWITCH_CASE ||
956 op == OpCode::DEFAULT_CASE ||
957 op == OpCode::LOOP_BACK ||
958 op == OpCode::MERGE ||
959 op == OpCode::VALUE_SELECTOR ||
960 op == OpCode::DEPEND_SELECTOR ||
961 op == OpCode::DEPEND_RELAY ||
962 op == OpCode::ORDINARY_BLOCK);
963 }
964
IsControlCase(GateRef gate) const965 bool GateAccessor::IsControlCase(GateRef gate) const
966 {
967 return circuit_->IsControlCase(gate);
968 }
969
IsLoopExit(GateRef gate) const970 bool GateAccessor::IsLoopExit(GateRef gate) const
971 {
972 return (GetOpCode(gate) == OpCode::LOOP_EXIT);
973 }
974
IsLoopExitRelated(GateRef gate) const975 bool GateAccessor::IsLoopExitRelated(GateRef gate) const
976 {
977 return (GetOpCode(gate) == OpCode::LOOP_EXIT) ||
978 (GetOpCode(gate) == OpCode::LOOP_EXIT_DEPEND) ||
979 (GetOpCode(gate) == OpCode::LOOP_EXIT_VALUE);
980 }
981
IsLoopHead(GateRef gate) const982 bool GateAccessor::IsLoopHead(GateRef gate) const
983 {
984 return circuit_->IsLoopHead(gate);
985 }
986
IsLoopBack(GateRef gate) const987 bool GateAccessor::IsLoopBack(GateRef gate) const
988 {
989 return GetOpCode(gate) == OpCode::LOOP_BACK;
990 }
991
IsState(GateRef gate) const992 bool GateAccessor::IsState(GateRef gate) const
993 {
994 return GetMetaData(gate)->IsState();
995 }
996
IsConstant(GateRef gate) const997 bool GateAccessor::IsConstant(GateRef gate) const
998 {
999 return GetMetaData(gate)->IsConstant();
1000 }
1001
IsDependSelector(GateRef gate) const1002 bool GateAccessor::IsDependSelector(GateRef gate) const
1003 {
1004 return GetMetaData(gate)->IsDependSelector();
1005 }
1006
IsConstantValue(GateRef gate,uint64_t value) const1007 bool GateAccessor::IsConstantValue(GateRef gate, uint64_t value) const
1008 {
1009 if (GetOpCode(gate) == OpCode::CONSTANT) {
1010 uint64_t bitField = GetConstantValue(gate);
1011 return bitField == value;
1012 }
1013 return false;
1014 }
1015
IsConstantUndefined(GateRef gate) const1016 bool GateAccessor::IsConstantUndefined(GateRef gate) const
1017 {
1018 return IsConstantValue(gate, JSTaggedValue::VALUE_UNDEFINED);
1019 }
1020
IsUndefinedOrNull(GateRef gate) const1021 bool GateAccessor::IsUndefinedOrNull(GateRef gate) const
1022 {
1023 return IsConstantValue(gate, JSTaggedValue::VALUE_UNDEFINED) ||
1024 IsConstantValue(gate, JSTaggedValue::VALUE_NULL);
1025 }
1026
IsTypedOperator(GateRef gate) const1027 bool GateAccessor::IsTypedOperator(GateRef gate) const
1028 {
1029 return GetMetaData(gate)->IsTypedOperator();
1030 }
1031
IsNotWrite(GateRef gate) const1032 bool GateAccessor::IsNotWrite(GateRef gate) const
1033 {
1034 return GetMetaData(gate)->IsNotWrite();
1035 }
1036
IsCheckWithTwoIns(GateRef gate) const1037 bool GateAccessor::IsCheckWithTwoIns(GateRef gate) const
1038 {
1039 return GetMetaData(gate)->IsCheckWithTwoIns();
1040 }
1041
IsCheckWithOneIn(GateRef gate) const1042 bool GateAccessor::IsCheckWithOneIn(GateRef gate) const
1043 {
1044 return GetMetaData(gate)->IsCheckWithOneIn();
1045 }
1046
IsSchedulable(GateRef gate) const1047 bool GateAccessor::IsSchedulable(GateRef gate) const
1048 {
1049 return GetMetaData(gate)->IsSchedulable();
1050 }
1051
IsVirtualState(GateRef gate) const1052 bool GateAccessor::IsVirtualState(GateRef gate) const
1053 {
1054 return GetMetaData(gate)->IsVirtualState();
1055 }
1056
IsGeneralState(GateRef gate) const1057 bool GateAccessor::IsGeneralState(GateRef gate) const
1058 {
1059 return GetMetaData(gate)->IsGeneralState();
1060 }
1061
IsIfOrSwitchRelated(GateRef gate) const1062 bool GateAccessor::IsIfOrSwitchRelated(GateRef gate) const
1063 {
1064 return GetMetaData(gate)->IsIfOrSwitchRelated();
1065 }
1066
GetDep(GateRef gate,size_t idx) const1067 GateRef GateAccessor::GetDep(GateRef gate, size_t idx) const
1068 {
1069 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1070 ASSERT(idx < gatePtr->GetDependCount());
1071 size_t dependIndex = gatePtr->GetStateCount();
1072 return circuit_->GetIn(gate, dependIndex + idx);
1073 }
1074
GetImmediateId(GateRef gate) const1075 size_t GateAccessor::GetImmediateId(GateRef gate) const
1076 {
1077 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1078 ASSERT(gatePtr->GetGateType() == GateType::NJSValue());
1079 ASSERT(gatePtr->GetOpCode() == OpCode::CONSTANT);
1080 ASSERT(gatePtr->GetMachineType() == MachineType::I64);
1081 size_t imm = gatePtr->GetOneParameterMetaData()->GetValue();
1082 return imm;
1083 }
1084
SetDep(GateRef gate,GateRef depGate,size_t idx)1085 void GateAccessor::SetDep(GateRef gate, GateRef depGate, size_t idx)
1086 {
1087 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1088 ASSERT(idx < gatePtr->GetDependCount());
1089 size_t dependIndex = gatePtr->GetStateCount();
1090 gatePtr->ModifyIn(dependIndex + idx, circuit_->LoadGatePtr(depGate));
1091 }
1092
ReplaceIn(const UseIterator & useIt,GateRef replaceGate)1093 UseIterator GateAccessor::ReplaceIn(const UseIterator &useIt, GateRef replaceGate)
1094 {
1095 UseIterator next = useIt;
1096 next++;
1097 Gate *curGatePtr = circuit_->LoadGatePtr(*useIt);
1098 Gate *replaceGatePtr = circuit_->LoadGatePtr(replaceGate);
1099 curGatePtr->ModifyIn(useIt.GetIndex(), replaceGatePtr);
1100 return next;
1101 }
1102
GetGateType(GateRef gate) const1103 GateType GateAccessor::GetGateType(GateRef gate) const
1104 {
1105 return circuit_->LoadGatePtr(gate)->GetGateType();
1106 }
1107
SetGateType(GateRef gate,GateType gt)1108 void GateAccessor::SetGateType(GateRef gate, GateType gt)
1109 {
1110 circuit_->LoadGatePtr(gate)->SetGateType(gt);
1111 }
1112
ReplaceHirIfSuccess(const UseIterator & useIt,GateRef state)1113 UseIterator GateAccessor::ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state)
1114 {
1115 ASSERT(GetOpCode(*useIt) == OpCode::IF_SUCCESS);
1116 auto uses = Uses(*useIt);
1117 for (auto it = uses.begin(); it != uses.end();) {
1118 if (IsStateIn(it)) {
1119 it = ReplaceIn(it, state);
1120 }
1121 }
1122 auto next = DeleteGate(useIt);
1123 return next;
1124 }
1125
ReplaceHirIfException(const UseIterator & useIt,StateDepend replacement)1126 UseIterator GateAccessor::ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement)
1127 {
1128 ASSERT(GetOpCode(*useIt) == OpCode::IF_EXCEPTION);
1129 auto uses = Uses(*useIt);
1130 for (auto it = uses.begin(); it != uses.end();) {
1131 if (IsStateIn(it)) {
1132 it = ReplaceIn(it, replacement.State());
1133 } else if (IsDependIn(it)) {
1134 it = ReplaceIn(it, replacement.Depend());
1135 } else {
1136 ASSERT(!IsValueIn(it));
1137 }
1138 }
1139 UseIterator next = useIt;
1140 next++;
1141 return next;
1142 }
1143
ExceptionReturn(GateRef state,GateRef depend)1144 void GateAccessor::ExceptionReturn(GateRef state, GateRef depend)
1145 {
1146 CircuitBuilder builder(circuit_);
1147 auto constant = builder.ExceptionConstant();
1148 builder.Return(state, depend, constant);
1149 }
1150
ReplaceHirWithIfBranch(GateRef hirGate,StateDepend success,StateDepend exception,GateRef value)1151 void GateAccessor::ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success,
1152 StateDepend exception, GateRef value)
1153 {
1154 auto uses = Uses(hirGate);
1155 GateRef ifException = Circuit::NullGate();
1156 for (auto it = uses.begin(); it != uses.end();) {
1157 if (IsStateIn(it)) {
1158 const OpCode op = GetOpCode(*it);
1159 if (op == OpCode::IF_SUCCESS) {
1160 it = ReplaceHirIfSuccess(it, success.State());
1161 } else if (op == OpCode::IF_EXCEPTION) {
1162 ifException = *it;
1163 it = ReplaceHirIfException(it, exception);
1164 } else if (GetMetaData(*it)->IsVirtualState()) {
1165 it = ReplaceIn(it, success.State());
1166 } else {
1167 ExceptionReturn(exception.State(), exception.Depend());
1168 it = ReplaceIn(it, success.State());
1169 }
1170 } else if (IsDependIn(it)) {
1171 const OpCode op = GetOpCode(*it);
1172 if (op == OpCode::IF_EXCEPTION) {
1173 // ignore it now.
1174 it++;
1175 } else {
1176 it = ReplaceIn(it, success.Depend());
1177 }
1178 } else {
1179 ASSERT(IsValueIn(it));
1180 it = ReplaceIn(it, value);
1181 }
1182 }
1183
1184 if (ifException != Circuit::NullGate()) {
1185 DeleteGate(ifException);
1186 }
1187
1188 // delete old gate
1189 DeleteGate(hirGate);
1190 }
1191
ReplaceHirDirectly(GateRef hirGate,StateDepend replacement,GateRef value)1192 void GateAccessor::ReplaceHirDirectly(GateRef hirGate,
1193 StateDepend replacement, GateRef value)
1194 {
1195 auto uses = Uses(hirGate);
1196 for (auto it = uses.begin(); it != uses.end();) {
1197 if (IsStateIn(it)) {
1198 ASSERT(GetOpCode(*it) != OpCode::IF_SUCCESS &&
1199 GetOpCode(*it) != OpCode::IF_EXCEPTION);
1200 it = ReplaceIn(it, replacement.State());
1201 } else if (IsDependIn(it)) {
1202 it = ReplaceIn(it, replacement.Depend());
1203 } else {
1204 ASSERT(IsValueIn(it));
1205 it = ReplaceIn(it, value);
1206 }
1207 }
1208
1209 // delete old gate
1210 DeleteGate(hirGate);
1211 }
1212
ReplaceHirAndDeleteIfException(GateRef hirGate,StateDepend replacement,GateRef value)1213 void GateAccessor::ReplaceHirAndDeleteIfException(GateRef hirGate,
1214 StateDepend replacement, GateRef value)
1215 {
1216 if (value != Circuit::NullGate()) {
1217 auto type = GetGateType(hirGate);
1218 if (!type.IsAnyType()) {
1219 SetGateType(value, type);
1220 }
1221 }
1222 GateRef ifException = Circuit::NullGate();
1223 auto uses = Uses(hirGate);
1224 for (auto it = uses.begin(); it != uses.end();) {
1225 if (IsStateIn(it)) {
1226 const OpCode op = GetOpCode(*it);
1227 if (op == OpCode::IF_SUCCESS) {
1228 it = ReplaceHirIfSuccess(it, replacement.State());
1229 } else if (op == OpCode::IF_EXCEPTION) {
1230 ifException = *it;
1231 it = ReplaceIn(it, circuit_->DeadGate());
1232 } else {
1233 it = ReplaceIn(it, replacement.State());
1234 }
1235 } else if (IsDependIn(it)) {
1236 const OpCode op = GetOpCode(*it);
1237 if (op == OpCode::IF_EXCEPTION) {
1238 it = ReplaceIn(it, circuit_->DeadGate());
1239 } else {
1240 it = ReplaceIn(it, replacement.Depend());
1241 }
1242 } else {
1243 ASSERT(IsValueIn(it));
1244 it = ReplaceIn(it, value);
1245 }
1246 }
1247
1248 // delete old gate
1249 DeleteGate(hirGate);
1250 if (ifException != Circuit::NullGate()) {
1251 ReplaceGate(ifException, circuit_->DeadGate());
1252 }
1253 }
1254
DeleteGate(const UseIterator & useIt)1255 UseIterator GateAccessor::DeleteGate(const UseIterator &useIt)
1256 {
1257 auto next = useIt;
1258 next++;
1259 circuit_->DeleteGate(*useIt);
1260 return next;
1261 }
1262
DecreaseIn(const UseIterator & useIt)1263 void GateAccessor::DecreaseIn(const UseIterator &useIt)
1264 {
1265 size_t idx = useIt.GetIndex();
1266 circuit_->DecreaseIn(*useIt, idx);
1267 }
1268
DecreaseIn(GateRef gate,size_t index)1269 void GateAccessor::DecreaseIn(GateRef gate, size_t index)
1270 {
1271 circuit_->DecreaseIn(gate, index);
1272 }
1273
NewIn(GateRef gate,size_t idx,GateRef in)1274 void GateAccessor::NewIn(GateRef gate, size_t idx, GateRef in)
1275 {
1276 circuit_->NewIn(gate, idx, in);
1277 }
1278
GetStateCount(GateRef gate) const1279 size_t GateAccessor::GetStateCount(GateRef gate) const
1280 {
1281 return circuit_->LoadGatePtr(gate)->GetStateCount();
1282 }
1283
GetDependCount(GateRef gate) const1284 size_t GateAccessor::GetDependCount(GateRef gate) const
1285 {
1286 return circuit_->LoadGatePtr(gate)->GetDependCount();
1287 }
1288
GetInValueCount(GateRef gate) const1289 size_t GateAccessor::GetInValueCount(GateRef gate) const
1290 {
1291 return circuit_->LoadGatePtr(gate)->GetInValueCount();
1292 }
1293
UpdateAllUses(GateRef oldIn,GateRef newIn)1294 void GateAccessor::UpdateAllUses(GateRef oldIn, GateRef newIn)
1295 {
1296 if (oldIn == newIn) {
1297 return;
1298 }
1299 auto uses = Uses(oldIn);
1300 for (auto useIt = uses.begin(); useIt != uses.end();) {
1301 useIt = ReplaceIn(useIt, newIn);
1302 }
1303 }
1304
ReplaceIn(GateRef gate,size_t index,GateRef in)1305 void GateAccessor::ReplaceIn(GateRef gate, size_t index, GateRef in)
1306 {
1307 circuit_->ModifyIn(gate, index, in);
1308 }
1309
DeleteIn(GateRef gate,size_t idx)1310 void GateAccessor::DeleteIn(GateRef gate, size_t idx)
1311 {
1312 ASSERT(idx < circuit_->LoadGatePtrConst(gate)->GetNumIns());
1313 ASSERT(!circuit_->IsInGateNull(gate, idx));
1314 circuit_->LoadGatePtr(gate)->DeleteIn(idx);
1315 }
1316
ReplaceStateIn(GateRef gate,GateRef in,size_t index)1317 void GateAccessor::ReplaceStateIn(GateRef gate, GateRef in, size_t index)
1318 {
1319 ASSERT(index < GetStateCount(gate));
1320 circuit_->ModifyIn(gate, index, in);
1321 }
1322
ReplaceDependIn(GateRef gate,GateRef in,size_t index)1323 void GateAccessor::ReplaceDependIn(GateRef gate, GateRef in, size_t index)
1324 {
1325 ASSERT(index < GetDependCount(gate));
1326 size_t stateCount = GetStateCount(gate);
1327 circuit_->ModifyIn(gate, stateCount + index, in);
1328 }
1329
ReplaceOrNewDependIn(GateRef gate,GateRef in,size_t index)1330 void GateAccessor::ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index)
1331 {
1332 ASSERT(index < GetDependCount(gate));
1333 size_t stateCount = GetStateCount(gate);
1334 auto depend = GetDep(gate);
1335 if (depend == Circuit::NullGate()) {
1336 circuit_->NewIn(gate, stateCount + index, in);
1337 } else {
1338 circuit_->ModifyIn(gate, stateCount + index, in);
1339 }
1340 }
1341
ReplaceValueIn(GateRef gate,GateRef in,size_t index)1342 void GateAccessor::ReplaceValueIn(GateRef gate, GateRef in, size_t index)
1343 {
1344 ASSERT(index < GetInValueCount(gate));
1345 size_t valueStartIndex = GetInValueStarts(gate);
1346 circuit_->ModifyIn(gate, valueStartIndex + index, in);
1347 }
1348
DeleteGate(GateRef gate)1349 void GateAccessor::DeleteGate(GateRef gate)
1350 {
1351 circuit_->DeleteGate(gate);
1352 }
1353
GetMachineType(GateRef gate) const1354 MachineType GateAccessor::GetMachineType(GateRef gate) const
1355 {
1356 return circuit_->GetMachineType(gate);
1357 }
1358
SetMachineType(GateRef gate,MachineType type)1359 void GateAccessor::SetMachineType(GateRef gate, MachineType type)
1360 {
1361 circuit_->SetMachineType(gate, type);
1362 }
1363
GetConstantGate(MachineType bitValue,BitField bitfield,GateType type) const1364 GateRef GateAccessor::GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const
1365 {
1366 return circuit_->GetConstantGate(bitValue, bitfield, type);
1367 }
1368
GetInitialEnvGate(GateRef jsFunc) const1369 GateRef GateAccessor::GetInitialEnvGate(GateRef jsFunc) const
1370 {
1371 return circuit_->GetInitialEnvGate(jsFunc);
1372 }
1373
IsConstantNumber(GateRef gate) const1374 bool GateAccessor::IsConstantNumber(GateRef gate) const
1375 {
1376 DISALLOW_GARBAGE_COLLECTION;
1377 if (GetGateType(gate).IsNJSValueType() ||
1378 (GetOpCode(gate) != OpCode::CONSTANT)) {
1379 return false;
1380 }
1381 JSTaggedValue value(GetConstantValue(gate));
1382 return value.IsNumber();
1383 }
1384
GetFloat64FromConstant(GateRef gate) const1385 double GateAccessor::GetFloat64FromConstant(GateRef gate) const
1386 {
1387 DISALLOW_GARBAGE_COLLECTION;
1388 ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1389 uint64_t rawValue = GetConstantValue(gate);
1390 if (GetGateType(gate).IsNJSValueType()) {
1391 ASSERT(GetMachineType(gate) == MachineType::F64);
1392 return base::bit_cast<double>(rawValue);
1393 }
1394 JSTaggedValue value(rawValue);
1395 return value.GetDouble();
1396 }
1397
GetInt32FromConstant(GateRef gate) const1398 int GateAccessor::GetInt32FromConstant(GateRef gate) const
1399 {
1400 DISALLOW_GARBAGE_COLLECTION;
1401 ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
1402 uint64_t rawValue = GetConstantValue(gate);
1403 if (GetGateType(gate).IsNJSValueType()) {
1404 ASSERT(GetMachineType(gate) == MachineType::I32);
1405 return static_cast<int>(rawValue);
1406 }
1407 JSTaggedValue value(rawValue);
1408 return value.GetInt();
1409 }
1410
IsStateIn(const UseIterator & useIt) const1411 bool GateAccessor::IsStateIn(const UseIterator &useIt) const
1412 {
1413 size_t stateStartIndex = 0;
1414 size_t stateEndIndex = stateStartIndex + GetStateCount(*useIt);
1415 size_t index = useIt.GetIndex();
1416 return (index >= stateStartIndex && index < stateEndIndex);
1417 }
1418
IsDependIn(const UseIterator & useIt) const1419 bool GateAccessor::IsDependIn(const UseIterator &useIt) const
1420 {
1421 size_t dependStartIndex = GetStateCount(*useIt);
1422 size_t dependEndIndex = dependStartIndex + GetDependCount(*useIt);
1423 size_t index = useIt.GetIndex();
1424 return (index >= dependStartIndex && index < dependEndIndex);
1425 }
1426
IsValueIn(const UseIterator & useIt) const1427 bool GateAccessor::IsValueIn(const UseIterator &useIt) const
1428 {
1429 size_t valueStartIndex = GetInValueStarts(*useIt);
1430 size_t valueEndIndex = valueStartIndex + GetInValueCount(*useIt);
1431 size_t index = useIt.GetIndex();
1432 return (index >= valueStartIndex && index < valueEndIndex);
1433 }
1434
IsFrameStateIn(const UseIterator & useIt) const1435 bool GateAccessor::IsFrameStateIn(const UseIterator &useIt) const
1436 {
1437 size_t index = useIt.GetIndex();
1438 return IsFrameStateIn(*useIt, index);
1439 }
1440
IsStateIn(GateRef gate,size_t index) const1441 bool GateAccessor::IsStateIn(GateRef gate, size_t index) const
1442 {
1443 size_t stateStartIndex = 0;
1444 size_t stateEndIndex = stateStartIndex + GetStateCount(gate);
1445 return (index >= stateStartIndex && index < stateEndIndex);
1446 }
1447
IsDependIn(GateRef gate,size_t index) const1448 bool GateAccessor::IsDependIn(GateRef gate, size_t index) const
1449 {
1450 size_t dependStartIndex = GetStateCount(gate);
1451 size_t dependEndIndex = dependStartIndex + GetDependCount(gate);
1452 return (index >= dependStartIndex && index < dependEndIndex);
1453 }
1454
IsValueIn(GateRef gate,size_t index) const1455 bool GateAccessor::IsValueIn(GateRef gate, size_t index) const
1456 {
1457 size_t valueStartIndex = GetInValueStarts(gate);
1458 size_t valueEndIndex = valueStartIndex + GetInValueCount(gate);
1459 return (index >= valueStartIndex && index < valueEndIndex);
1460 }
1461
IsFrameStateIn(GateRef gate,size_t index) const1462 bool GateAccessor::IsFrameStateIn(GateRef gate, size_t index) const
1463 {
1464 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1465 size_t frameStateStartIndex = gatePtr->GetInFrameStateStarts();
1466 size_t FrameStateEndIndex = frameStateStartIndex + gatePtr->GetInFrameStateCount();
1467 return (index >= frameStateStartIndex && index < FrameStateEndIndex);
1468 }
1469
ReplaceGate(GateRef gate,GateRef state,GateRef depend,GateRef value)1470 void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
1471 {
1472 if (value != Circuit::NullGate()) {
1473 GateType type = GetGateType(gate);
1474 GateType valueType = GetGateType(value);
1475 if (!type.IsAnyType() && !valueType.IsNJSValueType()) {
1476 SetGateType(value, type);
1477 }
1478 }
1479
1480 auto uses = Uses(gate);
1481 for (auto useIt = uses.begin(); useIt != uses.end();) {
1482 if (IsStateIn(useIt)) {
1483 ASSERT(state != Circuit::NullGate());
1484 useIt = ReplaceIn(useIt, state);
1485 } else if (IsDependIn(useIt)) {
1486 ASSERT(depend != Circuit::NullGate());
1487 useIt = ReplaceIn(useIt, depend);
1488 } else if (IsValueIn(useIt)) {
1489 ASSERT(value != Circuit::NullGate());
1490 useIt = ReplaceIn(useIt, value);
1491 } else {
1492 LOG_ECMA(FATAL) << "this branch is unreachable";
1493 UNREACHABLE();
1494 }
1495 }
1496 DeleteGate(gate);
1497 }
1498
ReplaceGate(GateRef gate,GateRef replacement)1499 void GateAccessor::ReplaceGate(GateRef gate, GateRef replacement)
1500 {
1501 GateRef depend = Circuit::NullGate();
1502 if (GetDependCount(gate) > 0) {
1503 ASSERT(GetDependCount(gate) == 1); // 1: one dep
1504 depend = GetDep(gate);
1505 }
1506 GateRef state = Circuit::NullGate();
1507 if (GetStateCount(gate) > 0) {
1508 ASSERT(GetStateCount(gate) == 1); // 1: one state
1509 state = GetState(gate);
1510 }
1511 return ReplaceGate(gate, StateDepend {state, depend}, replacement);
1512 }
1513
ReplaceGate(GateRef gate,StateDepend stateDepend,GateRef replacement)1514 void GateAccessor::ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement)
1515 {
1516 ASSERT(gate != replacement);
1517 auto state = stateDepend.State();
1518 auto depend = stateDepend.Depend();
1519 auto uses = Uses(gate);
1520 for (auto it = uses.begin(); it != uses.end();) {
1521 if (IsStateIn(it)) {
1522 ASSERT(state != Circuit::NullGate());
1523 it = ReplaceIn(it, state);
1524 } else if (IsDependIn(it)) {
1525 ASSERT(depend != Circuit::NullGate());
1526 it = ReplaceIn(it, depend);
1527 } else {
1528 it = ReplaceIn(it, replacement);
1529 }
1530 }
1531 DeleteGate(gate);
1532 }
1533
1534
1535 // When Insert newGate, all the stateIn from state and dependIn from depend can be replaced to newGate
ReplaceInAfterInsert(GateRef state,GateRef depend,GateRef newGate)1536 void GateAccessor::ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate)
1537 {
1538 auto uses = Uses(state);
1539 for (auto useIt = uses.begin(); useIt != uses.end();) {
1540 if (IsStateIn(useIt) && (*useIt != newGate)) {
1541 ASSERT(newGate != Circuit::NullGate());
1542 // Exception, for example, IF_TRUE / IF_FALSE -> DEPEND_RELAY,
1543 // or LOOP_BEGIN / MERGE -> DEPEND_SELECTOR cannot be replaced
1544 if (!IsState(*useIt)) {
1545 useIt++;
1546 continue;
1547 }
1548 useIt = ReplaceIn(useIt, newGate);
1549 } else {
1550 useIt++;
1551 }
1552 }
1553
1554 uses = Uses(depend);
1555 for (auto useIt = uses.begin(); useIt != uses.end();) {
1556 if (IsDependIn(useIt) && (*useIt != newGate)) {
1557 ASSERT(newGate != Circuit::NullGate());
1558 useIt = ReplaceIn(useIt, newGate);
1559 } else {
1560 useIt++;
1561 }
1562 }
1563 }
1564
1565 // When loopExit, find stateSplit after DEPEND_SELECTOR
GetFrameStateDependIn(GateRef gate,GateRef & dependIn)1566 void GateAccessor::GetFrameStateDependIn(GateRef gate, GateRef &dependIn)
1567 {
1568 auto uses = Uses(gate);
1569 size_t stateSplitCount = 0;
1570 GateRef stateSplit = Circuit::NullGate();
1571 for (auto it = uses.begin(); it != uses.end();) {
1572 if (GetOpCode(*it) == OpCode::STATE_SPLIT) {
1573 ASSERT(stateSplitCount < 1); // only one state Split;
1574 stateSplitCount++;
1575 stateSplit = *it;
1576 break;
1577 } else {
1578 ++it;
1579 }
1580 }
1581
1582 ASSERT(stateSplitCount <= 1);
1583 if (stateSplitCount == 1 && stateSplit != Circuit::NullGate()) {
1584 dependIn = stateSplit;
1585 }
1586 }
1587
1588 // When ifOp or loopExit, insertAfter
1589 // stateIn: IF_TRUE / IF_FALSE / MERGE
1590 // dependIn: DEPEND_RELAY / DEPEND_SELECTOR, if stateSplit follow closely, after the stateSplit.
1591
GetStateInAndDependIn(GateRef insertAfter,GateRef & stateIn,GateRef & dependIn)1592 void GateAccessor::GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn)
1593 {
1594 if (GetOpCode(insertAfter) == OpCode::IF_TRUE || GetOpCode(insertAfter) == OpCode::IF_FALSE) {
1595 auto uses = Uses(insertAfter);
1596 for (auto it = uses.begin(); it != uses.end();) {
1597 if (GetOpCode(*it) == OpCode::DEPEND_RELAY) {
1598 stateIn = insertAfter;
1599 dependIn = (*it);
1600 break;
1601 } else {
1602 ++it;
1603 }
1604 }
1605 } else if (GetOpCode(insertAfter) == OpCode::MERGE) {
1606 auto uses = Uses(insertAfter);
1607 for (auto it = uses.begin(); it != uses.end();) {
1608 if (GetOpCode(*it) == OpCode::DEPEND_SELECTOR) {
1609 stateIn = insertAfter;
1610 dependIn = (*it);
1611 GetFrameStateDependIn(*it, dependIn);
1612 break;
1613 } else {
1614 ++it;
1615 }
1616 }
1617 }
1618 ASSERT(GetDependCount(dependIn) > 0);
1619 }
1620
GetFrameDepth(GateRef gate,OpCode op)1621 size_t GateAccessor::GetFrameDepth(GateRef gate, OpCode op)
1622 {
1623 if (GetOpCode(gate) != op) {
1624 return 0;
1625 }
1626 size_t depth = 0;
1627 GateRef prev = GetFrameState(gate);
1628 while ((GetOpCode(prev) == op)) {
1629 depth++;
1630 prev = GetFrameState(prev);
1631 }
1632 return depth;
1633 }
1634
GetFrameState(GateRef gate) const1635 GateRef GateAccessor::GetFrameState(GateRef gate) const
1636 {
1637 ASSERT(HasFrameState(gate));
1638 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1639 size_t index = gatePtr->GetInFrameStateStarts();
1640 return circuit_->GetIn(gate, index);
1641 }
1642
FindNearestFrameState(GateRef gate) const1643 GateRef GateAccessor::FindNearestFrameState(GateRef gate) const
1644 {
1645 auto statesplit = FindNearestStateSplit(gate);
1646 return GetFrameState(statesplit);
1647 }
1648
FindNearestStateSplit(GateRef gate) const1649 GateRef GateAccessor::FindNearestStateSplit(GateRef gate) const
1650 {
1651 auto statesplit = gate;
1652 while (GetOpCode(statesplit) != OpCode::STATE_SPLIT) {
1653 statesplit = GetDep(statesplit);
1654 }
1655 return statesplit;
1656 }
1657
HasFrameState(GateRef gate) const1658 bool GateAccessor::HasFrameState(GateRef gate) const
1659 {
1660 return GetMetaData(gate)->HasFrameState();
1661 }
1662
ReplaceFrameStateIn(GateRef gate,GateRef in)1663 void GateAccessor::ReplaceFrameStateIn(GateRef gate, GateRef in)
1664 {
1665 ASSERT(HasFrameState(gate));
1666 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1667 size_t index = gatePtr->GetInFrameStateStarts();
1668 circuit_->ModifyIn(gate, index, in);
1669 }
1670
GetRoot(OpCode opcode) const1671 GateRef GateAccessor::GetRoot(OpCode opcode) const
1672 {
1673 GateRef root = circuit_->GetRoot();
1674 if (opcode == OpCode::CIRCUIT_ROOT) {
1675 return root;
1676 }
1677
1678 auto uses = ConstUses(root);
1679 for (auto useIt = uses.begin(); useIt != uses.end(); ++useIt) {
1680 if (GetOpCode(*useIt) == opcode) {
1681 return *useIt;
1682 }
1683 }
1684 return Circuit::NullGate();
1685 }
1686
GetGlueFromArgList() const1687 GateRef GateAccessor::GetGlueFromArgList() const
1688 {
1689 auto argRoot = GetArgRoot();
1690 ASSERT(static_cast<size_t>(CommonArgIdx::GLUE) == 0);
1691 const Gate *curGate = circuit_->LoadGatePtrConst(argRoot);
1692
1693 const Out *curOut = curGate->GetFirstOutConst();
1694 ASSERT(!curGate->IsFirstOutNull());
1695 while (!curOut->IsNextOutNull()) {
1696 curOut = curOut->GetNextOutConst();
1697 }
1698 return circuit_->GetGateRef(curOut->GetGateConst());
1699 }
1700
GetArgsOuts(std::vector<GateRef> & outs) const1701 void GateAccessor::GetArgsOuts(std::vector<GateRef>& outs) const
1702 {
1703 auto argRoot = GetArgRoot();
1704 GetOuts(argRoot, outs);
1705 }
1706
GetReturnOuts(std::vector<GateRef> & outs) const1707 void GateAccessor::GetReturnOuts(std::vector<GateRef>& outs) const
1708 {
1709 auto returnRoot = GetReturnRoot();
1710 GetOuts(returnRoot, outs);
1711 }
1712
GetMetaData(GateRef gate) const1713 const GateMetaData *GateAccessor::GetMetaData(GateRef gate) const
1714 {
1715 return circuit_->LoadGatePtrConst(gate)->GetMetaData();
1716 }
1717
SetMetaData(GateRef gate,const GateMetaData * meta)1718 void GateAccessor::SetMetaData(GateRef gate, const GateMetaData* meta)
1719 {
1720 return circuit_->LoadGatePtr(gate)->SetMetaData(meta);
1721 }
1722
IsFixed(GateRef g) const1723 bool GateAccessor::IsFixed(GateRef g) const
1724 {
1725 return GetMetaData(g)->IsFixed();
1726 }
1727
IsProlog(GateRef g) const1728 bool GateAccessor::IsProlog(GateRef g) const
1729 {
1730 return GetMetaData(g)->IsProlog();
1731 }
1732
IsCFGMerge(GateRef g) const1733 bool GateAccessor::IsCFGMerge(GateRef g) const
1734 {
1735 return GetMetaData(g)->IsCFGMerge();
1736 }
1737
MetaDataEqu(GateRef g1,GateRef g2) const1738 bool GateAccessor::MetaDataEqu(GateRef g1, GateRef g2) const
1739 {
1740 return GetMetaData(g1) == GetMetaData(g2);
1741 }
1742
MetaDataValueEqu(GateRef g1,GateRef g2) const1743 bool GateAccessor::MetaDataValueEqu(GateRef g1, GateRef g2) const
1744 {
1745 const GateMetaData *g1Meta = GetMetaData(g1);
1746 const GateMetaData *g2Meta = GetMetaData(g2);
1747
1748 return g1Meta->equal(*g2Meta);
1749 }
1750
IsNop(GateRef g) const1751 bool GateAccessor::IsNop(GateRef g) const
1752 {
1753 return GetMetaData(g)->IsNop();
1754 }
1755
IsDead(GateRef gate) const1756 bool GateAccessor::IsDead(GateRef gate) const
1757 {
1758 return GetMetaData(gate)->IsDead();
1759 }
1760
IsRoot(GateRef g) const1761 bool GateAccessor::IsRoot(GateRef g) const
1762 {
1763 return GetMetaData(g)->IsRoot();
1764 }
1765
GetMetaData(GateRef g) const1766 const GateMetaData *ConstGateAccessor::GetMetaData(GateRef g) const
1767 {
1768 return circuit_->LoadGatePtrConst(g)->GetMetaData();
1769 }
1770
IsFixed(GateRef g) const1771 bool ConstGateAccessor::IsFixed(GateRef g) const
1772 {
1773 return GetMetaData(g)->IsFixed();
1774 }
1775
IsProlog(GateRef g) const1776 bool ConstGateAccessor::IsProlog(GateRef g) const
1777 {
1778 return GetMetaData(g)->IsProlog();
1779 }
1780
IsSchedulable(GateRef g) const1781 bool ConstGateAccessor::IsSchedulable(GateRef g) const
1782 {
1783 return GetMetaData(g)->IsSchedulable();
1784 }
1785
GetDependSelectorFromMerge(GateRef gate)1786 GateRef GateAccessor::GetDependSelectorFromMerge(GateRef gate)
1787 {
1788 GateRef depend = Circuit::NullGate();
1789 auto uses = Uses(gate);
1790 for (auto useIt = uses.begin(); useIt != uses.end(); useIt++) {
1791 if (GetOpCode(*useIt) == OpCode::DEPEND_SELECTOR) {
1792 depend = *useIt;
1793 break;
1794 }
1795 }
1796 ASSERT(depend != Circuit::NullGate());
1797 return depend;
1798 }
1799
HasIfExceptionUse(GateRef gate) const1800 bool GateAccessor::HasIfExceptionUse(GateRef gate) const
1801 {
1802 ASSERT(GetStateCount(gate) > 0);
1803 auto uses = ConstUses(gate);
1804 for (auto it = uses.begin(); it != uses.end(); it++) {
1805 if (GetOpCode(*it) == OpCode::IF_EXCEPTION) {
1806 return true;
1807 }
1808 }
1809 return false;
1810 }
1811
IsHeapObjectFromElementsKind(GateRef gate)1812 bool GateAccessor::IsHeapObjectFromElementsKind(GateRef gate)
1813 {
1814 OpCode opcode = GetOpCode(gate);
1815 if (opcode == OpCode::JS_BYTECODE) {
1816 auto bc = GetByteCodeOpcode(gate);
1817 if (bc == EcmaOpcode::LDOBJBYVALUE_IMM8_V8 || bc == EcmaOpcode::LDOBJBYVALUE_IMM16_V8 ||
1818 bc == EcmaOpcode::LDTHISBYVALUE_IMM8 || bc == EcmaOpcode::LDTHISBYVALUE_IMM16) {
1819 ElementsKind kind = TryGetElementsKind(gate);
1820 return Elements::IsObject(kind);
1821 }
1822 return false;
1823 }
1824
1825 if (opcode == OpCode::LOAD_ELEMENT) {
1826 TypedLoadOp typedOp = GetTypedLoadOp(gate);
1827 return typedOp == TypedLoadOp::ARRAY_LOAD_OBJECT_ELEMENT;
1828 }
1829
1830 return false;
1831 }
1832
IsConstString(GateRef gate)1833 bool GateAccessor::IsConstString(GateRef gate)
1834 {
1835 OpCode op = GetOpCode(gate);
1836 if (op == OpCode::JS_BYTECODE) {
1837 EcmaOpcode ecmaOpcode = GetByteCodeOpcode(gate);
1838 return ecmaOpcode == EcmaOpcode::LDA_STR_ID16;
1839 }
1840 return false;
1841 }
1842
IsSingleCharGate(GateRef gate)1843 bool GateAccessor::IsSingleCharGate(GateRef gate)
1844 {
1845 OpCode op = GetOpCode(gate);
1846 if (op == OpCode::LOAD_ELEMENT) {
1847 return GetTypedLoadOp(gate) == TypedLoadOp::STRING_LOAD_ELEMENT;
1848 }
1849 return false;
1850 }
1851
GetStringIdFromLdaStrGate(GateRef gate)1852 uint32_t GateAccessor::GetStringIdFromLdaStrGate(GateRef gate)
1853 {
1854 ASSERT(GetByteCodeOpcode(gate) == EcmaOpcode::LDA_STR_ID16);
1855 GateRef stringId = GetValueIn(gate, 0);
1856 return GetConstantValue(stringId);
1857 }
1858
IsLoopBackUse(GateRef gate,const UseIterator & useIt) const1859 bool GateAccessor::IsLoopBackUse(GateRef gate, const UseIterator &useIt) const
1860 {
1861 if (IsLoopBack(gate) && IsStateIn(useIt)) {
1862 return IsLoopHead(*useIt);
1863 }
1864 if ((IsValueSelector(*useIt) && IsValueIn(useIt)) ||
1865 (IsDependSelector(*useIt) && IsDependIn(useIt))) {
1866 return IsLoopHead(GetState(*useIt));
1867 }
1868 return false;
1869 }
1870
IsCreateArray(GateRef gate) const1871 bool GateAccessor::IsCreateArray(GateRef gate) const
1872 {
1873 if (GetOpCode(gate) != OpCode::JS_BYTECODE) {
1874 return false;
1875 }
1876 EcmaOpcode ecmaop = GetByteCodeOpcode(gate);
1877 switch (ecmaop) {
1878 case EcmaOpcode::CREATEEMPTYARRAY_IMM8:
1879 case EcmaOpcode::CREATEEMPTYARRAY_IMM16:
1880 case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
1881 case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
1882 return true;
1883 default:
1884 return false;
1885 }
1886 UNREACHABLE();
1887 return false;
1888 }
1889
SetStoreNoBarrier(GateRef gate,bool isNoBarrier)1890 void GateAccessor::SetStoreNoBarrier(GateRef gate, bool isNoBarrier)
1891 {
1892 ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
1893 GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
1894 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1895 const_cast<BoolMetaData *>(gatePtr->GetBoolMetaData())->SetBool(isNoBarrier);
1896 }
1897
IsNoBarrier(GateRef gate) const1898 bool GateAccessor::IsNoBarrier(GateRef gate) const
1899 {
1900 ASSERT(GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY_LOOK_UP_PROTO ||
1901 GetOpCode(gate) == OpCode::MONO_STORE_PROPERTY);
1902 Gate *gatePtr = circuit_->LoadGatePtr(gate);
1903 return gatePtr->GetBoolMetaData()->GetBool();
1904 }
1905 } // namespace panda::ecmascript::kungfu
1906