• 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/gate_meta_data.h"
21 #include "ecmascript/pgo_profiler/pgo_profiler_type.h"
22 
23 namespace panda::ecmascript::kungfu {
24 
25 class StateDepend {
26 public:
StateDepend()27     StateDepend()
28         : state_(Circuit::NullGate()), depend_(Circuit::NullGate()) {}
29 
StateDepend(GateRef state,GateRef depend)30     explicit StateDepend(GateRef state, GateRef depend)
31         : state_(state), depend_(depend) {}
32 
State()33     GateRef State() const
34     {
35         return state_;
36     }
37 
Depend()38     GateRef Depend() const
39     {
40         return depend_;
41     }
42 
SetState(GateRef state)43     void SetState(GateRef state)
44     {
45         state_ = state;
46     }
47 
SetDepend(GateRef depend)48     void SetDepend(GateRef depend)
49     {
50         depend_ = depend;
51     }
52 
Reset()53     void Reset()
54     {
55         state_ = Circuit::NullGate();
56         depend_ = Circuit::NullGate();
57     }
58 
59 private:
60     GateRef state_;
61     GateRef depend_;
62 };
63 
64 class Edge {
65 public:
Edge(GateRef gate,size_t index)66     explicit Edge(GateRef gate, size_t index) : gate_(gate), index_(static_cast<uint32_t>(index)) {}
67 
GetGate()68     GateRef GetGate() const
69     {
70         return gate_;
71     }
72 
GetIndex()73     size_t GetIndex() const
74     {
75         return static_cast<size_t>(index_);
76     }
77 
SetIndex(size_t index)78     void SetIndex(size_t index)
79     {
80         index_ = static_cast<uint32_t>(index);
81     }
82 
83 private:
84     GateRef gate_;
85     uint32_t index_;
86 };
87 
88 class GateAccessor {
89 public:
90     // do not create new gate or modify self during iteration
91     struct ConstUseIterator {
ConstUseIteratorConstUseIterator92         ConstUseIterator(const Circuit* circuit, const Out* out) : circuit_(circuit), out_(out)
93         {
94         }
95 
96         GateRef operator*() const
97         {
98             if (out_ != nullptr) {
99                 return circuit_->GetGateRef(out_->GetGateConst());
100             }
101             return 0;
102         }
103 
104         const ConstUseIterator operator++()
105         {
106             ASSERT(out_ != nullptr);
107             if (!out_->IsNextOutNull()) {
108                 out_ = out_->GetNextOutConst();
109                 return *this;
110             }
111             out_ = nullptr;
112             return *this;
113         }
114         const ConstUseIterator operator++(int)
115         {
116             ConstUseIterator tmp = *this;
117             ++(*this);
118             return tmp;
119         }
120 
GetIndexConstUseIterator121         size_t GetIndex() const
122         {
123             ASSERT(out_ != nullptr);
124             return out_->GetIndex();
125         }
126 
GetOpCodeConstUseIterator127         OpCode GetOpCode() const
128         {
129             ASSERT(out_ != nullptr);
130             return out_->GetGateConst()->GetOpCode();
131         }
132 
133         friend bool operator == (const ConstUseIterator& a, const ConstUseIterator& b)
134         {
135             return a.out_ == b.out_;
136         };
137         friend bool operator != (const ConstUseIterator& a, const ConstUseIterator& b)
138         {
139             return a.out_ != b.out_;
140         };
141 
142     private:
143         const Circuit* circuit_;
144         const Out* out_;
145     };
146 
147     // do not create new gate or modify self during iteration
148     struct UseIterator {
UseIteratorUseIterator149         UseIterator(Circuit* circuit, Out* out) : circuit_(circuit), out_(out)
150         {
151         }
152 
153         GateRef operator*() const
154         {
155             if (out_ != nullptr) {
156                 return circuit_->GetGateRef(out_->GetGate());
157             }
158             return 0;
159         }
160 
161         const UseIterator& operator++()
162         {
163             ASSERT(out_ != nullptr);
164             out_ = out_->IsNextOutNull() ? nullptr
165                                          : out_->GetNextOut();
166             return *this;
167         }
168 
169         UseIterator operator++(int)
170         {
171             UseIterator tmp = *this;
172             ++(*this);
173             return tmp;
174         }
175 
GetIndexUseIterator176         size_t GetIndex() const
177         {
178             ASSERT(out_ != nullptr);
179             return out_->GetIndex();
180         }
181 
GetEdgeUseIterator182         Edge GetEdge()
183         {
184             ASSERT(out_ != nullptr);
185             UseIterator it = *this;
186             return Edge(*it, GetIndex());
187         }
188 
GetOpCodeUseIterator189         OpCode GetOpCode() const
190         {
191             ASSERT(out_ != nullptr);
192             return out_->GetGateConst()->GetOpCode();
193         }
194 
195         friend bool operator == (const UseIterator& a, const UseIterator& b)
196         {
197             return a.out_ == b.out_;
198         };
199         friend bool operator != (const UseIterator& a, const UseIterator& b)
200         {
201             return a.out_ != b.out_;
202         };
203 
204     private:
205         Circuit* circuit_;
206         Out* out_;
207     };
208 
209     struct ConstInsIterator {
ConstInsIteratorConstInsIterator210         ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
211         {
212         }
213 
214         GateRef operator*() const
215         {
216             return circuit_->GetGateRef(in_->GetGateConst());
217         }
218 
219         const ConstInsIterator& operator++()
220         {
221             in_++;
222             return *this;
223         }
224         ConstInsIterator operator++(int)
225         {
226             ConstInsIterator tmp = *this;
227             ++(*this);
228             return tmp;
229         }
230 
GetOpCodeConstInsIterator231         OpCode GetOpCode() const
232         {
233             ASSERT(in_ != nullptr);
234             return in_->GetGateConst()->GetOpCode();
235         }
236 
237         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
238         {
239             return a.in_ == b.in_;
240         };
241         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
242         {
243             return a.in_ != b.in_;
244         };
245 
246     private:
247         const Circuit* circuit_;
248         const In* in_;
249     };
250 
251     struct InsIterator {
InsIteratorInsIterator252         InsIterator(const Circuit* circuit, In* in) : circuit_(circuit), in_(in)
253         {
254         }
255 
256         GateRef operator*()
257         {
258             return circuit_->GetGateRef(in_->GetGate());
259         }
260 
261         const InsIterator& operator++()
262         {
263             in_++;
264             return *this;
265         }
266         InsIterator operator++(int)
267         {
268             InsIterator tmp = *this;
269             ++(*this);
270             return tmp;
271         }
272 
GetOpCodeInsIterator273         OpCode GetOpCode() const
274         {
275             ASSERT(in_ != nullptr);
276             return in_->GetGateConst()->GetOpCode();
277         }
278 
279         friend bool operator== (const InsIterator& a, const InsIterator& b)
280         {
281             return a.in_ == b.in_;
282         };
283         friend bool operator!= (const InsIterator& a, const InsIterator& b)
284         {
285             return a.in_ != b.in_;
286         };
287 
288     private:
289         const Circuit* circuit_;
290         In* in_;
291     };
292 
293     struct ConstUseWrapper {
294         Circuit* circuit;
295         GateRef gate;
beginConstUseWrapper296         auto begin()
297         {
298             return GateAccessor(circuit).ConstUseBegin(gate);
299         }
endConstUseWrapper300         auto end()
301         {
302             return GateAccessor(circuit).ConstUseEnd();
303         }
304     };
305 
306     struct UseWrapper {
307         Circuit* circuit;
308         GateRef gate;
beginUseWrapper309         auto begin()
310         {
311             return GateAccessor(circuit).UseBegin(gate);
312         }
endUseWrapper313         auto end()
314         {
315             return GateAccessor(circuit).UseEnd();
316         }
317     };
318 
319     struct ConstInWrapper {
320         Circuit* circuit;
321         const GateRef gate;
beginConstInWrapper322         auto begin()
323         {
324             return GateAccessor(circuit).ConstInBegin(gate);
325         }
endConstInWrapper326         auto end()
327         {
328             return GateAccessor(circuit).ConstInEnd(gate);
329         }
330     };
331 
332     struct InWrapper {
333         Circuit* circuit;
334         GateRef gate;
beginInWrapper335         auto begin()
336         {
337             return GateAccessor(circuit).InBegin(gate);
338         }
endInWrapper339         auto end()
340         {
341             return GateAccessor(circuit).InEnd(gate);
342         }
343     };
344 
ConstIns(GateRef gate)345     ConstInWrapper ConstIns(GateRef gate) const
346     {
347         return { circuit_, gate };
348     }
349 
Ins(GateRef gate)350     InWrapper Ins(GateRef gate) const
351     {
352         return { circuit_, gate };
353     }
354 
ConstUses(GateRef gate)355     ConstUseWrapper ConstUses(GateRef gate) const
356     {
357         return { circuit_, gate };
358     }
359 
Uses(GateRef gate)360     UseWrapper Uses(GateRef gate)
361     {
362         return { circuit_, gate };
363     }
364 
GateAccessor(Circuit * circuit)365     explicit GateAccessor(Circuit *circuit) : circuit_(circuit)
366     {
367     }
368 
GetCircuit()369     Circuit *GetCircuit() const
370     {
371         return circuit_;
372     }
373 
374     ~GateAccessor() = default;
375     void GetAllGates(std::vector<GateRef>& gates) const;
376     size_t GetNumIns(GateRef gate) const;
377     OpCode GetOpCode(GateRef gate) const;
378     bool IsGCRelated(GateRef gate) const;
379     uint64_t TryGetValue(GateRef gate) const;
380     ICmpCondition GetICmpCondition(GateRef gate) const;
381     FCmpCondition GetFCmpCondition(GateRef gate) const;
382     size_t GetOffset(GateRef gate) const;
383     size_t GetIndex(GateRef gate) const;
384     size_t GetArraySize(GateRef gate) const;
385     void SetArraySize(GateRef gate, size_t size);
386     size_t GetVirtualRegisterIndex(GateRef gate) const;
387     TypedLoadOp GetTypedLoadOp(GateRef gate) const;
388     TypedStoreOp GetTypedStoreOp(GateRef gate) const;
389     MemoryType GetMemoryType(GateRef gate) const;
390     TypedBinOp GetTypedBinaryOp(GateRef gate) const;
391     TypedCallTargetCheckOp GetTypedCallTargetCheckOp(GateRef gate) const;
392     PGOSampleType GetTypedBinaryType(GateRef gate) const;
393     bool HasNumberType(GateRef gate) const;
394     GlobalTSTypeRef GetFuncGT(GateRef gate) const;
395     GateType GetParamGateType(GateRef gate) const;
396     TypedUnaryAccessor GetTypedUnAccessor(GateRef gate) const;
397     TypedJumpAccessor GetTypedJumpAccessor(GateRef gate) const;
398     ArrayMetaDataAccessor GetArrayMetaDataAccessor(GateRef gate) const;
399     ObjectTypeAccessor GetObjectTypeAccessor(GateRef gate) const;
400     uint64_t GetConstantValue(GateRef gate) const;
401     const ChunkVector<char>& GetConstantString(GateRef gate) const;
402     bool IsVtable(GateRef gate) const;
403     bool GetNoGCFlag(GateRef gate) const;
404     bool TypedCallIsNoGC(GateRef gate) const;
405     bool IsNoGC(GateRef gate) const;
406     uint32_t TryGetPcOffset(GateRef gate) const;
407     PGOSampleType TryGetPGOType(GateRef gate) const;
408     void TrySetPGOType(GateRef gate, PGOSampleType type);
409     ElementsKind TryGetElementsKind(GateRef gate) const;
410     void TrySetElementsKind(GateRef gate, ElementsKind kind);
411     EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
412     void Print(GateRef gate) const;
413     void ShortPrint(GateRef gate) const;
414     GateId GetId(GateRef gate) const;
415     GateRef GetValueIn(GateRef gate, size_t idx = 0) const;
416     size_t GetNumValueIn(GateRef gate) const;
417     GateRef GetIn(GateRef gate, size_t idx) const;
418     GateRef GetState(GateRef gate, size_t idx = 0) const;
419     GateRef GetDep(GateRef gate, size_t idx = 0) const;
420     size_t GetImmediateId(GateRef gate) const;
421     void SetDep(GateRef gate, GateRef depGate, size_t idx = 0);
422     UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate);
423     // Add for lowering
424     GateType GetGateType(GateRef gate) const;
425     bool IsConvertSupport(GateRef gate) const;
426     ValueType GetSrcType(GateRef gate) const;
427     ValueType GetDstType(GateRef gate) const;
428     void SetGateType(GateRef gate, GateType gt);
429     void DeleteIn(GateRef gate, size_t idx);
430     UseIterator DeleteGate(const UseIterator &useIt);
431     void DecreaseIn(const UseIterator &useIt);
432     void DecreaseIn(GateRef gate, size_t index);
433     void NewIn(GateRef gate, size_t idx, GateRef in);
434     size_t GetStateCount(GateRef gate) const;
435     size_t GetDependCount(GateRef gate) const;
436     size_t GetInValueCount(GateRef gate) const;
437     size_t GetInValueStarts(GateRef gate) const;
438     void UpdateAllUses(GateRef gate, GateRef replaceValueIn);
439     void ReplaceIn(GateRef gate, size_t index, GateRef in);
440     void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0);
441     void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0);
442     void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0);
443     void DeleteGate(GateRef gate);
444     MachineType GetMachineType(GateRef gate) const;
445     void SetMachineType(GateRef gate, MachineType type);
446     GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const;
447     GateRef GetInitialEnvGate(GateRef jsFunc) const;
448     double GetFloat64FromConstant(GateRef gate) const;
449     int GetInt32FromConstant(GateRef gate) const;
450     bool IsInGateNull(GateRef gate, size_t idx) const;
451     bool IsSelector(GateRef g) const;
452     bool IsSimpleState(GateRef g) const;
453     bool IsValueSelector(GateRef g) const;
454     bool IsControlCase(GateRef gate) const;
455     bool IsLoopExit(GateRef gate) const;
456     bool IsLoopExitRelated(GateRef gate) const;
457     bool IsLoopHead(GateRef gate) const;
458     bool IsLoopBack(GateRef gate) const;
459     bool IsState(GateRef gate) const;
460     bool IsConstant(GateRef gate) const;
461     bool IsDependSelector(GateRef gate) const;
462     bool IsConstantValue(GateRef gate, uint64_t value) const;
463     bool IsConstantUndefined(GateRef gate) const;
464     bool IsConstantNumber(GateRef gate) const;
465     bool IsTypedOperator(GateRef gate) const;
466     bool IsNotWrite(GateRef gate) const;
467     bool IsDead(GateRef gate) const;
468     bool IsCheckWithOneIn(GateRef gate) const;
469     bool IsCheckWithTwoIns(GateRef gate) const;
470     bool IsSchedulable(GateRef gate) const;
471     bool IsVirtualState(GateRef gate) const;
472     bool IsGeneralState(GateRef gate) const;
473     MarkCode GetMark(GateRef gate) const;
474     void SetMark(GateRef gate, MarkCode mark);
475     bool IsFinished(GateRef gate) const;
476     bool IsVisited(GateRef gate) const;
477     bool IsNotMarked(GateRef gate) const;
478     void SetFinished(GateRef gate);
479     void SetVisited(GateRef gate);
480     bool IsStateIn(const UseIterator &useIt) const;
481     bool IsDependIn(const UseIterator &useIt) const;
482     bool IsValueIn(const UseIterator &useIt) const;
483     bool IsFrameStateIn(const UseIterator &useIt) const;
484     bool IsStateIn(GateRef gate, size_t index) const;
485     bool IsDependIn(GateRef gate, size_t index) const;
486     bool IsValueIn(GateRef gate, size_t index) const;
487     void GetStateUses(GateRef gate, std::vector<GateRef> &stateUses);
488     void GetDependUses(GateRef gate, std::vector<GateRef> &dependUses);
489     void GetValueUses(GateRef gate, std::vector<GateRef> &valueUses);
490     bool IsFrameStateIn(GateRef gate, size_t index) const;
491     void EliminateRedundantPhi();
492     void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
493     GateType GetLeftType(GateRef gate) const;
494     GateType GetRightType(GateRef gate) const;
495     uint32_t GetFirstValue(GateRef gate) const;
496     uint32_t GetSecondValue(GateRef gate) const;
497     GateRef GetGlueFromArgList() const;
498     void GetArgsOuts(std::vector<GateRef>& outs) const;
499     void GetReturnOuts(std::vector<GateRef>& outs) const;
500     bool IsFixed(GateRef g) const;
501     bool IsProlog(GateRef g) const;
502     bool IsCFGMerge(GateRef g) const;
503     bool MetaDataEqu(GateRef g1, GateRef g2) const;
504     bool IsNop(GateRef g) const;
505     bool IsRoot(GateRef g) const;
506     bool HasOuts(GateRef gate) const;
507     void DeleteGateIfNoUse(GateRef gate);
508     GateRef GetDependSelectorFromMerge(GateRef gate);
509     bool HasIfExceptionUse(GateRef gate) const;
510     bool IsIn(GateRef g, GateRef in) const;
511     bool IsHeapObjectFromElementsKind(GateRef gate);
512 
GetCircuitRoot()513     GateRef GetCircuitRoot() const
514     {
515         return GetRoot(OpCode::CIRCUIT_ROOT);
516     }
517 
GetStateRoot()518     GateRef GetStateRoot() const
519     {
520         return GetRoot(OpCode::STATE_ENTRY);
521     }
522 
GetDependRoot()523     GateRef GetDependRoot() const
524     {
525         return GetRoot(OpCode::DEPEND_ENTRY);
526     }
527 
GetArgRoot()528     GateRef GetArgRoot() const
529     {
530         return GetRoot(OpCode::ARG_LIST);
531     }
532 
GetReturnRoot()533     GateRef GetReturnRoot() const
534     {
535         return GetRoot(OpCode::RETURN_LIST);
536     }
537 
IsStateRoot(GateRef gate)538     inline bool IsStateRoot(GateRef gate) const
539     {
540         return gate == GetStateRoot();
541     }
542 
543     GateRef GetFrameState(GateRef gate) const;
544     void ReplaceFrameStateIn(GateRef gate, GateRef in);
545     bool HasFrameState(GateRef gate) const;
546     GateRef FindNearestFrameState(GateRef gate) const;
547     GateRef FindNearestStateSplit(GateRef gate) const;
548     void SetMetaData(GateRef gate, const GateMetaData* meta);
549 
550     void ReplaceHirWithIfBranch(GateRef hirGate, StateDepend success, StateDepend exception, GateRef value);
551     void ReplaceHirDirectly(GateRef hirGate, StateDepend replacement, GateRef value);
552     void ReplaceHirAndDeleteIfException(GateRef hirGate, StateDepend replacement, GateRef value);
553 
554 private:
555     const GateMetaData *GetMetaData(GateRef gate) const;
556     UseIterator ReplaceHirIfSuccess(const UseIterator &useIt, GateRef state);
557     UseIterator ReplaceHirIfException(const UseIterator &useIt, StateDepend replacement);
558     void ExceptionReturn(GateRef state, GateRef depend);
559 
560     GateRef GetRoot(OpCode opcode) const;
ConstUseBegin(GateRef gate)561     ConstUseIterator ConstUseBegin(GateRef gate) const
562     {
563         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
564             return ConstUseIterator(circuit_, nullptr);
565         }
566         auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst();
567         return ConstUseIterator(circuit_, use);
568     }
569 
ConstUseEnd()570     ConstUseIterator ConstUseEnd() const
571     {
572         return ConstUseIterator(circuit_, nullptr);
573     }
574 
UseBegin(GateRef gate)575     UseIterator UseBegin(GateRef gate) const
576     {
577         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
578             return UseIterator(circuit_, nullptr);
579         }
580         auto use = circuit_->LoadGatePtr(gate)->GetFirstOut();
581         return UseIterator(circuit_, use);
582     }
583 
UseEnd()584     UseIterator UseEnd() const
585     {
586         return UseIterator(circuit_, nullptr);
587     }
588 
ConstInBegin(GateRef gate)589     ConstInsIterator ConstInBegin(GateRef gate) const
590     {
591         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
592     }
593 
ConstInEnd(GateRef gate)594     ConstInsIterator ConstInEnd(GateRef gate) const
595     {
596         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
597         return ConstInsIterator(circuit_,
598                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
599     }
600 
InBegin(GateRef gate)601     InsIterator InBegin(GateRef gate)
602     {
603         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]);
604     }
605 
InEnd(GateRef gate)606     InsIterator InEnd(GateRef gate)
607     {
608         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
609         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]);
610     }
611 
612     void GetIns(GateRef gate, std::vector<GateRef>& ins) const;
613 
614     void GetOuts(GateRef gate, std::vector<GateRef>& outs) const;
615 
616     void GetInStates(GateRef gate, std::vector<GateRef>& ins) const;
617 
618     void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const;
619 
620     Circuit *circuit_;
621 
622     friend class Circuit;
623     friend class LLVMIRBuilder;
624     friend class Scheduler;
625     friend class LoopPeeling;
626 };
627 
628 class ConstGateAccessor {
629 public:
630     struct ConstInsIterator {
ConstInsIteratorConstInsIterator631         ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
632         {
633         }
634 
635         GateRef operator*() const
636         {
637             return circuit_->GetGateRef(in_->GetGateConst());
638         }
639 
640         const ConstInsIterator& operator++()
641         {
642             in_++;
643             return *this;
644         }
645         ConstInsIterator operator++(int)
646         {
647             ConstInsIterator tmp = *this;
648             ++(*this);
649             return tmp;
650         }
651 
GetOpCodeConstInsIterator652         OpCode GetOpCode() const
653         {
654             ASSERT(in_ != nullptr);
655             return in_->GetGateConst()->GetOpCode();
656         }
657 
658         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
659         {
660             return a.in_ == b.in_;
661         };
662         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
663         {
664             return a.in_ != b.in_;
665         };
666 
667     private:
668         const Circuit* circuit_;
669         const In* in_;
670     };
671 
672     struct ConstInWrapper {
673         const Circuit* circuit;
674         const GateRef gate;
beginConstInWrapper675         auto begin()
676         {
677             return ConstGateAccessor(circuit).ConstInBegin(gate);
678         }
endConstInWrapper679         auto end()
680         {
681             return ConstGateAccessor(circuit).ConstInEnd(gate);
682         }
683     };
684 
Ins(GateRef gate)685     ConstInWrapper Ins(GateRef gate) const
686     {
687         return { circuit_, gate };
688     }
689 
ConstGateAccessor(const Circuit * circuit)690     explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit)
691     {
692     }
693 
694     ~ConstGateAccessor() = default;
695 
696     bool IsFixed(GateRef g) const;
697     bool IsProlog(GateRef g) const;
698     bool IsSchedulable(GateRef g) const;
699 
700 private:
ConstInBegin(GateRef gate)701     ConstInsIterator ConstInBegin(GateRef gate) const
702     {
703         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
704     }
705 
ConstInEnd(GateRef gate)706     ConstInsIterator ConstInEnd(GateRef gate) const
707     {
708         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
709         return ConstInsIterator(circuit_,
710                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
711     }
712     const GateMetaData *GetMetaData(GateRef g) const;
713 
714     const Circuit *circuit_;
715     friend struct ConstInWrapper;
716 };
717 }
718 #endif  // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
719