• 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_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/common_stubs.h"
27 #include "ecmascript/compiler/interpreter_stub.h"
28 #include "ecmascript/compiler/rt_call_signature.h"
29 #include "ecmascript/compiler/ir_builder.h"
30 #include "ecmascript/compiler/ir_module.h"
31 #include "ecmascript/jspandafile/method_literal.h"
32 #include "lmir_builder.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     const std::vector<std::vector<GateRef>> *scheduledGates_ {nullptr};
106     const Circuit *circuit_ {nullptr};
107     LMIRModule *lmirModule_ {nullptr};
108     const CompilationConfig *compCfg_ {nullptr};
109     CallSignature::CallConv callConv_ = CallSignature::CallConv::CCallConv;
110     bool enableLog_ {false};
111     bool enableOptInlining_ {false};
112     const panda::ecmascript::MethodLiteral *methodLiteral_ {nullptr};
113     const JSPandaFile *jsPandaFile_ {nullptr};
114     std::string funcName_;
115     GateAccessor acc_;
116     maple::litecg::LMIRBuilder *lmirBuilder_ {nullptr};
117     std::unordered_map<GateRef, maple::litecg::LiteCGValue> gate2Expr_;
118     std::unordered_map<OpCode, void (LiteCGIRBuilder::*)(GateRef gate)> opHandlers_;
119     std::set<OpCode> illegalOpHandlers_;
120     std::map<GateId, int> instID2bbID_;
121     std::map<int, maple::litecg::BB *> bbID2BB_;
122     int slotSize_ {-1};
123     maple::litecg::Type *slotType_ {nullptr};
124     std::map<int, std::vector<PhiDesc>> bbID2unmergedPhis_;
125 
126 #define DECLAREVISITLOWEROPCODE(name, signature) void Visit##name signature;
127     OPCODES(DECLAREVISITLOWEROPCODE)
128 #undef DECLAREVISITLOWEROPCODE
129 #define DECLAREHANDLELOWEROPCODE(name, ignore) void Handle##name(GateRef gate);
OPCODES(DECLAREHANDLELOWEROPCODE)130     OPCODES(DECLAREHANDLELOWEROPCODE)
131 #undef DECLAREHANDLELOWEROPCODE
132     void InsertUsedOpcodeSet(std::unordered_set<OpCode> &usedOpcodeSet, OpCode op)
133     {
134         if (enableLog_) {
135             usedOpcodeSet.insert(op);
136         }
137     }
138     void SaveGate2Expr(GateRef gate, maple::litecg::Expr expr);
139     maple::litecg::Expr GetExprFromGate(GateRef gate);
140     maple::litecg::Expr GetConstant(GateRef gate);
141     void BuildInstID2BBIDMap();
142     maple::litecg::BB &GetOrCreateBB(int bbID);
143     maple::litecg::BB &GetFirstBB();
144     maple::litecg::BB &CreateBB();
145     void AddPhiDesc(int bbID, PhiDesc &desc);
146     maple::litecg::Type *ConvertLiteCGTypeFromGate(GateRef gate, bool isSigned = true) const;
147     maple::litecg::IntCmpCondition ConvertLiteCGPredicateFromICMP(ICmpCondition cond) const;
148     maple::litecg::FloatCmpCondition ConvertLiteCGPredicateFromFCMP(FCmpCondition cond) const;
149     void InitializeHandlers();
150     maple::litecg::Expr GetGlue(const std::vector<GateRef> &inList);
151     maple::litecg::Expr GetRTStubOffset(maple::litecg::Expr glue, int index);
152     maple::litecg::Type *ConvertLiteCGTypeFromVariableType(VariableType type) const;
153     maple::litecg::Type *GenerateFuncType(const std::vector<maple::litecg::Expr> &params,
154                                           const CallSignature *stubDescriptor);
155     maple::litecg::Type *GetFuncType(const CallSignature *stubDescriptor) const;
156     maple::litecg::Expr GetFunction(maple::litecg::BB &bb, maple::litecg::Expr glue, const CallSignature *signature,
157                                     maple::litecg::Expr rtbaseoffset, const std::string &realName = "") const;
158     bool IsOptimizedJSFunction() const;
159     bool IsOptimized() const;
160     CallExceptionKind GetCallExceptionKind(size_t index, OpCode op) const;
161     maple::litecg::Expr GetRTStubOffset(maple::litecg::Expr glue, int index) const;
162     maple::litecg::Expr GetCoStubOffset(maple::litecg::Expr glue, int index) const;
163     maple::litecg::Expr GetCallee(maple::litecg::BB &bb, const std::vector<GateRef> &inList,
164                                   const CallSignature *signature, const std::string &realName);
165     maple::litecg::Expr CanonicalizeToPtr(maple::litecg::Expr expr, maple::litecg::Type *type);
166     maple::litecg::Expr CanonicalizeToInt(GateRef gate);
167     int64_t GetBitWidthFromMachineType(MachineType machineType) const;
168     int LookupPredBB(GateRef start, int bbID);
169     maple::litecg::Expr GetBuiltinsStubOffset(maple::litecg::Expr glue);
170     void UpdateLeaveFrame(maple::litecg::Expr glue);
171     maple::litecg::Expr GetLeaveFrameOffset(maple::litecg::Expr glue);
172     maple::litecg::Expr CallingFp(bool isCaller);
173     maple::litecg::Expr GetBaseOffset(GateRef gate, maple::litecg::Expr glue);
174     maple::litecg::Expr GetBCDebugStubOffset(maple::litecg::Expr glue);
175     maple::litecg::Expr GetBCStubOffset(maple::litecg::Expr glue);
176     maple::litecg::Type *GetExperimentalDeoptTy();
177     maple::litecg::Function *GetExperimentalDeopt();
178     void GenDeoptEntry(std::string funcName);
179     void SaveFrameTypeOnFrame(maple::litecg::BB &bb, FrameType frameType);
180     maple::litecg::Expr ConvertToTagged(GateRef gate);
181     maple::litecg::Expr ConvertInt32ToTaggedInt(maple::litecg::Expr value);
182     maple::litecg::Expr ConvertBoolToTaggedBoolean(GateRef gate);
183     maple::litecg::Expr ConvertFloat64ToTaggedDouble(GateRef gate);
184     void SaveDeoptVregInfo(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo, maple::litecg::BB &bb,
185                            int32_t index, size_t curDepth, size_t shift, GateRef gate);
186     void SaveDeoptVregInfoWithI64(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo,
187                                   maple::litecg::BB &bb, int32_t index, size_t curDepth, size_t shift, GateRef gate);
188     maple::litecg::Type *GetMachineRepType(MachineRep rep) const;
189 
190     maple::litecg::ConvAttr ConvertCallAttr(const CallSignature::CallConv callConv);
191     void CollectExraCallSiteInfo(std::unordered_map<int, maple::litecg::LiteCGValue> &deoptBundleInfo,
192                                  maple::litecg::Expr pcOffset, GateRef frameArgs);
193     void GenPrologue(maple::litecg::Function &function);
194     void SaveJSFuncOnOptJSFuncFrame(maple::litecg::Var &value);
195     void SaveFrameTypeOnFrame(FrameType frameType);
196     bool IsInterpreted() const;
197     void AddFunc();
IsLogEnabled()198     bool IsLogEnabled() const
199     {
200         return enableLog_;
201     }
202 };
203 }  // namespace panda::ecmascript::kungfu
204 #endif  // ECMASCRIPT_COMPILER_LITECG_IR_BUILDER_H
205