1 /*
2  * Copyright (c) 2023 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 
17 #ifndef ECMASCRIPT_LEXICAL_ENV_SPECIALIZATION_H
18 #define ECMASCRIPT_LEXICAL_ENV_SPECIALIZATION_H
19 
20 #include "ecmascript/compiler/base/depend_chain_helper.h"
21 #include "ecmascript/compiler/gate_accessor.h"
22 #include "ecmascript/compiler/combined_pass_visitor.h"
23 
24 namespace panda::ecmascript::kungfu {
25 class DependChains;
26 class LexicalEnvSpecializationPass : public PassVisitor {
27 public:
LexicalEnvSpecializationPass(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk, bool enableLog)28     LexicalEnvSpecializationPass(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk, bool enableLog)
29         : PassVisitor(circuit, chunk, visitor), chunk_(chunk), dependChains_(chunk), specializeId_(chunk),
30         notdomStlexvar_(chunk), notDomCall_(chunk_), enableLog_(enableLog), acc_(circuit) {}
31 
32     ~LexicalEnvSpecializationPass() = default;
33 
34     void Initialize() override;
35     GateRef VisitGate(GateRef gate) override;
36     bool SearchStLexVar(GateRef gate, GateRef ldLexVar, GateRef &result);
37     void PrintSpecializeId();
38 private:
GetDependChain(GateRef dependIn)39     DependChains* GetDependChain(GateRef dependIn)
40     {
41         size_t idx = acc_.GetId(dependIn);
42         ASSERT(idx <= circuit_->GetMaxGateId());
43         return dependChains_[idx];
44     }
45 
46     GateRef VisitDependEntry(GateRef gate);
47     GateRef UpdateDependChain(GateRef gate, DependChains* dependInfo);
48     GateRef TrySpecializeLdLexVar(GateRef gate);
49     GateRef VisitOther(GateRef gate);
50     GateRef VisitDependSelector(GateRef gate);
51     bool CheckStLexVar(GateRef gate, GateRef ldLexVar);
52     bool caclulateDistanceToTarget(GateRef startEnv, GateRef targetEnv, int32_t &dis);
53     void HasNotdomStLexVarOrCall(GateRef gate, GateRef next);
54     bool HasNotDomStLexvar(GateRef gate);
55     bool HasNotDomCall(GateRef gate);
56     bool HasNotDomIllegalOp(GateRef gate);
57     void LookUpNotDomStLexVarOrCall(GateRef current, GateRef next);
58     GateRef LookupStLexvarNode(DependChains* dependChain, GateRef gate);
59 
60     Chunk *chunk_ {nullptr};
61     ChunkVector<DependChains*> dependChains_;
62     ChunkVector<size_t> specializeId_;
63     ChunkMap<GateRef, GateRef> notdomStlexvar_;
64     ChunkMap<GateRef, GateRef> notDomCall_;
65     bool enableLog_ {false};
66     GateAccessor acc_;
67 };
68 
69 class GetEnvSpecializationPass : public PassVisitor {
70 public:
GetEnvSpecializationPass(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk)71     GetEnvSpecializationPass(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk)
72         : PassVisitor(circuit, chunk, visitor),
73           acc_(circuit) {}
74     ~GetEnvSpecializationPass() = default;
75 
76     GateRef VisitGate(GateRef gate) override;
77 private:
78     GateRef TryGetReplaceEnv(GateRef func);
79 
80     GateAccessor acc_;
81 };
82 }
83 #endif // ECMASCRIPT_LEXICAL_ENV_SPECIALIZATION_H