• 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 
21 namespace panda::ecmascript::kungfu {
22 class GateAccessor {
23 public:
24     // do not create new gate or modify self during iteration
25     struct ConstUseIterator {
ConstUseIteratorConstUseIterator26         explicit ConstUseIterator(const Circuit* circuit, const Out* out) : circuit_(circuit), out_(out)
27         {
28         }
29 
30         GateRef operator*() const
31         {
32             if (out_ != nullptr) {
33                 return circuit_->GetGateRef(out_->GetGateConst());
34             }
35             return 0;
36         }
37 
38         const ConstUseIterator operator++()
39         {
40             ASSERT(out_ != nullptr);
41             if (!out_->IsNextOutNull()) {
42                 out_ = out_->GetNextOutConst();
43                 return *this;
44             }
45             out_ = nullptr;
46             return *this;
47         }
48         const ConstUseIterator operator++(int)
49         {
50             ConstUseIterator tmp = *this;
51             ++(*this);
52             return tmp;
53         }
54 
GetIndexConstUseIterator55         size_t GetIndex() const
56         {
57             ASSERT(out_ != nullptr);
58             return out_->GetIndex();
59         }
60 
GetOpCodeConstUseIterator61         OpCode GetOpCode() const
62         {
63             ASSERT(out_ != nullptr);
64             return out_->GetGateConst()->GetOpCode();
65         }
66 
67         friend bool operator== (const ConstUseIterator& a, const ConstUseIterator& b)
68         {
69             return a.out_ == b.out_;
70         };
71         friend bool operator!= (const ConstUseIterator& a, const ConstUseIterator& b)
72         {
73             return a.out_ != b.out_;
74         };
75 
76     private:
77         const Circuit* circuit_;
78         const Out* out_;
79     };
80 
81     // do not create new gate or modify self during iteration
82     struct UseIterator {
UseIteratorUseIterator83         explicit UseIterator(Circuit* circuit, Out* out) : circuit_(circuit), out_(out)
84         {
85         }
86 
87         GateRef operator*() const
88         {
89             if (out_ != nullptr) {
90                 return circuit_->GetGateRef(out_->GetGate());
91             }
92             return 0;
93         }
94 
95         const UseIterator& operator++()
96         {
97             ASSERT(out_ != nullptr);
98             out_ = out_->IsNextOutNull() ? nullptr
99                                          : out_->GetNextOut();
100             return *this;
101         }
102 
103         UseIterator operator++(int)
104         {
105             UseIterator tmp = *this;
106             ++(*this);
107             return tmp;
108         }
109 
GetIndexUseIterator110         size_t GetIndex() const
111         {
112             ASSERT(out_ != nullptr);
113             return out_->GetIndex();
114         }
115 
GetOpCodeUseIterator116         OpCode GetOpCode() const
117         {
118             ASSERT(out_ != nullptr);
119             return out_->GetGateConst()->GetOpCode();
120         }
121 
122         friend bool operator== (const UseIterator& a, const UseIterator& b)
123         {
124             return a.out_ == b.out_;
125         };
126         friend bool operator!= (const UseIterator& a, const UseIterator& b)
127         {
128             return a.out_ != b.out_;
129         };
130 
131     private:
132         Circuit* circuit_;
133         Out* out_;
134     };
135 
136     struct ConstInsIterator {
ConstInsIteratorConstInsIterator137         explicit ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
138         {
139         }
140 
141         GateRef operator*() const
142         {
143             return circuit_->GetGateRef(in_->GetGateConst());
144         }
145 
146         const ConstInsIterator& operator++()
147         {
148             in_++;
149             return *this;
150         }
151         ConstInsIterator operator++(int)
152         {
153             ConstInsIterator tmp = *this;
154             ++(*this);
155             return tmp;
156         }
157 
GetOpCodeConstInsIterator158         OpCode GetOpCode() const
159         {
160             ASSERT(in_ != nullptr);
161             return in_->GetGateConst()->GetOpCode();
162         }
163 
164         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
165         {
166             return a.in_ == b.in_;
167         };
168         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
169         {
170             return a.in_ != b.in_;
171         };
172 
173     private:
174         const Circuit* circuit_;
175         const In* in_;
176     };
177 
178     struct InsIterator {
InsIteratorInsIterator179         explicit InsIterator(const Circuit* circuit, In* in) : circuit_(circuit), in_(in)
180         {
181         }
182 
183         GateRef operator*()
184         {
185             return circuit_->GetGateRef(in_->GetGate());
186         }
187 
188         const InsIterator& operator++()
189         {
190             in_++;
191             return *this;
192         }
193         InsIterator operator++(int)
194         {
195             InsIterator tmp = *this;
196             ++(*this);
197             return tmp;
198         }
199 
GetOpCodeInsIterator200         OpCode GetOpCode() const
201         {
202             ASSERT(in_ != nullptr);
203             return in_->GetGateConst()->GetOpCode();
204         }
205 
206         friend bool operator== (const InsIterator& a, const InsIterator& b)
207         {
208             return a.in_ == b.in_;
209         };
210         friend bool operator!= (const InsIterator& a, const InsIterator& b)
211         {
212             return a.in_ != b.in_;
213         };
214 
215     private:
216         const Circuit* circuit_;
217         In* in_;
218     };
219 
220     struct ConstUseWrapper {
221         Circuit* circuit;
222         GateRef gate;
beginConstUseWrapper223         auto begin()
224         {
225             return GateAccessor(circuit).ConstUseBegin(gate);
226         }
endConstUseWrapper227         auto end()
228         {
229             return GateAccessor(circuit).ConstUseEnd();
230         }
231     };
232 
233     struct UseWrapper {
234         Circuit* circuit;
235         GateRef gate;
beginUseWrapper236         auto begin()
237         {
238             return GateAccessor(circuit).UseBegin(gate);
239         }
endUseWrapper240         auto end()
241         {
242             return GateAccessor(circuit).UseEnd();
243         }
244     };
245 
246     struct ConstInWrapper {
247         Circuit* circuit;
248         const GateRef gate;
beginConstInWrapper249         auto begin()
250         {
251             return GateAccessor(circuit).ConstInBegin(gate);
252         }
endConstInWrapper253         auto end()
254         {
255             return GateAccessor(circuit).ConstInEnd(gate);
256         }
257     };
258 
259     struct InWrapper {
260         Circuit* circuit;
261         GateRef gate;
beginInWrapper262         auto begin()
263         {
264             return GateAccessor(circuit).InBegin(gate);
265         }
endInWrapper266         auto end()
267         {
268             return GateAccessor(circuit).InEnd(gate);
269         }
270     };
271 
ConstIns(GateRef gate)272     ConstInWrapper ConstIns(GateRef gate) const
273     {
274         return { circuit_, gate };
275     }
276 
Ins(GateRef gate)277     InWrapper Ins(GateRef gate) const
278     {
279         return { circuit_, gate };
280     }
281 
ConstUses(GateRef gate)282     ConstUseWrapper ConstUses(GateRef gate) const
283     {
284         return { circuit_, gate };
285     }
286 
Uses(GateRef gate)287     UseWrapper Uses(GateRef gate)
288     {
289         return { circuit_, gate };
290     }
291 
GateAccessor(Circuit * circuit)292     explicit GateAccessor(Circuit *circuit) : circuit_(circuit)
293     {
294     }
295 
GetCircuit()296     Circuit *GetCircuit() const
297     {
298         return circuit_;
299     }
300 
301     ~GateAccessor() = default;
302     void GetAllGates(std::vector<GateRef>& gates) const;
303     size_t GetNumIns(GateRef gate) const;
304     OpCode GetOpCode(GateRef gate) const;
305     bool IsGCRelated(GateRef gate) const;
306     uint64_t TryGetValue(GateRef gate) const;
307     ICmpCondition GetICmpCondition(GateRef gate) const;
308     FCmpCondition GetFCmpCondition(GateRef gate) const;
309     ConstDataId GetConstDataId(GateRef gate) const;
310     size_t GetVirtualRegisterIndex(GateRef gate) const;
311     TypedLoadOp GetTypedLoadOp(GateRef gate) const;
312     TypedStoreOp GetTypedStoreOp(GateRef gate) const;
313     TypedBinOp GetTypedBinaryOp(GateRef gate) const;
314     GateType GetParamGateType(GateRef gate) const;
315     TypedUnaryAccessor GetTypedUnOp(GateRef gate) const;
316     uint64_t GetConstantValue(GateRef gate) const;
317     uint32_t GetBytecodeIndex(GateRef gate) const;
318     EcmaOpcode GetByteCodeOpcode(GateRef gate) const;
319     void Print(GateRef gate) const;
320     void ShortPrint(GateRef gate) const;
321     GateId GetId(GateRef gate) const;
322     GateRef GetValueIn(GateRef gate, size_t idx = 0) const;
323     size_t GetNumValueIn(GateRef gate) const;
324     GateRef GetIn(GateRef gate, size_t idx) const;
325     GateRef GetState(GateRef gate, size_t idx = 0) const;
326     GateRef GetDep(GateRef gate, size_t idx = 0) const;
327     size_t GetImmediateId(GateRef gate) const;
328     void SetDep(GateRef gate, GateRef depGate, size_t idx = 0);
329     UseIterator ReplaceIn(const UseIterator &useIt, GateRef replaceGate);
330     // Add for lowering
331     GateType GetGateType(GateRef gate) const;
332     void SetGateType(GateRef gate, GateType gt);
333     UseIterator DeleteExceptionDep(const UseIterator &useIt);
334     void DeleteIn(GateRef gate, size_t idx);
335     UseIterator DeleteGate(const UseIterator &useIt);
336     void DecreaseIn(const UseIterator &useIt);
337     void DecreaseIn(GateRef gate, size_t index);
338     void NewIn(GateRef gate, size_t idx, GateRef in);
339     size_t GetStateCount(GateRef gate) const;
340     size_t GetDependCount(GateRef gate) const;
341     size_t GetInValueCount(GateRef gate) const;
342     size_t GetInValueStarts(GateRef gate) const;
343     void UpdateAllUses(GateRef gate, GateRef replaceValueIn);
344     void ReplaceIn(GateRef gate, size_t index, GateRef in);
345     void ReplaceStateIn(GateRef gate, GateRef in, size_t index = 0);
346     void ReplaceDependIn(GateRef gate, GateRef in, size_t index = 0);
347     void ReplaceValueIn(GateRef gate, GateRef in, size_t index = 0);
348     void DeleteGate(GateRef gate);
349     MachineType GetMachineType(GateRef gate) const;
350     void SetMachineType(GateRef gate, MachineType type);
351     GateRef GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const;
352     bool IsInGateNull(GateRef gate, size_t idx) const;
353     bool IsSelector(GateRef g) const;
354     bool IsControlCase(GateRef gate) const;
355     bool IsLoopHead(GateRef gate) const;
356     bool IsLoopBack(GateRef gate) const;
357     bool IsState(GateRef gate) const;
358     bool IsConstant(GateRef gate) const;
359     bool IsDependSelector(GateRef gate) const;
360     bool IsConstantValue(GateRef gate, uint64_t value) const;
361     bool IsTypedOperator(GateRef gate) const;
362     bool IsNotWrite(GateRef gate) const;
363     bool IsDead(GateRef gate) const;
364     bool IsCheckWithOneIn(GateRef gate) const;
365     bool IsCheckWithTwoIns(GateRef gate) const;
366     bool IsSchedulable(GateRef gate) const;
367     MarkCode GetMark(GateRef gate) const;
368     void SetMark(GateRef gate, MarkCode mark);
369     bool IsFinished(GateRef gate) const;
370     bool IsVisited(GateRef gate) const;
371     bool IsNotMarked(GateRef gate) const;
372     void SetFinished(GateRef gate);
373     void SetVisited(GateRef gate);
374     bool IsStateIn(const UseIterator &useIt) const;
375     bool IsDependIn(const UseIterator &useIt) const;
376     bool IsValueIn(const UseIterator &useIt) const;
377     bool IsFrameStateIn(const UseIterator &useIt) const;
378     bool IsExceptionState(const UseIterator &useIt) const;
379     bool IsDependIn(GateRef gate, size_t index) const;
380     bool IsValueIn(GateRef gate, size_t index) const;
381     void GetStateUses(GateRef gate, std::vector<GateRef>& stateUses);
382     void GetDependUses(GateRef gate, std::vector<GateRef>& dependUses);
383     bool IsFrameStateIn(GateRef gate, size_t index) const;
384     void DeleteStateSplitAndFrameState(GateRef gate);
385     void ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value);
386     GateType GetLeftType(GateRef gate) const;
387     GateType GetRightType(GateRef gate) const;
388     GateRef GetGlueFromArgList() const;
389     void GetArgsOuts(std::vector<GateRef>& outs) const;
390     void GetReturnOuts(std::vector<GateRef>& outs) const;
391 
GetStateRoot()392     GateRef GetStateRoot() const
393     {
394         return GetRoot(OpCode::STATE_ENTRY);
395     }
396 
GetDependRoot()397     GateRef GetDependRoot() const
398     {
399         return GetRoot(OpCode::DEPEND_ENTRY);
400     }
401 
GetArgRoot()402     GateRef GetArgRoot() const
403     {
404         return GetRoot(OpCode::ARG_LIST);
405     }
406 
GetReturnRoot()407     GateRef GetReturnRoot() const
408     {
409         return GetRoot(OpCode::RETURN_LIST);
410     }
411 
412     GateRef GetFrameState(GateRef gate) const;
413     void ReplaceFrameStateIn(GateRef gate, GateRef in);
414     bool HasFrameState(GateRef gate) const;
415     const GateMetaData *GetMetaData(GateRef gate) const;
416     void SetMetaData(GateRef gate, const GateMetaData* meta);
417 
418 private:
419     GateRef GetRoot(OpCode opcode) const;
ConstUseBegin(GateRef gate)420     ConstUseIterator ConstUseBegin(GateRef gate) const
421     {
422         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
423             return ConstUseIterator(circuit_, nullptr);
424         }
425         auto use = circuit_->LoadGatePtrConst(gate)->GetFirstOutConst();
426         return ConstUseIterator(circuit_, use);
427     }
428 
ConstUseEnd()429     ConstUseIterator ConstUseEnd() const
430     {
431         return ConstUseIterator(circuit_, nullptr);
432     }
433 
UseBegin(GateRef gate)434     UseIterator UseBegin(GateRef gate) const
435     {
436         if (circuit_->LoadGatePtrConst(gate)->IsFirstOutNull()) {
437             return UseIterator(circuit_, nullptr);
438         }
439         auto use = circuit_->LoadGatePtr(gate)->GetFirstOut();
440         return UseIterator(circuit_, use);
441     }
442 
UseEnd()443     UseIterator UseEnd() const
444     {
445         return UseIterator(circuit_, nullptr);
446     }
447 
ConstInBegin(GateRef gate)448     ConstInsIterator ConstInBegin(GateRef gate) const
449     {
450         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
451     }
452 
ConstInEnd(GateRef gate)453     ConstInsIterator ConstInEnd(GateRef gate) const
454     {
455         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
456         return ConstInsIterator(circuit_,
457                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
458     }
459 
InBegin(GateRef gate)460     InsIterator InBegin(GateRef gate)
461     {
462         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[0]);
463     }
464 
InEnd(GateRef gate)465     InsIterator InEnd(GateRef gate)
466     {
467         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
468         return InsIterator(circuit_, &reinterpret_cast<In *>(circuit_->LoadGatePtr(gate) + 1)[endIndex]);
469     }
470 
471     void GetIns(GateRef gate, std::vector<GateRef>& ins) const;
472 
473     void GetOuts(GateRef gate, std::vector<GateRef>& outs) const;
474 
475     void GetInStates(GateRef gate, std::vector<GateRef>& ins) const;
476 
477     void GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const;
478 
479     Circuit *circuit_;
480 
481     friend class Circuit;
482     friend class LLVMIRBuilder;
483     friend class Scheduler;
484     friend class EarlyElimination;
485     friend class ArgumentAccessor;
486     friend class BytecodeCircuitBuilder;
487 };
488 
489 class ConstGateAccessor {
490 public:
491     struct ConstInsIterator {
ConstInsIteratorConstInsIterator492         explicit ConstInsIterator(const Circuit* circuit, const In* in) : circuit_(circuit), in_(in)
493         {
494         }
495 
496         GateRef operator*() const
497         {
498             return circuit_->GetGateRef(in_->GetGateConst());
499         }
500 
501         const ConstInsIterator& operator++()
502         {
503             in_++;
504             return *this;
505         }
506         ConstInsIterator operator++(int)
507         {
508             ConstInsIterator tmp = *this;
509             ++(*this);
510             return tmp;
511         }
512 
GetOpCodeConstInsIterator513         OpCode GetOpCode() const
514         {
515             ASSERT(in_ != nullptr);
516             return in_->GetGateConst()->GetOpCode();
517         }
518 
519         friend bool operator== (const ConstInsIterator& a, const ConstInsIterator& b)
520         {
521             return a.in_ == b.in_;
522         };
523         friend bool operator!= (const ConstInsIterator& a, const ConstInsIterator& b)
524         {
525             return a.in_ != b.in_;
526         };
527 
528     private:
529         const Circuit* circuit_;
530         const In* in_;
531     };
532 
533     struct ConstInWrapper {
534         const Circuit* circuit;
535         const GateRef gate;
beginConstInWrapper536         auto begin()
537         {
538             return ConstGateAccessor(circuit).ConstInBegin(gate);
539         }
endConstInWrapper540         auto end()
541         {
542             return ConstGateAccessor(circuit).ConstInEnd(gate);
543         }
544     };
545 
Ins(GateRef gate)546     ConstInWrapper Ins(GateRef gate) const
547     {
548         return { circuit_, gate };
549     }
550 
ConstGateAccessor(const Circuit * circuit)551     explicit ConstGateAccessor(const Circuit *circuit) : circuit_(circuit)
552     {
553     }
554 
555     ~ConstGateAccessor() = default;
556 
557 private:
ConstInBegin(GateRef gate)558     ConstInsIterator ConstInBegin(GateRef gate) const
559     {
560         return ConstInsIterator(circuit_, &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[0]);
561     }
562 
ConstInEnd(GateRef gate)563     ConstInsIterator ConstInEnd(GateRef gate) const
564     {
565         auto endIndex = circuit_->LoadGatePtrConst(gate)->GetNumIns();
566         return ConstInsIterator(circuit_,
567                                 &reinterpret_cast<const In *>(circuit_->LoadGatePtrConst(gate) + 1)[endIndex]);
568     }
569 
570     const Circuit *circuit_;
571     friend struct ConstInWrapper;
572 };
573 }
574 #endif  // ECMASCRIPT_COMPILER_GATE_ACCESSOR_H
575