• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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_LITECG_IR_BUILDER_H
17 #define ECMASCRIPT_COMPILER_LITECG_IR_BUILDER_H
18 
19 #include <map>
20 #include <vector>
21 
22 #include "ecmascript/compiler/circuit.h"
23 #include "ecmascript/compiler/gate.h"
24 #include "ecmascript/compiler/stub_builder.h"
25 #include "ecmascript/compiler/call_signature.h"
26 #include "ecmascript/compiler/interpreter_stub.h"
27 #include "ecmascript/compiler/rt_call_signature.h"
28 #include "ecmascript/compiler/ir_builder.h"
29 #include "ecmascript/compiler/ir_module.h"
30 #include "ecmascript/jspandafile/method_literal.h"
31 #include "lmir_builder.h"
32 #include "constantfold.h"
33 
34 namespace panda::ecmascript::kungfu {
35 class LMIRModule : public IRModule {
36 public:
37     static constexpr int kDeoptEntryOffset = 0;
LMIRModule(NativeAreaAllocator * allocator,const std::string & name,bool logDbg,const std::string & triple,bool isJit)38     LMIRModule(NativeAreaAllocator *allocator, const std::string &name, bool logDbg, const std::string &triple,
39          bool isJit)
40         : IRModule(allocator, logDbg, triple)
41     {
42         moduleName = name;
43         module = isJit ? nullptr : maple::litecg::CreateModuleWithName(name);
44     }
45 
~LMIRModule()46     ~LMIRModule()
47     {
48         if (module != nullptr) {
49             maple::litecg::ReleaseModule(module);
50         }
51     }
52 
JitCreateLitecgModule()53     void JitCreateLitecgModule()
54     {
55         ASSERT(module == nullptr);
56         module = maple::litecg::CreateModuleWithName(moduleName);
57     }
58 
GetModule()59     maple::litecg::Module *GetModule()
60     {
61         ASSERT(module != nullptr);
62         return module;
63     }
64 
GetModuleKind()65     ModuleKind GetModuleKind() const override
66     {
67         return MODULE_LITECG;
68     }
69 
SetFunction(size_t index,std::string funcName,bool isFastCall)70     void SetFunction(size_t index, std::string funcName, bool isFastCall)
71     {
72         funcIndexMap_.emplace_back(std::make_tuple(index, funcName, isFastCall));
73     }
74 
75     template <class Callback>
IteratefuncIndexMap(const Callback & cb)76     void IteratefuncIndexMap(const Callback &cb) const
77     {
78         for (auto record : funcIndexMap_) {
79             // 2: 3nd param
80             cb(std::get<0>(record), std::get<1>(record), std::get<2>(record));
81         }
82     }
83 
84 private:
85     std::string moduleName;
86     maple::litecg::Module *module;
87     std::vector<std::tuple<size_t, std::string, bool>> funcIndexMap_;
88 };
89 
90 class LiteCGIRBuilder {
91 public:
92     LiteCGIRBuilder(const std::vector<std::vector<GateRef>> *schedule, Circuit *circuit, LMIRModule *module,
93                     const CompilationConfig *cfg, CallSignature::CallConv callConv, bool enableLog,
94                     bool enableOptInlining, const panda::ecmascript::MethodLiteral *methodLiteral,
95                     const JSPandaFile *jsPandaFile, const std::string &funcName);
96     ~LiteCGIRBuilder();
97     void Build();
98 
99 private:
100     struct PhiDesc {
101         int predBBId;
102         GateRef operand;
103         maple::litecg::PregIdx phi;
104     };
105     enum DerivedStatus {
106         IS_DERIVED,
107         IS_BASE,
108         UNKNOW
109     };
110     struct DeoptBBInfo {
111         maple::litecg::BB *deoptBB = nullptr;
112         maple::litecg::PregIdx deoptTypePreg = 0;
113         std::map<uint32_t, maple::litecg::BB*> deoptType2BB;
114 
DeoptBBInfoDeoptBBInfo115         DeoptBBInfo(maple::litecg::BB *bb, maple::litecg::PregIdx preg) : deoptBB(bb), deoptTypePreg(preg)
116         {}
117         ~DeoptBBInfo() = default;
118     };
119     const std::vector<std::vector<GateRef>> *scheduledGates_ {nullptr};
120     const Circuit *circuit_ {nullptr};
121     LMIRModule *lmirModule_ {nullptr};
122     const CompilationConfig *compCfg_ {nullptr};
123     CallSignature::CallConv callConv_ = CallSignature::CallConv::CCallConv;
124     bool enableLog_ {false};
125     bool enableOptInlining_ {false};
126     const panda::ecmascript::MethodLiteral *methodLiteral_ {nullptr};
127     const JSPandaFile *jsPandaFile_ {nullptr};
128     std::string funcName_;
129     GateAccessor acc_;
130     maple::litecg::LMIRBuilder *lmirBuilder_ {nullptr};
131     std::unordered_map<GateRef, maple::litecg::LiteCGValue> gate2Expr_;
132     std::set<OpCode> illegalOpHandlers_;
133     std::map<GateId, int> instID2bbID_;
134     std::map<int, maple::litecg::BB *> bbID2BB_;
135     int slotSize_ {-1};
136     maple::litecg::Type *slotType_ {nullptr};
137     std::map<int, std::vector<PhiDesc>> bbID2unmergedPhis_;
138     std::map<int, std::vector<PhiDesc>> bbID2basePhis_; // use for collect all the base references
139     // derived phi reference gate to base phi preg map
140     std::map<GateRef, maple::litecg::PregIdx> derivedPhiGate2BasePhiPreg_;
141     std::map<GateRef, GateRef> derivedGate2BaseGate_; // derived reference gate to base reference gate map
142     std::map<GateRef, bool> derivedGateCache_; // cache whether the phi reference is derived, base or unknow
143     std::map<GateRef, DeoptBBInfo> deoptFrameState2BB_;
144     maple::ConstantFold cf_;
145     std::unordered_map<GateRef, maple::litecg::Expr> derivedrefGate;
146 
147 #define DECLAREVISITLOWEROPCODE(name, signature) void Visit##name signature;
148     OPCODES(DECLAREVISITLOWEROPCODE)
149 #undef DECLAREVISITLOWEROPCODE
150 #define DECLAREHANDLELOWEROPCODE(name, ignore) void Handle##name(GateRef gate);
OPCODES(DECLAREHANDLELOWEROPCODE)151     OPCODES(DECLAREHANDLELOWEROPCODE)
152 #undef DECLAREHANDLELOWEROPCODE
153     void InsertUsedOpcodeSet(std::unordered_set<OpCode> &usedOpcodeSet, OpCode op)
154     {
155         if (enableLog_) {
156             usedOpcodeSet.insert(op);
157         }
158     }
159     maple::litecg::LiteCGValue ConstantFoldExpr(maple::litecg::Expr expr, maple::litecg::BB &curBB);
160     void SaveGate2Expr(GateRef gate, maple::litecg::Expr expr, bool isGlueAdd = false);
161     void SaveGate2Expr(GateRef gate, maple::litecg::PregIdx pregIdx1, maple::litecg::PregIdx pregIdx2);
162     maple::litecg::Expr CreateExprFromLiteCGValue(const maple::litecg::LiteCGValue &value);
163     maple::litecg::Expr GetExprFromGate(GateRef gate);
164     maple::litecg::Expr GetExprFromGate(GateRef gate, uint32_t index);
165     maple::litecg::Expr GetConstant(GateRef gate);
166     void BuildInstID2BBIDMap();
167     maple::litecg::BB &GetOrCreateBB(int bbID);
168     maple::litecg::BB &GetFirstBB();
169     maple::litecg::BB &CreateBB();
170     void AddPhiDesc(int bbID, PhiDesc &desc, std::map<int, std::vector<PhiDesc>> &bbID2Phis);
171     DerivedStatus CheckDerivedPhi(GateRef gate, std::set<GateRef> &vis);
172     void FindBaseRefForPhi(GateRef gate, const std::vector<GateRef> &phiIns);
173     maple::litecg::Type *ConvertLiteCGTypeFromGate(GateRef gate, bool isSigned = true) const;
174     maple::litecg::IntCmpCondition ConvertLiteCGPredicateFromICMP(ICmpCondition cond) const;
175     maple::litecg::FloatCmpCondition ConvertLiteCGPredicateFromFCMP(FCmpCondition cond) const;
176     void InitializeHandlers();
177     maple::litecg::Expr GetGlue(const std::vector<GateRef> &inList);
178     maple::litecg::Expr GetRTStubOffset(maple::litecg::Expr glue, int index);
179     maple::litecg::Type *ConvertLiteCGTypeFromVariableType(VariableType type) const;
180     maple::litecg::Type *GenerateFuncType(const std::vector<maple::litecg::Expr> &params,
181                                           const CallSignature *stubDescriptor);
182     maple::litecg::Type *GetFuncType(const CallSignature *stubDescriptor) const;
183     maple::litecg::Expr GetFunction(maple::litecg::BB &bb, maple::litecg::Expr glue, const CallSignature *signature,
184                                     maple::litecg::Expr rtbaseoffset, const std::string &realName = "") const;
185     bool IsOptimizedJSFunction() const;
186     bool IsOptimized() const;
187     CallExceptionKind GetCallExceptionKind(OpCode op, size_t index = SIZE_MAX) const;
188     maple::litecg::Expr GetRTStubOffset(maple::litecg::Expr glue, int index) const;
189     maple::litecg::Expr GetCoStubOffset(maple::litecg::Expr glue, int index) const;
190     maple::litecg::Expr GetBaselineStubOffset(maple::litecg::Expr glue, int index) const;
191     maple::litecg::Expr GetCallee(maple::litecg::BB &bb, const std::vector<GateRef> &inList,
192                                   const CallSignature *signature, const std::string &realName);
193     maple::litecg::Expr CanonicalizeToPtr(maple::litecg::Expr expr, maple::litecg::Type *type);
194     maple::litecg::Expr CanonicalizeToInt(GateRef gate);
195     int64_t GetBitWidthFromMachineType(MachineType machineType) const;
196     int LookupPredBB(GateRef start, int bbID);
197     maple::litecg::Expr GetBuiltinsStubOffset(maple::litecg::Expr glue);
198     void UpdateLeaveFrame(maple::litecg::Expr glue);
199     maple::litecg::Expr GetLeaveFrameOffset(maple::litecg::Expr glue);
200     maple::litecg::Expr CallingFp(bool isCaller);
201     maple::litecg::Expr GetBaseOffset(GateRef gate, maple::litecg::Expr glue);
202     maple::litecg::Expr GetBCDebugStubOffset(maple::litecg::Expr glue);
203     maple::litecg::Expr GetBCStubOffset(maple::litecg::Expr glue);
204     maple::litecg::Type *GetExperimentalDeoptTy();
205     maple::litecg::Function *GetExperimentalDeopt();
206     void GenDeoptEntry(std::string funcName);
207     void SaveFrameTypeOnFrame(maple::litecg::BB &bb, FrameType frameType);
208     maple::litecg::Expr ConvertToTagged(GateRef gate);
209     maple::litecg::Expr ConvertInt32ToTaggedInt(maple::litecg::Expr value);
210     maple::litecg::Expr ConvertBoolToTaggedBoolean(GateRef gate);
211     maple::litecg::Expr ConvertFloat64ToTaggedDouble(GateRef gate);
212     void SaveDeoptVregInfo(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo, maple::litecg::BB &bb,
213                            int32_t index, size_t curDepth, size_t shift, GateRef gate);
214     void SaveDeoptVregInfoWithI64(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo,
215                                   maple::litecg::BB &bb, int32_t index, size_t curDepth, size_t shift, GateRef gate);
216 
217     maple::litecg::ConvAttr ConvertCallAttr(const CallSignature::CallConv callConv);
218     void CollectExraCallSiteInfo(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo,
219                                  maple::litecg::Expr pcOffset, GateRef frameArgs);
220     void GenPrologue(maple::litecg::Function &function);
221     void AssistGenPrologue(const size_t reservedSlotsSize, FrameType frameType, maple::litecg::Function &function);
222     void SaveByteCodePcOnOptJSFuncFrame(maple::litecg::Var &value);
223     void SaveJSFuncOnOptJSFuncFrame(maple::litecg::Function &function, maple::litecg::Var &value, int funcIndex);
224     void SaveFrameTypeOnFrame(maple::litecg::Function &function, FrameType frameType);
225     bool IsInterpreted() const;
226     bool IsBaselineBuiltin() const;
227     void AddFunc();
228     void CollectDerivedRefInfo();
229     void HandleBB(const std::vector<GateRef> &bb, std::unordered_set<OpCode> &usedOpcodeSet);
IsLogEnabled()230     bool IsLogEnabled() const
231     {
232         return enableLog_;
233     }
234     void VisitBinaryOpWithOverflow(GateRef gate, GateRef e1, GateRef e2, maple::litecg::IntrinsicId intrinsicId);
235     void AddDerivedrefGate(GateRef gate, maple::litecg::Expr result);
236     maple::litecg::Expr GetDerivedrefExpr(GateRef gate);
237     DeoptBBInfo &GetOrCreateDeoptBBInfo(GateRef gate);
238 };
239 }  // namespace panda::ecmascript::kungfu
240 #endif  // ECMASCRIPT_COMPILER_LITECG_IR_BUILDER_H
241