• 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     uint32_t GetTrueWeight(GateRef gate) const;
387     uint32_t GetFalseWeight(GateRef gate) const;
388     bool HasBranchWeight(GateRef gate) const;
389     MemoryOrder GetMemoryOrder(GateRef gate) const;
390     size_t GetIndex(GateRef gate) const;
391     size_t GetJSType(GateRef gate) const;
392     uint32_t GetArraySize(GateRef gate) const;
393     void SetArraySize(GateRef gate, uint32_t size);
394     uint32_t GetStringStatus(GateRef gate) const;
395     void SetStringStatus(GateRef gate, uint32_t type);
396     size_t GetVirtualRegisterIndex(GateRef gate) const;
397     bool TypedOpIsTypedArray(GateRef gate, TypedOpKind kind) const;
398     GateType GetReceiverType(GateRef gate) const;
399     GateType GetHolderType(GateRef gate) const;
400     GateType GetNewHolderType(GateRef gate) const;
401     TypedLoadOp GetTypedLoadOp(GateRef gate) const;
402     TypedStoreOp GetTypedStoreOp(GateRef gate) const;
403     MemoryType GetMemoryType(GateRef gate) const;
404     uint32_t GetHClassIndex(GateRef gate) const;
405     TypedBinOp GetTypedBinaryOp(GateRef gate) const;
406     TypedCallTargetCheckOp GetTypedCallTargetCheckOp(GateRef gate) const;
407     PGOTypeRef GetTypedBinaryType(GateRef gate) const;
408     bool HasPrimitiveNumberType(GateRef gate) const;
409     bool HasNumberType(GateRef gate) const;
410     bool HasStringType(GateRef gate) const;
411     GlobalTSTypeRef GetFuncGT(GateRef gate) const;
412     GateType GetParamGateType(GateRef gate) const;
413     TypedUnaryAccessor GetTypedUnAccessor(GateRef gate) const;
414     TypedBinaryAccessor GetTypedBinaryAccessor(GateRef gate) const;
415     TypedJumpAccessor GetTypedJumpAccessor(GateRef gate) const;
416     ArrayMetaDataAccessor GetArrayMetaDataAccessor(GateRef gate) const;
417     ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const;
418     BuiltinPrototypeHClassAccessor GetBuiltinHClassAccessor(GateRef gate) const;
419     TypedArrayMetaDateAccessor GetTypedArrayMetaDateAccessor(GateRef gate) const;
420     LoadElementAccessor GetLoadElementAccessor(GateRef gate) const;
421     StoreElementAccessor GetStoreElementAccessor(GateRef gate) const;
422     uint64_t GetConstantValue(GateRef gate) const;
423     const ChunkVector<char>& GetConstantString(GateRef gate) const;
424     bool IsVtable(GateRef gate) const;
425     bool GetNoGCFlag(GateRef gate) const;
426     bool TypedCallIsNoGC(GateRef gate) const;
427     bool IsNoGC(GateRef gate) const;
428     uint32_t TryGetPcOffset(GateRef gate) const;
429     uint32_t TryGetBcIndex(GateRef gate) const;
430     uint32_t TryGetMethodOffset(GateRef gate) const;
431     GateRef GetFrameArgs(GateRef gate) const;
432     void UpdateMethodOffset(GateRef gate, uint32_t methodOffset);
433     PGOTypeRef TryGetPGOType(GateRef gate) const;
434     void TrySetPGOType(GateRef gate, PGOTypeRef type);
435     uint32_t TryGetArrayElementsLength(GateRef gate) const;
436     void TrySetArrayElementsLength(GateRef gate, uint32_t length);
437     ElementsKind TryGetElementsKind(GateRef gate) const;
438     ElementsKind TryGetArrayElementsKind(GateRef gate) const;
439     void TrySetElementsKind(GateRef gate, ElementsKind kind);
440     void TrySetOnHeapMode(GateRef gate, OnHeapMode onHeapMode) const;
441     OnHeapMode TryGetOnHeapMode(GateRef gate) const;
442     EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
443     void Print(GateRef gate) const DUMP_API_ATTR;
444 #ifndef NDEBUG
445     void PrintById(size_t id) const DUMP_API_ATTR ;
446 #endif
447     void PrintWithBytecode(GateRef gate) const DUMP_API_ATTR;
448     void ShortPrint(GateRef gate) const;
449     GateId GetId(GateRef gate) const;
450     GateRef GetValueIn(GateRef gate, size_t idx = 0) const;
451     size_t GetNumValueIn(GateRef gate) const;
452     GateRef GetIn(GateRef gate, size_t idx) const;
453     GateRef GetState(GateRef gate, size_t idx = 0) const;
454     GateRef GetDep(GateRef gate, size_t idx = 0) const;
455     size_t GetImmediateId(GateRef gate) const;
456     void SetDep(GateRef gate, GateRef depGate, size_t idx = 0);
457     UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate);
458     // Add for lowering
459     GateType GetGateType(GateRef gate) const;
460     bool IsConvertSupport(GateRef gate) const;
461     ValueType GetSrcType(GateRef gate) const;
462     ValueType GetDstType(GateRef gate) const;
463     void SetGateType(GateRef gate, GateType gt);
464     void DeleteIn(GateRef gate, size_t idx);
465     UseIterator DeleteGate(const UseIterator &useIt);
466     void DecreaseIn(const UseIterator &useIt);
467     void DecreaseIn(GateRef gate, size_t index);
468     void NewIn(GateRef gate, size_t idx, GateRef in);
469     size_t GetStateCount(GateRef gate) const;
470     size_t GetDependCount(GateRef gate) const;
471     size_t GetInValueCount(GateRef gate) const;
472     size_t GetInValueStarts(GateRef gate) const;
473     void UpdateAllUses(GateRef gate, GateRef replaceValueIn);
474     void ReplaceInAfterInsert(GateRef state, GateRef depend, GateRef newGate);
475     void GetFrameStateDependIn(GateRef gate, GateRef &dependIn);
476     void GetStateInAndDependIn(GateRef insertAfter, GateRef &stateIn, GateRef &dependIn);
477     void ReplaceIn(GateRef gate, size_t index, GateRef in);
478     void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0);
479     void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0);
480     void ReplaceOrNewDependIn(GateRef gate, GateRef in, size_t index = 0);
481     void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0);
482     void DeleteGate(GateRef gate);
483     MachineType GetMachineType(GateRef gate) const;
484     void SetMachineType(GateRef gate, MachineType type);
485     GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const;
486     GateRef GetInitialEnvGate(GateRef jsFunc) const;
487     double GetFloat64FromConstant(GateRef gate) const;
488     int GetInt32FromConstant(GateRef gate) const;
489     bool IsInGateNull(GateRef gate, size_t idx) const;
490     bool IsSelector(GateRef g) const;
491     bool IsSimpleState(GateRef g) const;
492     bool IsValueSelector(GateRef g) const;
493     bool IsFrameValues(GateRef g) const;
494     bool IsControlCase(GateRef gate) const;
495     bool IsLoopExit(GateRef gate) const;
496     bool IsLoopExitRelated(GateRef gate) const;
497     bool IsLoopHead(GateRef gate) const;
498     bool IsLoopBack(GateRef gate) const;
499     bool IsState(GateRef gate) const;
500     bool IsConstant(GateRef gate) const;
501     bool IsDependSelector(GateRef gate) const;
502     bool IsConstantValue(GateRef gate, uint64_t value) const;
503     bool IsConstantUndefined(GateRef gate) const;
504     bool IsUndefinedOrNull(GateRef gate) const;
505     bool IsConstantNumber(GateRef gate) const;
506     bool IsTypedOperator(GateRef gate) const;
507     bool IsNotWrite(GateRef gate) const;
508     bool IsDead(GateRef gate) const;
509     bool IsCheckWithOneIn(GateRef gate) const;
510     bool IsCheckWithTwoIns(GateRef gate) const;
511     bool IsSchedulable(GateRef gate) const;
512     bool IsVirtualState(GateRef gate) const;
513     bool IsGeneralState(GateRef gate) const;
514     MarkCode GetMark(GateRef gate) const;
515     void SetMark(GateRef gate, MarkCode mark);
516     bool IsFinished(GateRef gate) const;
517     bool IsVisited(GateRef gate) const;
518     bool IsPrevisit(GateRef gate) const;
519     bool IsNotMarked(GateRef gate) const;
520     void SetFinished(GateRef gate);
521     void SetPrevisit(GateRef gate);
522     void SetVisited(GateRef gate);
523     bool IsStateIn(const UseIterator &useIt) const;
524     bool IsDependIn(const UseIterator &useIt) const;
525     bool IsValueIn(const UseIterator &useIt) const;
526     bool IsFrameStateIn(const UseIterator &useIt) const;
527     bool IsStateIn(GateRef gate, size_t index) const;
528     bool IsDependIn(GateRef gate, size_t index) const;
529     bool IsValueIn(GateRef gate, size_t index) const;
530     void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses);
531     void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses);
532     void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses);
533     bool IsFrameStateIn(GateRef gate, size_t index) const;
534     void EliminateRedundantPhi();
535     void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
536     void ReplaceGate(GateRef gate, StateDepend stateDepend, GateRef replacement);
537     void ReplaceGate(GateRef gate, GateRef replacement);
538     GateType GetLeftType(GateRef gate) const;
539     GateType GetRightType(GateRef gate) const;
540     uint32_t GetFirstValue(GateRef gate) const;
541     uint32_t GetSecondValue(GateRef gate) const;
542     GateRef GetGlueFromArgList() const;
543     void GetArgsOuts(std::vector<GateRef>& outs) const;
544     void GetReturnOuts(std::vector<GateRef>& outs) const;
545     bool IsFixed(GateRef g) const;
546     bool IsProlog(GateRef g) const;
547     bool IsCFGMerge(GateRef g) const;
548     bool MetaDataEqu(GateRef g1, GateRef g2) const;
549     bool MetaDataValueEqu(GateRef g1, GateRef g2) const;
550     bool IsNop(GateRef g) const;
551     bool IsRoot(GateRef g) const;
552     bool HasOuts(GateRef gate) const;
553     void DeleteGateIfNoUse(GateRef gate);
554     GateRef GetDependSelectorFromMerge(GateRef gate);
555     bool HasIfExceptionUse(GateRef gate) const;
556     bool IsIn(GateRef g, GateRef in) const;
557     bool IsHeapObjectFromElementsKind(GateRef gate);
558     bool IsConstString(GateRef gate);
559     bool IsSingleCharGate(GateRef gate);
560     uint32_t GetStringIdFromLdaStrGate(GateRef gate);
561     bool IsIfOrSwitchRelated(GateRef gate) const;
562 
GetCircuitRoot()563     GateRef GetCircuitRoot() const
564     {
565         return GetRoot(OpCode::CIRCUIT_ROOT);
566     }
567 
GetStateRoot()568     GateRef GetStateRoot() const
569     {
570         return GetRoot(OpCode::STATE_ENTRY);
571     }
572 
GetDependRoot()573     GateRef GetDependRoot() const
574     {
575         return GetRoot(OpCode::DEPEND_ENTRY);
576     }
577 
GetArgRoot()578     GateRef GetArgRoot() const
579     {
580         return GetRoot(OpCode::ARG_LIST);
581     }
582 
GetReturnRoot()583     GateRef GetReturnRoot() const
584     {
585         return GetRoot(OpCode::RETURN_LIST);
586     }
587 
IsStateRoot(GateRef gate)588     inline bool IsStateRoot(GateRef gate) const
589     {
590         return gate == GetStateRoot();
591     }
592 
593     size_t GetFrameDepth(GateRef gate, OpCode op);
594     GateRef GetFrameState(GateRef gate) const;
595     void ReplaceFrameStateIn(GateRef gate, GateRef in);
596     bool HasFrameState(GateRef gate) const;
597     GateRef FindNearestFrameState(GateRef gate) const;
598     GateRef FindNearestStateSplit(GateRef gate) const;
599     void SetMetaData(GateRef gate, const GateMetaData* meta);
600 
601     void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value);
602     void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value);
603     void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value);
604 
605     bool IsLoopBackUse(GateRef gate, const UseIterator &useIt) const;
606     void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const;
607     bool IsCreateArray(GateRef gate) const;
608     void SetStoreNoBarrier(GateRef gate, bool isNoBarrier);
609     bool IsNoBarrier(GateRef gate) const;
610 
611 private:
612     const GateMetaData *GetMetaData(GateRef gate) const;
613     UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state);
614     UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement);
615     void ExceptionReturn(GateRef state, GateRef depend);
616 
617     GateRef GetRoot(OpCode opcode) const;
ConstUseBegin(GateRef gate)618     ConstUseIterator ConstUseBegin(GateRef gate) const
619     {
620         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
621             return ConstUseIterator(circuit_, nullptr);
622         }
623         auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst();
624         return ConstUseIterator(circuit_, use);
625     }
626 
ConstUseEnd()627     ConstUseIterator ConstUseEnd() const
628     {
629         return ConstUseIterator(circuit_, nullptr);
630     }
631 
UseBegin(GateRef gate)632     UseIterator UseBegin(GateRef gate) const
633     {
634         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
635             return UseIterator(circuit_, nullptr);
636         }
637         auto use = circuit_->LoadGatePtr(gate)->GetFirstOut();
638         return UseIterator(circuit_, use);
639     }
640 
UseEnd()641     UseIterator UseEnd() const
642     {
643         return UseIterator(circuit_, nullptr);
644     }
645 
ConstInBegin(GateRef gate)646     ConstInsIterator ConstInBegin(GateRef gate) const
647     {
648         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
649     }
650 
ConstInEnd(GateRef gate)651     ConstInsIterator ConstInEnd(GateRef gate) const
652     {
653         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
654         return ConstInsIterator(circuit_,
655                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
656     }
657 
InBegin(GateRef gate)658     InsIterator InBegin(GateRef gate)
659     {
660         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]);
661     }
662 
InEnd(GateRef gate)663     InsIterator InEnd(GateRef gate)
664     {
665         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
666         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]);
667     }
668 
669     void GetIns(GateRef gate, std::vector<GateRef>& ins) const;
670 
671     void GetOuts(GateRef gate, std::vector<GateRef>& outs) const;
672 
673     void GetInStates(GateRef gate, std::vector<GateRef>& ins) const;
674 
675     Circuit *circuit_;
676 
677     friend class Circuit;
678     friend class LLVMIRBuilder;
679     friend class LiteCGIRBuilder;
680     friend class Scheduler;
681     friend class LoopPeeling;
682 };
683 
684 class ConstGateAccessor {
685 public:
686     struct ConstInsIterator {
ConstInsIteratorConstInsIterator687         ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
688         {
689         }
690 
691         GateRef operator*() const
692         {
693             return circuit_->GetGateRef(in_->GetGateConst());
694         }
695 
696         const ConstInsIterator& operator++()
697         {
698             in_++;
699             return *this;
700         }
701         ConstInsIterator operator++(int)
702         {
703             ConstInsIterator tmp = *this;
704             ++(*this);
705             return tmp;
706         }
707 
GetOpCodeConstInsIterator708         OpCode GetOpCode() const
709         {
710             ASSERT(in_ != nullptr);
711             return in_->GetGateConst()->GetOpCode();
712         }
713 
714         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
715         {
716             return a.in_ == b.in_;
717         };
718         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
719         {
720             return a.in_ != b.in_;
721         };
722 
723     private:
724         const Circuit* circuit_;
725         const In* in_;
726     };
727 
728     struct ConstInWrapper {
729         const Circuit* circuit;
730         const GateRef gate;
beginConstInWrapper731         auto begin()
732         {
733             return ConstGateAccessor(circuit).ConstInBegin(gate);
734         }
endConstInWrapper735         auto end()
736         {
737             return ConstGateAccessor(circuit).ConstInEnd(gate);
738         }
739     };
740 
Ins(GateRef gate)741     ConstInWrapper Ins(GateRef gate) const
742     {
743         return { circuit_, gate };
744     }
745 
ConstGateAccessor(const Circuit * circuit)746     explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit)
747     {
748     }
749 
750     ~ConstGateAccessor() = default;
751 
752     bool IsFixed(GateRef g) const;
753     bool IsProlog(GateRef g) const;
754     bool IsSchedulable(GateRef g) const;
755 
756 private:
ConstInBegin(GateRef gate)757     ConstInsIterator ConstInBegin(GateRef gate) const
758     {
759         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
760     }
761 
ConstInEnd(GateRef gate)762     ConstInsIterator ConstInEnd(GateRef gate) const
763     {
764         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
765         return ConstInsIterator(circuit_,
766                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
767     }
768     const GateMetaData *GetMetaData(GateRef g) const;
769 
770     const Circuit *circuit_;
771     friend struct ConstInWrapper;
772 };
773 }
774 #endif  // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
775