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