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> ¶ms, 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