• 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 #ifndef ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
17 #define ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
18 
19 #include "ecmascript/compiler/circuit.h"
20 #include "ecmascript/compiler/mcr_gate_meta_data.h"
21 #include "ecmascript/elements.h"
22 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
23 
24 namespace panda::ecmascript::kungfu {
25 
26 class StateDepend {
27 public:
StateDepend()28     StateDepend()
29         : state_(Circuit::NullGate()), depend_(Circuit::NullGate()) {}
30 
StateDepend(GateRef state,GateRef depend)31     explicit StateDepend(GateRef state, GateRef depend)
32         : state_(state), depend_(depend) {}
33 
State()34     GateRef State() const
35     {
36         return state_;
37     }
38 
Depend()39     GateRef Depend() const
40     {
41         return depend_;
42     }
43 
SetState(GateRef state)44     void SetState(GateRef state)
45     {
46         state_ = state;
47     }
48 
SetDepend(GateRef depend)49     void SetDepend(GateRef depend)
50     {
51         depend_ = depend;
52     }
53 
Reset()54     void Reset()
55     {
56         state_ = Circuit::NullGate();
57         depend_ = Circuit::NullGate();
58     }
59 
60 private:
61     GateRef state_;
62     GateRef depend_;
63 };
64 
65 class Edge {
66 public:
Edge(GateRef gate,size_t index)67     explicit Edge(GateRef gate, size_t index) : gate_(gate), index_(static_cast<uint32_t>(index)) {}
68 
GetGate()69     GateRef GetGate() const
70     {
71         return gate_;
72     }
73 
GetIndex()74     size_t GetIndex() const
75     {
76         return static_cast<size_t>(index_);
77     }
78 
SetIndex(size_t index)79     void SetIndex(size_t index)
80     {
81         index_ = static_cast<uint32_t>(index);
82     }
83 
84 private:
85     GateRef gate_;
86     uint32_t index_;
87 };
88 
89 class GateAccessor {
90 public:
91     constexpr static uint32_t INVALID_BC_INDEX = 0;
92 
93     // do not create new gate or modify self during iteration
94     struct ConstUseIterator {
ConstUseIteratorConstUseIterator95         ConstUseIterator(const Circuit* circuit, const Out* out) : circuit_(circuit), out_(out)
96         {
97         }
98 
99         GateRef operator*() const
100         {
101             if (out_ != nullptr) {
102                 return circuit_->GetGateRef(out_->GetGateConst());
103             }
104             return 0;
105         }
106 
107         const ConstUseIterator operator++()
108         {
109             ASSERT(out_ != nullptr);
110             if (!out_->IsNextOutNull()) {
111                 out_ = out_->GetNextOutConst();
112                 return *this;
113             }
114             out_ = nullptr;
115             return *this;
116         }
117         const ConstUseIterator operator++(int)
118         {
119             ConstUseIterator tmp = *this;
120             ++(*this);
121             return tmp;
122         }
123 
GetIndexConstUseIterator124         size_t GetIndex() const
125         {
126             ASSERT(out_ != nullptr);
127             return out_->GetIndex();
128         }
129 
GetOpCodeConstUseIterator130         OpCode GetOpCode() const
131         {
132             ASSERT(out_ != nullptr);
133             return out_->GetGateConst()->GetOpCode();
134         }
135 
136         friend bool operator == (const ConstUseIterator& a, const ConstUseIterator& b)
137         {
138             return a.out_ == b.out_;
139         };
140         friend bool operator != (const ConstUseIterator& a, const ConstUseIterator& b)
141         {
142             return a.out_ != b.out_;
143         };
144 
145     private:
146         const Circuit* circuit_;
147         const Out* out_;
148     };
149 
150     // do not create new gate or modify self during iteration
151     struct UseIterator {
UseIteratorUseIterator152         UseIterator(Circuit* circuit, Out* out) : circuit_(circuit), out_(out)
153         {
154         }
155 
156         GateRef operator*() const
157         {
158             if (out_ != nullptr) {
159                 return circuit_->GetGateRef(out_->GetGate());
160             }
161             return 0;
162         }
163 
164         const UseIterator& operator++()
165         {
166             ASSERT(out_ != nullptr);
167             out_ = out_->IsNextOutNull() ? nullptr
168                                          : out_->GetNextOut();
169             return *this;
170         }
171 
172         UseIterator operator++(int)
173         {
174             UseIterator tmp = *this;
175             ++(*this);
176             return tmp;
177         }
178 
GetIndexUseIterator179         size_t GetIndex() const
180         {
181             ASSERT(out_ != nullptr);
182             return out_->GetIndex();
183         }
184 
GetEdgeUseIterator185         Edge GetEdge()
186         {
187             ASSERT(out_ != nullptr);
188             UseIterator it = *this;
189             return Edge(*it, GetIndex());
190         }
191 
GetOpCodeUseIterator192         OpCode GetOpCode() const
193         {
194             ASSERT(out_ != nullptr);
195             return out_->GetGateConst()->GetOpCode();
196         }
197 
198         friend bool operator == (const UseIterator& a, const UseIterator& b)
199         {
200             return a.out_ == b.out_;
201         };
202         friend bool operator != (const UseIterator& a, const UseIterator& b)
203         {
204             return a.out_ != b.out_;
205         };
206 
207     private:
208         Circuit* circuit_;
209         Out* out_;
210     };
211 
212     struct ConstInsIterator {
ConstInsIteratorConstInsIterator213         ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
214         {
215         }
216 
217         GateRef operator*() const
218         {
219             return circuit_->GetGateRef(in_->GetGateConst());
220         }
221 
222         const ConstInsIterator& operator++()
223         {
224             in_++;
225             return *this;
226         }
227         ConstInsIterator operator++(int)
228         {
229             ConstInsIterator tmp = *this;
230             ++(*this);
231             return tmp;
232         }
233 
GetOpCodeConstInsIterator234         OpCode GetOpCode() const
235         {
236             ASSERT(in_ != nullptr);
237             return in_->GetGateConst()->GetOpCode();
238         }
239 
240         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
241         {
242             return a.in_ == b.in_;
243         };
244         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
245         {
246             return a.in_ != b.in_;
247         };
248 
249     private:
250         const Circuit* circuit_;
251         const In* in_;
252     };
253 
254     struct InsIterator {
InsIteratorInsIterator255         InsIterator(const Circuit* circuit, In* in) : circuit_(circuit), in_(in)
256         {
257         }
258 
259         GateRef operator*()
260         {
261             return circuit_->GetGateRef(in_->GetGate());
262         }
263 
264         const InsIterator& operator++()
265         {
266             in_++;
267             return *this;
268         }
269         InsIterator operator++(int)
270         {
271             InsIterator tmp = *this;
272             ++(*this);
273             return tmp;
274         }
275 
GetOpCodeInsIterator276         OpCode GetOpCode() const
277         {
278             ASSERT(in_ != nullptr);
279             return in_->GetGateConst()->GetOpCode();
280         }
281 
282         friend bool operator== (const InsIterator& a, const InsIterator& b)
283         {
284             return a.in_ == b.in_;
285         };
286         friend bool operator!= (const InsIterator& a, const InsIterator& b)
287         {
288             return a.in_ != b.in_;
289         };
290 
291     private:
292         const Circuit* circuit_;
293         In* in_;
294     };
295 
296     struct ConstUseWrapper {
297         Circuit* circuit;
298         GateRef gate;
beginConstUseWrapper299         auto begin()
300         {
301             return GateAccessor(circuit).ConstUseBegin(gate);
302         }
endConstUseWrapper303         auto end()
304         {
305             return GateAccessor(circuit).ConstUseEnd();
306         }
307     };
308 
309     struct UseWrapper {
310         Circuit* circuit;
311         GateRef gate;
beginUseWrapper312         auto begin()
313         {
314             return GateAccessor(circuit).UseBegin(gate);
315         }
endUseWrapper316         auto end()
317         {
318             return GateAccessor(circuit).UseEnd();
319         }
320     };
321 
322     struct ConstInWrapper {
323         Circuit* circuit;
324         const GateRef gate;
beginConstInWrapper325         auto begin()
326         {
327             return GateAccessor(circuit).ConstInBegin(gate);
328         }
endConstInWrapper329         auto end()
330         {
331             return GateAccessor(circuit).ConstInEnd(gate);
332         }
333     };
334 
335     struct InWrapper {
336         Circuit* circuit;
337         GateRef gate;
beginInWrapper338         auto begin()
339         {
340             return GateAccessor(circuit).InBegin(gate);
341         }
endInWrapper342         auto end()
343         {
344             return GateAccessor(circuit).InEnd(gate);
345         }
346     };
347 
ConstIns(GateRef gate)348     ConstInWrapper ConstIns(GateRef gate) const
349     {
350         return { circuit_, gate };
351     }
352 
Ins(GateRef gate)353     InWrapper Ins(GateRef gate) const
354     {
355         return { circuit_, gate };
356     }
357 
ConstUses(GateRef gate)358     ConstUseWrapper ConstUses(GateRef gate) const
359     {
360         return { circuit_, gate };
361     }
362 
Uses(GateRef gate)363     UseWrapper Uses(GateRef gate)
364     {
365         return { circuit_, gate };
366     }
367 
GateAccessor(Circuit * circuit)368     explicit GateAccessor(Circuit *circuit) : circuit_(circuit)
369     {
370     }
371 
GetCircuit()372     Circuit *GetCircuit() const
373     {
374         return circuit_;
375     }
376 
377     ~GateAccessor() = default;
378     void GetAllGates(std::vector<GateRef>& gates) const;
379     size_t GetNumIns(GateRef gate) const;
380     OpCode GetOpCode(GateRef gate) const;
381     bool IsGCRelated(GateRef gate) const;
382     uint64_t TryGetValue(GateRef gate) const;
383     ICmpCondition GetICmpCondition(GateRef gate) const;
384     FCmpCondition GetFCmpCondition(GateRef gate) const;
385     size_t GetOffset(GateRef gate) const;
386     size_t GetInitOffset(GateRef gate) const;
387     uint32_t GetTrueWeight(GateRef gate) const;
388     uint32_t GetFalseWeight(GateRef gate) const;
389     bool HasBranchWeight(GateRef gate) const;
390     MemoryAttribute GetMemoryAttribute(GateRef gate) const;
391     size_t GetIndex(GateRef gate) const;
392     size_t GetJSType(GateRef gate) const;
393     uint32_t GetArraySize(GateRef gate) const;
394     void SetArraySize(GateRef gate, uint32_t size);
395     uint32_t GetStringStatus(GateRef gate) const;
396     void SetStringStatus(GateRef gate, uint32_t type);
397     ElementsKind GetElementsKind(GateRef gate) const;
398     void SetElementsKind(GateRef gate, ElementsKind kind);
399     RegionSpaceFlag GetRegionSpaceFlag(GateRef gate) const;
400     size_t GetVirtualRegisterIndex(GateRef gate) const;
401     bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const;
402     TypedLoadOp GetTypedLoadOp(GateRef gate) const;
403     TypedStoreOp GetTypedStoreOp(GateRef gate) const;
404     MemoryType GetMemoryType(GateRef gate) const;
405     uint32_t GetHClassIndex(GateRef gate) const;
406     TypedBinOp GetTypedBinaryOp(GateRef gate) const;
407     TypedCallTargetCheckOp GetTypedCallTargetCheckOp(GateRef gate) const;
408     bool HasNumberType(GateRef gate) const;
409     bool HasStringType(GateRef gate, bool onlyInternString = false) const;
410     bool IsInternStringType(GateRef gate) const;
411     GlobalTSTypeRef GetFuncGT(GateRef gate) const;
412     GateType GetParamGateType(GateRef gate) const;
413     ParamType GetParamType(GateRef gate) const;
414     TypedUnaryAccessor GetTypedUnAccessor(GateRef gate) const;
415     TypedBinaryAccessor GetTypedBinaryAccessor(GateRef gate) const;
416     TypedJumpAccessor GetTypedJumpAccessor(GateRef gate) const;
417     ArrayMetaDataAccessor GetArrayMetaDataAccessor(GateRef gate) const;
418     CreateArgumentsAccessor GetCreateArgumentsAccessor(GateRef gate) const;
419     ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const;
420     BuiltinPrototypeHClassAccessor GetBuiltinHClassAccessor(GateRef gate) const;
421     TypedArrayMetaDataAccessor GetTypedArrayMetaDataAccessor(GateRef gate) const;
422     LoadElementAccessor GetLoadElementAccessor(GateRef gate) const;
423     StoreElementAccessor GetStoreElementAccessor(GateRef gate) const;
424     bool NeedPushArgv(GateRef gate) const;
425     uint64_t GetConstantValue(GateRef gate) const;
426     const ChunkVector<char>& GetConstantString(GateRef gate) const;
427     bool IsVtable(GateRef gate) const;
428     bool GetNoGCFlag(GateRef gate) const;
429     bool TypedCallIsNoGC(GateRef gate) const;
430     bool IsNoGC(GateRef gate) const;
431     uint32_t TryGetPcOffset(GateRef gate) const;
432     uint32_t TryGetBcIndex(GateRef gate) const;
433     uint32_t TryGetMethodOffset(GateRef gate) const;
434     GateRef GetFrameArgs(GateRef gate) const;
435     void UpdateMethodOffset(GateRef gate, uint32_t methodOffset);
436     PGOTypeRef TryGetPGOType(GateRef gate) const;
437     void TrySetPGOType(GateRef gate, PGOTypeRef type);
438     uint32_t TryGetArrayElementsLength(GateRef gate) const;
439     void TrySetArrayElementsLength(GateRef gate, uint32_t length);
440     RegionSpaceFlag TryGetRegionSpaceFlag(GateRef gate) const;
441     void TrySetRegionSpaceFlag(GateRef gate, RegionSpaceFlag length);
442     ElementsKind TryGetElementsKind(GateRef gate) const;
443     ElementsKind TryGetArrayElementsKind(GateRef gate) const;
444     ElementsKind TryGetArrayElementsKindAfterTransition(GateRef gate) const;
445     void TrySetElementsKind(GateRef gate, ElementsKind kind);
446     void TrySetTransitionElementsKind(GateRef gate, ElementsKind kind);
447     void TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const;
448     OnHeapMode TryGetOnHeapMode(GateRef gate) const;
449     EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
450     void Print(GateRef gate) const DUMP_API_ATTR;
451     std::string ToString(GateRef gate) const DUMP_API_ATTR;
452 #ifndef NDEBUG
453     void PrintById(size_t id) const DUMP_API_ATTR ;
454 #endif
455     void PrintWithBytecode(GateRef gate) const DUMP_API_ATTR;
456     void ShortPrint(GateRef gate) const;
457     GateId GetId(GateRef gate) const;
458     GateRef GetValueIn(GateRef gate, size_t idx = 0) const;
459     size_t GetNumValueIn(GateRef gate) const;
460     std::vector<GateRef> GetValueIns(GateRef gate) const;
461     GateRef GetIn(GateRef gate, size_t idx) const;
462     GateRef GetState(GateRef gate, size_t idx = 0) const;
463     GateRef GetDep(GateRef gate, size_t idx = 0) const;
464     size_t GetImmediateId(GateRef gate) const;
465     void SetDep(GateRef gate, GateRef depGate, size_t idx = 0);
466     UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate);
467     // Add for lowering
468     GateType GetGateType(GateRef gate) const;
469     bool IsConvertSupport(GateRef gate) const;
470     ValueType GetSrcType(GateRef gate) const;
471     ValueType GetDstType(GateRef gate) const;
472     void SetGateType(GateRef gate, GateType gt);
473     void DeleteIn(GateRef gate, size_t idx);
474     UseIterator DeleteGate(const UseIterator &useIt);
475     void DecreaseIn(const UseIterator &useIt);
476     void DecreaseIn(GateRef gate, size_t index);
477     void NewIn(GateRef gate, size_t idx, GateRef in);
478     size_t GetStateCount(GateRef gate) const;
479     size_t GetDependCount(GateRef gate) const;
480     size_t GetInValueCount(GateRef gate) const;
481     size_t GetInValueStarts(GateRef gate) const;
482     void UpdateAllUses(GateRef gate, GateRef replaceValueIn);
483     void ReplaceControlGate(GateRef gate, GateRef newState);
484     void ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate);
485     void GetFrameStateDependIn(GateRef gate, GateRef &dependIn);
486     void GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn);
487     void ReplaceIn(GateRef gate, size_t index, GateRef in);
488     void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0);
489     void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0);
490     void ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index = 0);
491     void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0);
492     void DeleteGate(GateRef gate);
493     MachineType GetMachineType(GateRef gate) const;
494     void SetMachineType(GateRef gate, MachineType type);
495     GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const;
496     GateRef GetInitialEnvGate(GateRef depend, GateRef jsFunc) const;
497     double GetFloat64FromConstant(GateRef gate) const;
498     int GetInt32FromConstant(GateRef gate) const;
499     bool IsInGateNull(GateRef gate, size_t idx) const;
500     bool IsSelector(GateRef g) const;
501     bool IsSimpleState(GateRef g) const;
502     bool IsValueSelector(GateRef g) const;
503     bool IsFrameValues(GateRef g) const;
504     bool IsControlCase(GateRef gate) const;
505     bool IsLoopExit(GateRef gate) const;
506     bool IsLoopExitRelated(GateRef gate) const;
507     bool IsLoopHead(GateRef gate) const;
508     bool IsLoopBack(GateRef gate) const;
509     bool IsState(GateRef gate) const;
510     bool IsConstant(GateRef gate) const;
511     bool IsDependSelector(GateRef gate) const;
512     bool IsConstantValue(GateRef gate, uint64_t value) const;
513     bool IsConstantTaggedValue(GateRef gate, uint64_t value) const;
514     bool IsConstantUndefined(GateRef gate) const;
515     bool IsUndefinedOrNullOrHole(GateRef gate) const;
516     bool IsConstantNumber(GateRef gate) const;
517     bool IsTypedOperator(GateRef gate) const;
518     bool IsNotWrite(GateRef gate) const;
519     bool IsDead(GateRef gate) const;
520     bool IsCheckWithOneIn(GateRef gate) const;
521     bool IsCheckWithTwoIns(GateRef gate) const;
522     bool IsSchedulable(GateRef gate) const;
523     bool IsVirtualState(GateRef gate) const;
524     bool IsGeneralState(GateRef gate) const;
525     MarkCode GetMark(GateRef gate) const;
526     void SetMark(GateRef gate, MarkCode mark);
527     bool IsFinished(GateRef gate) const;
528     bool IsVisited(GateRef gate) const;
529     bool IsPrevisit(GateRef gate) const;
530     bool IsNotMarked(GateRef gate) const;
531     void SetFinished(GateRef gate);
532     void SetPrevisit(GateRef gate);
533     void SetVisited(GateRef gate);
534     bool IsStateIn(const UseIterator &useIt) const;
535     bool IsDependIn(const UseIterator &useIt) const;
536     bool IsValueIn(const UseIterator &useIt) const;
537     bool IsFrameStateIn(const UseIterator &useIt) const;
538     bool IsStateIn(GateRef gate, size_t index) const;
539     bool IsDependIn(GateRef gate, size_t index) const;
540     bool IsValueIn(GateRef gate, size_t index) const;
541     void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses);
542     void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses);
543     void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses);
544     size_t GetValueUsesCount(GateRef gate);
545     bool IsFrameStateIn(GateRef gate, size_t index) const;
546     void EliminateRedundantPhi();
547     void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
548     void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement);
549     void ReplaceGate(GateRef gate, GateRef replacement);
550     uint32_t GetFirstValue(GateRef gate) const;
551     uint32_t GetSecondValue(GateRef gate) const;
552     GateRef GetGlueFromArgList() const;
553     void GetArgsOuts(std::vector<GateRef>& outs) const;
554     void GetReturnOuts(std::vector<GateRef>& outs) const;
555     bool IsFixed(GateRef g) const;
556     bool IsProlog(GateRef g) const;
557     bool IsCFGMerge(GateRef g) const;
558     bool MetaDataEqu(GateRef g1, GateRef g2) const;
559     bool MetaDataValueEqu(GateRef g1, GateRef g2) const;
560     bool IsNop(GateRef g) const;
561     bool IsRoot(GateRef g) const;
562     bool HasOuts(GateRef gate) const;
563     void DeleteGateIfNoUse(GateRef gate);
564     GateRef GetDependSelectorFromMerge(GateRef gate);
565     bool HasIfExceptionUse(GateRef gate) const;
566     bool IsIn(GateRef g, GateRef in) const;
567     bool IsHeapObjectFromElementsKind(GateRef gate);
568     bool IsConstString(GateRef gate);
569     bool IsSingleCharGate(GateRef gate);
570     bool UseForTypeOpProfilerGate(GateRef gate) const;
571     uint32_t GetStringIdFromLdaStrGate(GateRef gate);
572     bool IsIfOrSwitchRelated(GateRef gate) const;
573     uint32_t GetConstpoolId(GateRef gate) const;
574     GateRef GetFrameValue(GateRef gate);
575 
GetCircuitRoot()576     GateRef GetCircuitRoot() const
577     {
578         return GetRoot(OpCode::CIRCUIT_ROOT);
579     }
580 
GetStateRoot()581     GateRef GetStateRoot() const
582     {
583         return GetRoot(OpCode::STATE_ENTRY);
584     }
585 
GetDependRoot()586     GateRef GetDependRoot() const
587     {
588         return GetRoot(OpCode::DEPEND_ENTRY);
589     }
590 
GetArgRoot()591     GateRef GetArgRoot() const
592     {
593         return GetRoot(OpCode::ARG_LIST);
594     }
595 
GetReturnRoot()596     GateRef GetReturnRoot() const
597     {
598         return GetRoot(OpCode::RETURN_LIST);
599     }
600 
IsStateRoot(GateRef gate)601     inline bool IsStateRoot(GateRef gate) const
602     {
603         return gate == GetStateRoot();
604     }
605 
606     size_t GetFrameDepth(GateRef gate, OpCode op);
607     GateRef GetFrameState(GateRef gate) const;
608     void ReplaceFrameStateIn(GateRef gate, GateRef in);
609     bool HasFrameState(GateRef gate) const;
610     GateRef FindNearestFrameState(GateRef gate) const;
611     GateRef FindNearestStateSplit(GateRef gate) const;
612     void SetMetaData(GateRef gate, const GateMetaData* meta);
613 
614     void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value);
615     void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value);
616     void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value);
617 
618     bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const;
619     void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const;
620     bool IsCreateArray(GateRef gate) const;
621     void SetStoreNoBarrier(GateRef gate, bool isNoBarrier);
622     bool IsNoBarrier(GateRef gate) const;
623     void GetIns(GateRef gate, std::vector<GateRef>& ins) const;
624 
625     bool TryGetMegaProp(GateRef gate) const;
626     TypedBinOp GetRevCompareOpForTypedBinOp(TypedBinOp op);
627     TypedBinOp GetSwapCompareOpForTypedBinOp(TypedBinOp op);
628     void UpdateOnHeapMode(GateRef gate, OnHeapMode onHeapMode);
629 
630 private:
631     const GateMetaData *GetMetaData(GateRef gate) const;
632     UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state);
633     UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement);
634     void ExceptionReturn(GateRef state, GateRef depend);
635 
636     GateRef GetRoot(OpCode opcode) const;
ConstUseBegin(GateRef gate)637     ConstUseIterator ConstUseBegin(GateRef gate) const
638     {
639         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
640             return ConstUseIterator(circuit_, nullptr);
641         }
642         auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst();
643         return ConstUseIterator(circuit_, use);
644     }
645 
ConstUseEnd()646     ConstUseIterator ConstUseEnd() const
647     {
648         return ConstUseIterator(circuit_, nullptr);
649     }
650 
UseBegin(GateRef gate)651     UseIterator UseBegin(GateRef gate) const
652     {
653         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
654             return UseIterator(circuit_, nullptr);
655         }
656         auto use = circuit_->LoadGatePtr(gate)->GetFirstOut();
657         return UseIterator(circuit_, use);
658     }
659 
UseEnd()660     UseIterator UseEnd() const
661     {
662         return UseIterator(circuit_, nullptr);
663     }
664 
ConstInBegin(GateRef gate)665     ConstInsIterator ConstInBegin(GateRef gate) const
666     {
667         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
668     }
669 
ConstInEnd(GateRef gate)670     ConstInsIterator ConstInEnd(GateRef gate) const
671     {
672         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
673         return ConstInsIterator(circuit_,
674                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
675     }
676 
InBegin(GateRef gate)677     InsIterator InBegin(GateRef gate)
678     {
679         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]);
680     }
681 
InEnd(GateRef gate)682     InsIterator InEnd(GateRef gate)
683     {
684         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
685         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]);
686     }
687 
688     void GetOuts(GateRef gate, std::vector<GateRef>& outs) const;
689 
690     void GetInStates(GateRef gate, std::vector<GateRef>& ins) const;
691 
692     Circuit *circuit_;
693 
694     friend class Circuit;
695     friend class CircuitBuilder;
696     friend class LLVMIRBuilder;
697     friend class LiteCGIRBuilder;
698     friend class Scheduler;
699     friend class LoopPeeling;
700 };
701 
702 class ConstGateAccessor {
703 public:
704     struct ConstInsIterator {
ConstInsIteratorConstInsIterator705         ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
706         {
707         }
708 
709         GateRef operator*() const
710         {
711             return circuit_->GetGateRef(in_->GetGateConst());
712         }
713 
714         const ConstInsIterator& operator++()
715         {
716             in_++;
717             return *this;
718         }
719         ConstInsIterator operator++(int)
720         {
721             ConstInsIterator tmp = *this;
722             ++(*this);
723             return tmp;
724         }
725 
GetOpCodeConstInsIterator726         OpCode GetOpCode() const
727         {
728             ASSERT(in_ != nullptr);
729             return in_->GetGateConst()->GetOpCode();
730         }
731 
732         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
733         {
734             return a.in_ == b.in_;
735         };
736         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
737         {
738             return a.in_ != b.in_;
739         };
740 
741     private:
742         const Circuit* circuit_;
743         const In* in_;
744     };
745 
746     struct ConstInWrapper {
747         const Circuit* circuit;
748         const GateRef gate;
beginConstInWrapper749         auto begin()
750         {
751             return ConstGateAccessor(circuit).ConstInBegin(gate);
752         }
endConstInWrapper753         auto end()
754         {
755             return ConstGateAccessor(circuit).ConstInEnd(gate);
756         }
757     };
758 
Ins(GateRef gate)759     ConstInWrapper Ins(GateRef gate) const
760     {
761         return { circuit_, gate };
762     }
763 
ConstGateAccessor(const Circuit * circuit)764     explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit)
765     {
766     }
767 
768     ~ConstGateAccessor() = default;
769 
770     bool IsFixed(GateRef g) const;
771     bool IsProlog(GateRef g) const;
772     bool IsSchedulable(GateRef g) const;
773 
774 private:
ConstInBegin(GateRef gate)775     ConstInsIterator ConstInBegin(GateRef gate) const
776     {
777         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
778     }
779 
ConstInEnd(GateRef gate)780     ConstInsIterator ConstInEnd(GateRef gate) const
781     {
782         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
783         return ConstInsIterator(circuit_,
784                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
785     }
786     const GateMetaData *GetMetaData(GateRef g) const;
787 
788     const Circuit *circuit_;
789     friend struct ConstInWrapper;
790 };
791 }
792 #endif  // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
793