• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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