• 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 #include "ecmascript/compiler/llvm_ir_builder.h"
17 
18 #include <iostream>
19 #include <set>
20 #include <string>
21 
22 #include "ecmascript/compiler/circuit.h"
23 #include "ecmascript/compiler/compiler_macros.h"
24 #include "ecmascript/compiler/fast_stub.h"
25 #include "ecmascript/compiler/gate.h"
26 #include "ecmascript/compiler/stub_descriptor.h"
27 #include "ecmascript/frames.h"
28 #include "ecmascript/js_thread.h"
29 #include "llvm/IR/Instructions.h"
30 #include "llvm/Support/Host.h"
31 #include "securec.h"
32 #include "utils/logger.h"
33 
34 namespace panda::ecmascript::kungfu {
LLVMIRBuilder(const std::vector<std::vector<GateRef>> * schedule,const Circuit * circuit,LLVMStubModule * module,LLVMValueRef function,const CompilationConfig * cfg)35 LLVMIRBuilder::LLVMIRBuilder(const std::vector<std::vector<GateRef>> *schedule, const Circuit *circuit,
36                              LLVMStubModule *module, LLVMValueRef function, const CompilationConfig *cfg)
37     : compCfg_(cfg), schedule_(schedule), circuit_(circuit), module_(module->GetModule()),
38       function_(function), stubModule_(module)
39 {
40     builder_ = LLVMCreateBuilder();
41     context_ = LLVMGetGlobalContext();
42     bbIdMapBb_.clear();
43     if (circuit_->GetFrameType() == FrameType::INTERPRETER_FRAME) {
44         LLVMSetFunctionCallConv(function_, LLVMGHCCallConv);
45     } else if (circuit_->GetFrameType() == FrameType::OPTIMIZED_FRAME) {
46         LLVMSetFunctionCallConv(function_, LLVMWebKitJSCallConv);
47     }
48     LLVMSetGC(function_, "statepoint-example");
49     if (compCfg_->Is32Bit()) {
50         slotSize_ = panda::ecmascript::FrameConstants::ARM32_SLOT_SIZE;
51         slotType_ = LLVMInt32Type();
52     } else {
53         slotSize_ = panda::ecmascript::FrameConstants::AARCH64_SLOT_SIZE;
54         slotType_ = LLVMInt64Type();
55     }
56     if (compCfg_->Is32Bit()) {
57         // hard float instruction
58         LLVMAddTargetDependentFunctionAttr(function_, "target-features", "+armv8-a");
59     }
60 }
61 
~LLVMIRBuilder()62 LLVMIRBuilder::~LLVMIRBuilder()
63 {
64     if (builder_ != nullptr) {
65         LLVMDisposeBuilder(builder_);
66     }
67 }
68 
FindBasicBlock(GateRef gate) const69 int LLVMIRBuilder::FindBasicBlock(GateRef gate) const
70 {
71     for (size_t bbIdx = 0; bbIdx < schedule_->size(); bbIdx++) {
72         for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) {
73             GateRef tmp = (*schedule_)[bbIdx][instIdx - 1];
74             if (tmp == gate) {
75                 return bbIdx;
76             }
77         }
78     }
79     return -1;
80 }
81 
AssignHandleMap()82 void LLVMIRBuilder::AssignHandleMap()
83 {
84     opCodeHandleMap_ = {
85         {OpCode::STATE_ENTRY, &LLVMIRBuilder::HandleGoto},
86         {OpCode::RETURN, &LLVMIRBuilder::HandleReturn},
87         {OpCode::RETURN_VOID, &LLVMIRBuilder::HandleReturnVoid},
88         {OpCode::IF_BRANCH, &LLVMIRBuilder::HandleBranch},
89         {OpCode::SWITCH_BRANCH, &LLVMIRBuilder::HandleSwitch},
90         {OpCode::ORDINARY_BLOCK, &LLVMIRBuilder::HandleGoto},
91         {OpCode::IF_TRUE, &LLVMIRBuilder::HandleGoto},
92         {OpCode::IF_FALSE, &LLVMIRBuilder::HandleGoto},
93         {OpCode::SWITCH_CASE, &LLVMIRBuilder::HandleGoto},
94         {OpCode::MERGE, &LLVMIRBuilder::HandleGoto},
95         {OpCode::DEFAULT_CASE, &LLVMIRBuilder::HandleGoto},
96         {OpCode::LOOP_BEGIN, &LLVMIRBuilder::HandleGoto},
97         {OpCode::LOOP_BACK, &LLVMIRBuilder::HandleGoto},
98         {OpCode::VALUE_SELECTOR, &LLVMIRBuilder::HandlePhi},
99         {OpCode::RUNTIME_CALL, &LLVMIRBuilder::HandleRuntimeCall},
100         {OpCode::CALL, &LLVMIRBuilder::HandleCall},
101         {OpCode::BYTECODE_CALL, &LLVMIRBuilder::HandleCall},
102         {OpCode::ALLOCA, &LLVMIRBuilder::HandleAlloca},
103         {OpCode::ARG, &LLVMIRBuilder::HandleParameter},
104         {OpCode::CONSTANT, &LLVMIRBuilder::HandleConstant},
105         {OpCode::RELOCATABLE_DATA, &LLVMIRBuilder::HandleRelocatableData},
106         {OpCode::ZEXT_TO_INT16, &LLVMIRBuilder::HandleZExtInt},
107         {OpCode::ZEXT_TO_INT32, &LLVMIRBuilder::HandleZExtInt},
108         {OpCode::ZEXT_TO_INT64, &LLVMIRBuilder::HandleZExtInt},
109         {OpCode::SEXT_TO_INT32, &LLVMIRBuilder::HandleSExtInt},
110         {OpCode::SEXT_TO_INT64, &LLVMIRBuilder::HandleSExtInt},
111         {OpCode::TRUNC_TO_INT1, &LLVMIRBuilder::HandleCastIntXToIntY},
112         {OpCode::TRUNC_TO_INT32, &LLVMIRBuilder::HandleCastIntXToIntY},
113         {OpCode::REV, &LLVMIRBuilder::HandleIntRev},
114         {OpCode::ADD, &LLVMIRBuilder::HandleAdd},
115         {OpCode::SUB, &LLVMIRBuilder::HandleSub},
116         {OpCode::MUL, &LLVMIRBuilder::HandleMul},
117         {OpCode::FDIV, &LLVMIRBuilder::HandleFloatDiv},
118         {OpCode::SDIV, &LLVMIRBuilder::HandleIntDiv},
119         {OpCode::UDIV, &LLVMIRBuilder::HandleUDiv},
120         {OpCode::AND, &LLVMIRBuilder::HandleIntAnd},
121         {OpCode::OR, &LLVMIRBuilder::HandleIntOr},
122         {OpCode::XOR, &LLVMIRBuilder::HandleIntXor},
123         {OpCode::LSR, &LLVMIRBuilder::HandleIntLsr},
124         {OpCode::SLT, &LLVMIRBuilder::HandleCmp},
125         {OpCode::ULT, &LLVMIRBuilder::HandleCmp},
126         {OpCode::SLE, &LLVMIRBuilder::HandleCmp},
127         {OpCode::SGT, &LLVMIRBuilder::HandleCmp},
128         {OpCode::SGE, &LLVMIRBuilder::HandleCmp},
129         {OpCode::NE, &LLVMIRBuilder::HandleCmp},
130         {OpCode::EQ, &LLVMIRBuilder::HandleCmp},
131         {OpCode::LOAD, &LLVMIRBuilder::HandleLoad},
132         {OpCode::STORE, &LLVMIRBuilder::HandleStore},
133         {OpCode::SIGNED_INT_TO_FLOAT, &LLVMIRBuilder::HandleChangeInt32ToDouble},
134         {OpCode::FLOAT_TO_SIGNED_INT, &LLVMIRBuilder::HandleChangeDoubleToInt32},
135         {OpCode::TAGGED_TO_INT64, &LLVMIRBuilder::HandleChangeTaggedPointerToInt64},
136         {OpCode::INT64_TO_TAGGED, &LLVMIRBuilder::HandleChangeInt64ToTagged},
137         {OpCode::BITCAST, &LLVMIRBuilder::HandleBitCast},
138         {OpCode::LSL, &LLVMIRBuilder::HandleIntLsl},
139         {OpCode::SMOD, &LLVMIRBuilder::HandleMod},
140         {OpCode::FMOD, &LLVMIRBuilder::HandleMod},
141     };
142     opCodeHandleIgnore = {
143         OpCode::NOP, OpCode::CIRCUIT_ROOT, OpCode::DEPEND_ENTRY,
144         OpCode::FRAMESTATE_ENTRY, OpCode::RETURN_LIST, OpCode::THROW_LIST,
145         OpCode::CONSTANT_LIST, OpCode::ARG_LIST, OpCode::THROW,
146         OpCode::DEPEND_SELECTOR, OpCode::DEPEND_RELAY, OpCode::DEPEND_AND
147     };
148 }
149 
LLVMValueToString(LLVMValueRef val) const150 std::string LLVMIRBuilder::LLVMValueToString(LLVMValueRef val) const
151 {
152     char* msg = LLVMPrintValueToString(val);
153     std::string str(msg);
154     LLVMDisposeMessage(msg);
155     return str;
156 }
157 
Build()158 void LLVMIRBuilder::Build()
159 {
160     COMPILER_LOG(INFO) << "LLVM IR Builder Create Id Map of Blocks...";
161     for (size_t bbIdx = 0; bbIdx < schedule_->size(); bbIdx++) {
162         for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) {
163             GateId gateId = circuit_->GetId((*schedule_)[bbIdx][instIdx - 1]);
164             instIdMapBbId_[gateId] = bbIdx;
165         }
166     }
167     COMPILER_LOG(INFO) << "LLVM IR Builder Visit Gate...";
168 
169     AssignHandleMap();
170     for (size_t bbIdx = 0; bbIdx < (*schedule_).size(); bbIdx++) {
171         OperandsVector predecessors;
172         for (auto in : circuit_->GetInVector((*schedule_)[bbIdx][0])) {
173             if (!circuit_->GetOpCode(in).IsState()) {
174                 continue;
175             }
176             predecessors.insert(instIdMapBbId_[circuit_->GetId(in)]);
177         }
178         VisitBlock(bbIdx, predecessors);
179 
180         for (size_t instIdx = (*schedule_)[bbIdx].size(); instIdx > 0; instIdx--) {
181             GateRef gate = (*schedule_)[bbIdx][instIdx - 1];
182             std::vector<GateRef> ins = circuit_->GetInVector(gate);
183             std::vector<GateRef> outs = circuit_->GetOutVector(gate);
184 #if ECMASCRIPT_ENABLE_COMPILER_LOG
185             circuit_->Print(gate);
186 #endif
187             auto found = opCodeHandleMap_.find(circuit_->GetOpCode(gate));
188             if (found != opCodeHandleMap_.end()) {
189                 (this->*(found->second))(gate);
190                 continue;
191             }
192             if (opCodeHandleIgnore.find(circuit_->GetOpCode(gate)) == opCodeHandleIgnore.end()) {
193                 LOG_ECMA(ERROR) << "The gate below need to be translated ";
194                 circuit_->Print(gate);
195                 UNREACHABLE();
196             }
197         }
198     }
199     End();
200 }
201 
EnsureBasicBlock(int id)202 BasicBlock *LLVMIRBuilder::EnsureBasicBlock(int id)
203 {
204     BasicBlock *bb = nullptr;
205     if (bbIdMapBb_.count(id) == 0) {
206         auto newBB = std::make_unique<BasicBlock>(id);
207         bb = newBB.get();
208         bbIdMapBb_[id] = std::move(newBB);
209     } else {
210         bb = bbIdMapBb_[id].get();
211     }
212     return bb;
213 }
214 
StartBuilder(BasicBlock * bb) const215 void LLVMIRBuilder::StartBuilder(BasicBlock *bb) const
216 {
217     EnsureBasicBlock(bb);
218     LLVMTFBuilderBasicBlockImpl *impl = bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
219     if ((impl == nullptr) || (impl->llvm_bb_ == nullptr)) {
220         COMPILER_LOG(ERROR) << "StartBuilder failed ";
221         return;
222     }
223     impl->started = true;
224     bb->SetImpl(impl);
225     COMPILER_LOG(DEBUG) << "Basicblock id :" << bb->GetId() << "impl:" << bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
226     LLVMPositionBuilderAtEnd(builder_, impl->llvm_bb_);
227 }
228 
ProcessPhiWorkList()229 void LLVMIRBuilder::ProcessPhiWorkList()
230 {
231     for (BasicBlock *bb : phiRebuildWorklist_) {
232         auto impl = bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
233         for (auto &e : impl->not_merged_phis) {
234             BasicBlock *pred = e.pred;
235             if (impl->started == 0) {
236                 COMPILER_LOG(ERROR) << " ProcessPhiWorkList error hav't start ";
237                 return;
238             }
239             LLVMValueRef value = gateToLLVMMaps_[e.operand];
240             if (LLVMTypeOf(value) != LLVMTypeOf(e.phi)) {
241                 COMPILER_LOG(ERROR) << " ProcessPhiWorkList LLVMTypeOf don't match error ";
242             }
243             LLVMBasicBlockRef llvmBB = EnsureBasicBlock(pred);
244             LLVMAddIncoming(e.phi, &value, &llvmBB, 1);
245         }
246         impl->not_merged_phis.clear();
247     }
248     phiRebuildWorklist_.clear();
249 }
250 
EndCurrentBlock() const251 void LLVMIRBuilder::EndCurrentBlock() const
252 {
253     LLVMTFBuilderBasicBlockImpl *impl = currentBb_->GetImpl<LLVMTFBuilderBasicBlockImpl>();
254     impl->ended = true;
255 }
256 
End()257 void LLVMIRBuilder::End()
258 {
259     ASSERT(!!currentBb_);
260     EndCurrentBlock();
261     ProcessPhiWorkList();
262     for (auto &it : bbIdMapBb_) {
263         it.second->ResetImpl<LLVMTFBuilderBasicBlockImpl>();
264     }
265 }
266 
EnsureBasicBlockImpl(BasicBlock * bb) const267 LLVMTFBuilderBasicBlockImpl *LLVMIRBuilder::EnsureBasicBlockImpl(BasicBlock *bb) const
268 {
269     if (bb->GetImpl<LLVMTFBuilderBasicBlockImpl>()) {
270         return bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
271     }
272     auto impl = std::make_unique<LLVMTFBuilderBasicBlockImpl>();
273     bb->SetImpl(impl.release());
274     return bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
275 }
276 
GenPrologue(LLVMModuleRef & module,LLVMBuilderRef & builder)277 void LLVMIRBuilder::GenPrologue(LLVMModuleRef &module, LLVMBuilderRef &builder)
278 {
279     /* current frame for x86_64 system:
280     for optimized entry frame
281          0    pre   <-- rbp register
282         -8    type
283         -16   current sp before call other function
284         -24   pre frame thread fp
285     for optimized frame
286          0    pre rbp  <-- rbp
287         -8    type
288         -16   current sp before call other function
289 
290      for 32 arm bit system:
291         not support
292      for arm64 system
293      for optimized entry frame
294          0    pre rbp  <-- x29 register
295         -8    type
296         -16   current sp before call other function
297         -24   pre frame thread fp
298     for optimized frame
299         0    pre rbp  <-- rbp
300         -8    type
301         -16   current sp before call other function
302     */
303     if (compCfg_->Is32Bit()) {
304         return;
305     }
306     auto frameType = circuit_->GetFrameType();
307     if (frameType != FrameType::OPTIMIZED_FRAME) {
308         return;
309     }
310     LLVMAddTargetDependentFunctionAttr(function_, "frame-pointer", "all");
311 
312     LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false);
313 
314     LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder, llvmFpAddr, slotType_, "cast_int_t");
315     LLVMValueRef frameTypeSlotAddr = LLVMBuildSub(builder, frameAddr, LLVMConstInt(slotType_,
316         slotSize_, false), "");
317     LLVMValueRef addr = LLVMBuildIntToPtr(builder, frameTypeSlotAddr,
318         LLVMPointerType(slotType_, 0), "frameType.Addr");
319 
320     if (frameType == panda::ecmascript::FrameType::OPTIMIZED_FRAME) {
321         LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "0");
322     } else if (frameType == panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME) {
323         LLVMAddTargetDependentFunctionAttr(function_, "js-stub-call", "1");
324     } else {
325         LOG_ECMA(FATAL) << "frameType interpret type error !";
326         ASSERT_PRINT(static_cast<uintptr_t>(frameType), "is not support !");
327     }
328 
329     LLVMValueRef llvmFrameType = LLVMConstInt(slotType_, static_cast<uintptr_t>(frameType), 0);
330     LLVMValueRef value = LLVMBuildStore(builder_, llvmFrameType, addr);
331 
332     if (frameType != panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME) {
333         return;
334     }
335 
336     LLVMValueRef glue = LLVMGetParam(function_, 0);
337     LLVMTypeRef glue_type = LLVMTypeOf(glue);
338     LLVMValueRef rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME), 0);
339     LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
340     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(slotType_, 0), "");
341     LLVMValueRef threadFpValue = LLVMBuildLoad(builder_, rtbaseAddr, "");
342     addr = LLVMBuildAdd(builder, frameAddr, LLVMConstInt(slotType_,
343         FrameConstants::INTERPER_FRAME_FP_TO_FP_DELTA * slotSize_, true), "");
344     value = LLVMBuildStore(builder_, threadFpValue,
345         LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "cast"));
346     LOG_ECMA(DEBUG) << "store value:" << value << " "
347                 << "value type" << LLVMTypeOf(value);
348 }
349 
CallingFp(LLVMModuleRef & module,LLVMBuilderRef & builder,bool isCaller)350 LLVMValueRef LLVMIRBuilder::CallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder, bool isCaller)
351 {
352     /* 0:calling 1:its caller */
353     std::vector<LLVMValueRef> args = {LLVMConstInt(LLVMInt32Type(), 0, isCaller)};
354     auto fn = LLVMGetNamedFunction(module, "llvm.frameaddress.p0i8");
355     if (!fn) {
356         /* init instrinsic function declare */
357         LLVMTypeRef paramTys1[] = {
358             LLVMInt32Type(),
359         };
360         auto fnTy = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), paramTys1, 1, 0);
361         fn = LLVMAddFunction(module, "llvm.frameaddress.p0i8", fnTy);
362     }
363     LLVMValueRef fAddrRet = LLVMBuildCall(builder, fn, args.data(), 1, "");
364     return fAddrRet;
365 }
366 
ReadRegister(LLVMModuleRef & module,LLVMBuilderRef & builder,LLVMMetadataRef meta)367 LLVMValueRef LLVMIRBuilder::ReadRegister(LLVMModuleRef &module, LLVMBuilderRef &builder,
368     LLVMMetadataRef meta)
369 {
370     std::vector<LLVMValueRef> args = {LLVMMetadataAsValue(context_, meta)};
371     auto fn = LLVMGetNamedFunction(module, "llvm.read_register.i64");
372     if (!fn) {
373         /* init instrinsic function declare */
374         LLVMTypeRef paramTys1[] = {
375             GetMachineRepType(MachineRep::K_META),
376         };
377         auto fnTy = LLVMFunctionType(LLVMInt64Type(), paramTys1, 1, 0);
378         fn = LLVMAddFunction(module, "llvm.read_register.i64", fnTy);
379     }
380     LLVMValueRef fAddrRet = LLVMBuildCall(builder_, fn, args.data(), 1, "");
381     return fAddrRet;
382 }
383 
EnsureBasicBlock(BasicBlock * bb) const384 LLVMBasicBlockRef LLVMIRBuilder::EnsureBasicBlock(BasicBlock *bb) const
385 {
386     LLVMTFBuilderBasicBlockImpl *impl = EnsureBasicBlockImpl(bb);
387     if (impl->llvm_bb_) {
388         return impl->llvm_bb_;
389     }
390 
391     std::string buf = "B" + std::to_string(bb->GetId());
392     LLVMBasicBlockRef llvmBB = LLVMAppendBasicBlock(function_, buf.c_str());
393     impl->llvm_bb_ = llvmBB;
394     impl->continuation = llvmBB;
395     bb->SetImpl(impl);
396     COMPILER_LOG(DEBUG) << "create LLVMBB = " << buf << " impl:" << bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
397     return llvmBB;
398 }
399 
GetMachineRepType(MachineRep rep) const400 LLVMTypeRef LLVMIRBuilder::GetMachineRepType(MachineRep rep) const
401 {
402     LLVMTypeRef dstType;
403     switch (rep) {
404         case MachineRep::K_BIT:
405             dstType = LLVMInt1TypeInContext(context_);
406             break;
407         case MachineRep::K_WORD8:
408             dstType = LLVMInt8TypeInContext(context_);
409             break;
410         case MachineRep::K_WORD16:
411             dstType = LLVMInt16TypeInContext(context_);
412             break;
413         case MachineRep::K_WORD32:
414             dstType = LLVMInt32TypeInContext(context_);
415             break;
416         case MachineRep::K_FLOAT64:
417             dstType = LLVMDoubleTypeInContext(context_);
418             break;
419         case MachineRep::K_WORD64:
420             dstType = LLVMInt64TypeInContext(context_);
421             break;
422         case MachineRep::K_PTR_1:
423             if (compCfg_->Is32Bit()) {
424                 dstType = LLVMVectorType(LLVMPointerType(LLVMInt8Type(), 1), 2); // 2: packed vector type
425             } else {
426                 dstType = LLVMPointerType(LLVMInt64TypeInContext(context_), 1);
427             }
428             break;
429         case MachineRep::K_META:
430             dstType = LLVMMetadataTypeInContext(context_);
431             break;
432         default:
433             UNREACHABLE();
434             break;
435     }
436     return dstType;
437 }
438 
HandleCall(GateRef gate)439 void LLVMIRBuilder::HandleCall(GateRef gate)
440 {
441     std::vector<GateRef> ins = circuit_->GetInVector(gate);
442     if (circuit_->GetOpCode(gate) == OpCode::CALL) {
443         VisitCall(gate, ins);
444     } else {
445         VisitBytecodeCall(gate, ins);
446     }
447 }
448 
HandleRuntimeCall(GateRef gate)449 void LLVMIRBuilder::HandleRuntimeCall(GateRef gate)
450 {
451     std::vector<GateRef> ins = circuit_->GetInVector(gate);
452     VisitRuntimeCall(gate, ins);
453 }
454 
VisitRuntimeCall(GateRef gate,const std::vector<GateRef> & inList)455 void LLVMIRBuilder::VisitRuntimeCall(GateRef gate, const std::vector<GateRef> &inList)
456 {
457     int paraStartIndex = 3;
458     ASSERT(stubModule_ != nullptr);
459     LLVMValueRef callee;
460     LLVMValueRef rtoffset;
461     LLVMTypeRef rtfuncType = stubModule_->GetStubFunctionType(FAST_STUB_ID(CallRuntimeTrampoline));
462     LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0);
463     LLVMValueRef glue = gateToLLVMMaps_[inList[2]];  // 2 : 2 means skip two input gates (target glue)
464     LLVMTypeRef glue_type = LLVMTypeOf(glue);
465     rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::RUNTIME_FUNCTIONS) +
466                                 (FAST_STUB_ID(CallRuntimeTrampoline) - FAST_STUB_MAXCOUNT) * slotSize_, 0);
467     LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
468     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(glue_type, 0), "");
469     LLVMValueRef llvmAddr = LLVMBuildLoad(builder_, rtbaseAddr, "");
470     callee = LLVMBuildIntToPtr(builder_, llvmAddr, rtfuncTypePtr, "cast");
471     // 16 : params limit
472     LLVMValueRef params[16];
473     params[0] = glue;
474     int index = circuit_->GetBitField(inList[1]);
475     params[1] = LLVMConstInt(LLVMInt64Type(), index - FAST_STUB_MAXCOUNT, 0);
476     params[2] = LLVMConstInt(LLVMInt64Type(), 2882400000, 0); // 2882400000: default statepoint ID
477     params[3] = LLVMConstInt(LLVMInt64Type(), inList.size() - paraStartIndex, 0); // 3 : 3 means fourth parameter
478     for (size_t paraIdx = paraStartIndex; paraIdx < inList.size(); ++paraIdx) {
479         GateRef gateTmp = inList[paraIdx];
480         params[paraIdx + 1] = gateToLLVMMaps_[gateTmp];
481     }
482     if (callee == nullptr) {
483         COMPILER_LOG(ERROR) << "callee nullptr";
484         return;
485     }
486     LLVMValueRef runtimeCall = LLVMBuildCall(builder_, callee, params, inList.size() + 1, "");
487     LLVMSetInstructionCallConv(runtimeCall, LLVMWebKitJSCallConv);
488     gateToLLVMMaps_[gate] = runtimeCall;
489 }
490 
GetCurrentSP()491 LLVMValueRef LLVMIRBuilder::GetCurrentSP()
492 {
493     LLVMMetadataRef meta;
494     if (compCfg_->IsAmd64()) {
495         meta = LLVMMDStringInContext2(context_, "rsp", 4);   // 4 : 4 means len of "rsp"
496     } else {
497         meta = LLVMMDStringInContext2(context_, "sp", 3);   // 3 : 3 means len of "sp"
498     }
499     LLVMMetadataRef metadataNode = LLVMMDNodeInContext2(context_, &meta, 1);
500     LLVMValueRef spValue = ReadRegister(module_, builder_, metadataNode);
501     return spValue;
502 }
503 
SaveCurrentSP()504 void LLVMIRBuilder::SaveCurrentSP()
505 {
506     if (circuit_->GetFrameType() != FrameType::OPTIMIZED_FRAME) {
507         return;
508     }
509     if (compCfg_->Is64Bit()) {
510         LLVMValueRef llvmFpAddr = CallingFp(module_, builder_, false);
511         LLVMValueRef frameAddr = LLVMBuildPtrToInt(builder_, llvmFpAddr, slotType_, "cast_int_t");
512         LLVMValueRef frameSpSlotAddr = LLVMBuildSub(builder_, frameAddr, LLVMConstInt(slotType_,
513             3 * slotSize_, false), ""); // 3: type + threadsp + current sp
514         LLVMValueRef addr = LLVMBuildIntToPtr(builder_, frameSpSlotAddr,
515                                               LLVMPointerType(slotType_, 0), "frameCallSiteSP.Addr");
516         LLVMMetadataRef meta;
517         if (compCfg_->IsAmd64()) {
518             meta = LLVMMDStringInContext2(context_, "rsp", 4);   // 4 : 4 means len of "rsp"
519         } else {
520             meta = LLVMMDStringInContext2(context_, "sp", 3);   // 3 : 3 means len of "sp"
521         }
522         LLVMMetadataRef metadataNode = LLVMMDNodeInContext2(context_, &meta, 1);
523         LLVMValueRef spValue = ReadRegister(module_, builder_, metadataNode);
524         LLVMBuildStore(builder_, spValue, addr);
525     }
526 }
527 
GetCurrentSPFrameAddr()528 LLVMValueRef LLVMIRBuilder::GetCurrentSPFrameAddr()
529 {
530     LLVMValueRef glue = LLVMGetParam(function_, 0);
531     LLVMTypeRef glue_type = LLVMTypeOf(glue);
532     LLVMValueRef rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::CURRENT_FRAME), 0);
533     LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
534     return rtbaseoffset;
535 }
536 
GetCurrentSPFrame()537 LLVMValueRef LLVMIRBuilder::GetCurrentSPFrame()
538 {
539     LLVMValueRef addr = GetCurrentSPFrameAddr();
540     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "");
541     LLVMValueRef currentSpFrame = LLVMBuildLoad(builder_, rtbaseAddr, "");
542     return currentSpFrame;
543 }
544 
SetCurrentSPFrame(LLVMValueRef sp)545 void LLVMIRBuilder::SetCurrentSPFrame(LLVMValueRef sp)
546 {
547     LLVMValueRef addr = GetCurrentSPFrameAddr();
548     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, addr, LLVMPointerType(slotType_, 0), "");
549     LLVMBuildStore(builder_, sp, rtbaseAddr);
550 }
551 
GetCurrentFrameType(LLVMValueRef currentSpFrameAddr)552 LLVMValueRef LLVMIRBuilder::GetCurrentFrameType(LLVMValueRef currentSpFrameAddr)
553 {
554     LLVMValueRef tmp = LLVMBuildSub(builder_, currentSpFrameAddr, LLVMConstInt(slotType_, slotSize_, 1), "");
555     LLVMValueRef frameTypeAddr = LLVMBuildIntToPtr(builder_, tmp, LLVMPointerType(LLVMInt64Type(), 0), "");
556     LLVMValueRef frameType = LLVMBuildLoad(builder_, frameTypeAddr, "");
557     return frameType;
558 }
559 
VisitCall(GateRef gate,const std::vector<GateRef> & inList)560 void LLVMIRBuilder::VisitCall(GateRef gate, const std::vector<GateRef> &inList)
561 {
562     int paraStartIndex = 3;
563     int index = circuit_->GetBitField(inList[1]);
564     ASSERT(stubModule_ != nullptr);
565     LLVMValueRef callee;
566     LLVMValueRef rtoffset;
567     StubDescriptor *calleeDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(index);
568     LLVMTypeRef rtfuncType = stubModule_->GetStubFunctionType(index);
569     LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0);
570     LLVMValueRef glue = gateToLLVMMaps_[inList[2]];  // 2 : 2 means skip two input gates (target glue)
571     LLVMTypeRef glue_type = LLVMTypeOf(glue);
572     // runtime case
573     if (calleeDescriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB ||
574         calleeDescriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB_NO_GC) {
575         rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::RUNTIME_FUNCTIONS) +
576                                 (index - FAST_STUB_MAXCOUNT) * slotSize_, 0);
577     } else {
578         rtoffset = LLVMConstInt(glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::FAST_STUB_ENTRIES) +
579                                 index * slotSize_, 0);
580     }
581     LLVMValueRef rtbaseoffset = LLVMBuildAdd(builder_, glue, rtoffset, "");
582     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(glue_type, 0), "");
583     LLVMValueRef llvmAddr = LLVMBuildLoad(builder_, rtbaseAddr, "");
584     callee = LLVMBuildIntToPtr(builder_, llvmAddr, rtfuncTypePtr, "cast");
585     // 16 : params limit
586     LLVMValueRef params[16];
587     for (size_t paraIdx = paraStartIndex; paraIdx < inList.size(); ++paraIdx) {
588         GateRef gateTmp = inList[paraIdx];
589         params[paraIdx - paraStartIndex] = gateToLLVMMaps_[gateTmp];
590     }
591     if (callee == nullptr) {
592         COMPILER_LOG(ERROR) << "callee nullptr";
593         return;
594     }
595     if (compCfg_->Is32Bit() || compCfg_->Is64Bit()) {
596         SaveCurrentSP();
597     }
598 
599     gateToLLVMMaps_[gate] = LLVMBuildCall(builder_, callee, params, inList.size() - paraStartIndex, "");
600     return;
601 }
602 
VisitBytecodeCall(GateRef gate,const std::vector<GateRef> & inList)603 void LLVMIRBuilder::VisitBytecodeCall(GateRef gate, const std::vector<GateRef> &inList)
604 {
605     int paraStartIndex = 3;
606     LLVMValueRef opcodeOffset = gateToLLVMMaps_[inList[1]];
607     ASSERT(stubModule_ != nullptr);
608     LLVMValueRef callee;
609     LLVMTypeRef rtfuncType = stubModule_->GetStubFunctionType(CallStubId::NAME_BytecodeHandler);
610     LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0);
611     LLVMValueRef glue = gateToLLVMMaps_[inList[2]];  // 2 : 2 means skip two input gates (target glue)
612     LLVMTypeRef glue_type = LLVMTypeOf(glue);
613     LLVMValueRef bytecodeoffset = LLVMConstInt(
614         glue_type, compCfg_->GetGlueOffset(JSThread::GlueID::BYTECODE_HANDLERS), 0);
615     LLVMValueRef rtbaseoffset = LLVMBuildAdd(
616         builder_, glue, LLVMBuildAdd(builder_, bytecodeoffset, opcodeOffset, ""), "");
617     LLVMValueRef rtbaseAddr = LLVMBuildIntToPtr(builder_, rtbaseoffset, LLVMPointerType(glue_type, 0), "");
618     LLVMValueRef llvmAddr = LLVMBuildLoad(builder_, rtbaseAddr, "");
619     callee = LLVMBuildIntToPtr(builder_, llvmAddr, rtfuncTypePtr, "cast");
620     // 16 : params limit
621     LLVMValueRef params[16];
622     for (size_t paraIdx = paraStartIndex; paraIdx < inList.size(); ++paraIdx) {
623         GateRef gateTmp = inList[paraIdx];
624         params[paraIdx - paraStartIndex] = gateToLLVMMaps_[gateTmp];
625     }
626     LLVMValueRef call = LLVMBuildCall(builder_, callee, params, inList.size() - paraStartIndex, "");
627     LLVMSetTailCall(call, true);
628     const char *attrName = "gc-leaf-function";
629     const char *attrValue = "true";
630     LLVMAttributeRef llvmAttr = LLVMCreateStringAttribute(context_, attrName, strlen(attrName), attrValue,
631                                                           strlen(attrValue));
632     LLVMAddCallSiteAttribute(call, LLVMAttributeFunctionIndex, llvmAttr);
633     LLVMSetInstructionCallConv(call, LLVMGHCCallConv);
634     gateToLLVMMaps_[gate] = call;
635 }
636 
HandleAlloca(GateRef gate)637 void LLVMIRBuilder::HandleAlloca(GateRef gate)
638 {
639     return VisitAlloca(gate);
640 }
641 
VisitAlloca(GateRef gate)642 void LLVMIRBuilder::VisitAlloca(GateRef gate)
643 {
644     uint64_t machineRep = circuit_->GetBitField(gate);
645     LLVMTypeRef dataType = GetMachineRepType(static_cast<MachineRep>(machineRep));
646     COMPILER_LOG(DEBUG) << LLVMPrintTypeToString(dataType);
647     COMPILER_LOG(DEBUG) << LLVMPrintTypeToString(ConvertLLVMTypeFromGate(gate));
648     gateToLLVMMaps_[gate] = LLVMBuildPtrToInt(builder_, LLVMBuildAlloca(builder_, dataType, ""),
649                                               ConvertLLVMTypeFromGate(gate), "");
650 }
651 
HandlePhi(GateRef gate)652 void LLVMIRBuilder::HandlePhi(GateRef gate)
653 {
654     std::vector<GateRef> ins = circuit_->GetInVector(gate);
655     VisitPhi(gate, ins);
656 }
657 
VisitPhi(GateRef gate,const std::vector<GateRef> & srcGates)658 void LLVMIRBuilder::VisitPhi(GateRef gate, const std::vector<GateRef> &srcGates)
659 {
660     LLVMTypeRef type = ConvertLLVMTypeFromGate(gate);
661     LLVMValueRef phi = LLVMBuildPhi(builder_, type, "");
662     std::vector<GateRef> relMergeIns = circuit_->GetInVector(srcGates[0]);
663     bool addToPhiRebuildList = false;
664     for (int i = 1; i < static_cast<int>(srcGates.size()); i++) {
665         GateId gateId = circuit_->GetId(relMergeIns[i - 1]);
666         int bbIdx = instIdMapBbId_[gateId];
667         COMPILER_LOG(DEBUG) << "srcGate: " << srcGates[i] << " dominated gateId:" << gateId << "dominated bbIdx: " <<
668             bbIdx;
669         int cnt = bbIdMapBb_.count(bbIdx);
670         // if cnt = 0 means bb with current bbIdx hasn't been created
671         if (cnt > 0) {
672             BasicBlock *bb = bbIdMapBb_[bbIdx].get();
673             COMPILER_LOG(DEBUG) << "bb : " << bb;
674             if (bb == nullptr) {
675                 COMPILER_LOG(ERROR) << "VisitPhi failed BasicBlock nullptr";
676                 return;
677             }
678             LLVMTFBuilderBasicBlockImpl *impl = bb->GetImpl<LLVMTFBuilderBasicBlockImpl>();
679             if (impl == nullptr) {
680                 COMPILER_LOG(ERROR) << "VisitPhi failed impl nullptr";
681                 return;
682             }
683             LLVMBasicBlockRef llvmBB = EnsureBasicBlock(bb);  // The llvm bb
684             LLVMValueRef value = gateToLLVMMaps_[srcGates[i]];
685 
686             if (impl->started) {
687                 LLVMAddIncoming(phi, &value, &llvmBB, 1);
688             } else {
689                 addToPhiRebuildList = true;
690                 impl = currentBb_->GetImpl<LLVMTFBuilderBasicBlockImpl>();
691                 impl->not_merged_phis.emplace_back();
692                 auto &not_merged_phi = impl->not_merged_phis.back();
693                 not_merged_phi.phi = phi;
694                 not_merged_phi.pred = bb;
695                 not_merged_phi.operand = srcGates[i];
696             }
697         } else {
698             addToPhiRebuildList = true;
699         }
700         if (addToPhiRebuildList == true) {
701             phiRebuildWorklist_.push_back(currentBb_);
702         }
703         gateToLLVMMaps_[gate] = phi;
704     }
705 }
706 
VisitReturn(GateRef gate,GateRef popCount,const std::vector<GateRef> & operands)707 void LLVMIRBuilder::VisitReturn(GateRef gate, GateRef popCount, const std::vector<GateRef> &operands)
708 {
709     // [STATE] [DEPEND] [VALUE] [RETURN_LIST]
710     GateRef operand = operands[2];  // 2: skip 2 in gate that are not data gate
711     COMPILER_LOG(DEBUG) << " gate: " << gate << " popCount: " << popCount;
712     COMPILER_LOG(DEBUG) << " return: " << operand << " gateId: " << circuit_->GetId(operand);
713     LLVMValueRef returnValue = gateToLLVMMaps_[operand];
714     COMPILER_LOG(DEBUG) << LLVMValueToString(returnValue);
715     LLVMBuildRet(builder_, returnValue);
716 }
717 
HandleReturn(GateRef gate)718 void LLVMIRBuilder::HandleReturn(GateRef gate)
719 {
720     std::vector<GateRef> ins = circuit_->GetInVector(gate);
721     VisitReturn(gate, 1, ins);
722 }
723 
VisitReturnVoid(GateRef gate)724 void LLVMIRBuilder::VisitReturnVoid(GateRef gate)
725 {
726     // [STATE] [DEPEND] [VALUE] [RETURN_LIST]
727     COMPILER_LOG(DEBUG) << " gate: " << gate;
728     LLVMBuildRetVoid(builder_);
729 }
730 
HandleReturnVoid(GateRef gate)731 void LLVMIRBuilder::HandleReturnVoid(GateRef gate)
732 {
733     VisitReturnVoid(gate);
734 }
735 
VisitBlock(int gate,const OperandsVector & predecessors)736 void LLVMIRBuilder::VisitBlock(int gate, const OperandsVector &predecessors)  // NOLINTNEXTLINE(misc-unused-parameters)
737 {
738     COMPILER_LOG(DEBUG) << " BBIdx:" << gate;
739     BasicBlock *bb = EnsureBasicBlock(gate);
740     if (bb == nullptr) {
741         COMPILER_LOG(ERROR) << " block create failed ";
742         return;
743     }
744     currentBb_ = bb;
745     LLVMBasicBlockRef llvmbb = EnsureBasicBlock(bb);
746     StartBuilder(bb);
747     COMPILER_LOG(DEBUG) << "predecessors :";
748     for (int predecessor : predecessors) {
749         BasicBlock *pre = EnsureBasicBlock(predecessor);
750         if (pre == nullptr) {
751             COMPILER_LOG(ERROR) << " block setup failed, predecessor:%d nullptr" << predecessor;
752             return;
753         }
754         LLVMBasicBlockRef llvmpre = EnsureBasicBlock(pre);
755         COMPILER_LOG(DEBUG) << "  " << predecessor;
756         LLVMMoveBasicBlockBefore(llvmpre, llvmbb);
757     }
758     if (gate == 0) { // insert prologue
759         GenPrologue(module_, builder_);
760     }
761 }
762 
HandleGoto(GateRef gate)763 void LLVMIRBuilder::HandleGoto(GateRef gate)
764 {
765     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
766     int block = instIdMapBbId_[circuit_->GetId(gate)];
767     int bbOut = instIdMapBbId_[circuit_->GetId(outs[0])];
768     switch (circuit_->GetOpCode(gate)) {
769         case OpCode::MERGE:
770         case OpCode::LOOP_BEGIN: {
771             for (int i = 0; i < static_cast<int>(outs.size()); i++) {
772                 bbOut = instIdMapBbId_[circuit_->GetId(outs[i])];
773                 VisitGoto(block, bbOut);
774             }
775             break;
776         }
777         default: {
778             VisitGoto(block, bbOut);
779             break;
780         }
781     }
782 }
783 
VisitGoto(int block,int bbOut)784 void LLVMIRBuilder::VisitGoto(int block, int bbOut)
785 {
786     if (block == bbOut) {
787         return;
788     }
789     BasicBlock *bb = EnsureBasicBlock(bbOut);
790     if (bb == nullptr) {
791         COMPILER_LOG(ERROR) << " block is nullptr ";
792         return;
793     }
794     llvm::BasicBlock *self = llvm::unwrap(EnsureBasicBlock(bbIdMapBb_[block].get()));
795     llvm::BasicBlock *out = llvm::unwrap(EnsureBasicBlock(bbIdMapBb_[bbOut].get()));
796     llvm::BranchInst::Create(out, self);
797     EndCurrentBlock();
798 }
799 
HandleConstant(GateRef gate)800 void LLVMIRBuilder::HandleConstant(GateRef gate)
801 {
802     std::bitset<64> value = circuit_->GetBitField(gate); // 64: bit width
803     VisitConstant(gate, value);
804 }
805 
VisitConstant(GateRef gate,std::bitset<64> value)806 void LLVMIRBuilder::VisitConstant(GateRef gate, std::bitset<64> value) // 64: bit width
807 {
808     LLVMValueRef llvmValue = nullptr;
809     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
810     if (machineType == MachineType::I32) {
811         llvmValue = LLVMConstInt(LLVMInt32Type(), value.to_ulong(), 0);
812     } else if (machineType == MachineType::I64) {
813         llvmValue = LLVMConstInt(LLVMInt64Type(), value.to_ullong(), 0);
814         LLVMTypeRef type = ConvertLLVMTypeFromGate(gate);
815         if (LLVMGetTypeKind(type) == LLVMPointerTypeKind) {
816             llvmValue = LLVMBuildIntToPtr(builder_, llvmValue, type, "");
817         } else if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
818             LLVMValueRef tmp1Value =
819                     LLVMBuildLShr(builder_, llvmValue, LLVMConstInt(LLVMInt32Type(), 32, 0), ""); // 32: offset
820             LLVMValueRef tmp2Value = LLVMBuildIntCast(builder_, llvmValue, LLVMInt32Type(), ""); // low
821             LLVMValueRef emptyValue = LLVMGetUndef(type);
822             tmp1Value = LLVMBuildIntToPtr(builder_, tmp1Value, LLVMPointerType(LLVMInt8Type(), 1), "");
823             tmp2Value = LLVMBuildIntToPtr(builder_, tmp2Value, LLVMPointerType(LLVMInt8Type(), 1), "");
824             llvmValue = LLVMBuildInsertElement(
825                 builder_, emptyValue, tmp2Value, LLVMConstInt(LLVMInt32Type(), 0, 0), "");
826             llvmValue = LLVMBuildInsertElement(builder_, llvmValue, tmp1Value, LLVMConstInt(LLVMInt32Type(), 1, 0), "");
827         } else if (LLVMGetTypeKind(type) == LLVMIntegerTypeKind) {
828             // do nothing
829         } else {
830             abort();
831         }
832     } else if (machineType == MachineType::F64) {
833         auto doubleValue = bit_cast<double>(value.to_ullong()); // actual double value
834         llvmValue = LLVMConstReal(LLVMDoubleType(), doubleValue);
835     } else if (machineType == MachineType::I8) {
836         llvmValue = LLVMConstInt(LLVMInt8Type(), value.to_ulong(), 0);
837     } else if (machineType == MachineType::I16) {
838         llvmValue = LLVMConstInt(LLVMInt16Type(), value.to_ulong(), 0);
839     } else {
840         abort();
841     }
842     gateToLLVMMaps_[gate] = llvmValue;
843     COMPILER_LOG(DEBUG) << "VisitConstant set gate:" << gate << "  value:" << value;
844     COMPILER_LOG(DEBUG) << "VisitConstant " << LLVMValueToString(llvmValue);
845 }
846 
HandleRelocatableData(GateRef gate)847 void LLVMIRBuilder::HandleRelocatableData(GateRef gate)
848 {
849     uint64_t value = circuit_->GetBitField(gate);
850     VisitRelocatableData(gate, value);
851 }
852 
VisitRelocatableData(GateRef gate,uint64_t value)853 void LLVMIRBuilder::VisitRelocatableData(GateRef gate, uint64_t value)
854 {
855     LLVMValueRef globalValue = LLVMAddGlobal(module_, LLVMInt64Type(), "G");
856     LLVMSetInitializer(globalValue, LLVMConstInt(LLVMInt64Type(), value, 0));
857     gateToLLVMMaps_[gate] = globalValue;
858     COMPILER_LOG(DEBUG) << "VisitRelocatableData set gate:" << gate << "  value:" << value;
859     COMPILER_LOG(DEBUG) << "VisitRelocatableData " << LLVMValueToString(globalValue);
860 }
861 
HandleZExtInt(GateRef gate)862 void LLVMIRBuilder::HandleZExtInt(GateRef gate)
863 {
864     std::vector<GateRef> ins = circuit_->GetInVector(gate);
865     VisitZExtInt(gate, ins[0]);
866 }
867 
HandleSExtInt(GateRef gate)868 void LLVMIRBuilder::HandleSExtInt(GateRef gate)
869 {
870     std::vector<GateRef> ins = circuit_->GetInVector(gate);
871     VisitSExtInt(gate, ins[0]);
872 }
873 
HandleParameter(GateRef gate)874 void LLVMIRBuilder::HandleParameter(GateRef gate)
875 {
876     return VisitParameter(gate);
877 }
878 
VisitParameter(GateRef gate)879 void LLVMIRBuilder::VisitParameter(GateRef gate)
880 {
881     int argth = circuit_->LoadGatePtrConst(gate)->GetBitField();
882     COMPILER_LOG(DEBUG) << " Parameter value" << argth;
883     LLVMValueRef value = LLVMGetParam(function_, argth);
884     ASSERT(LLVMTypeOf(value) == ConvertLLVMTypeFromGate(gate));
885     gateToLLVMMaps_[gate] = value;
886     COMPILER_LOG(DEBUG) << "VisitParameter set gate:" << gate << "  value:" << value;
887     // NOTE: caller put args, otherwise crash
888     if (value == nullptr) {
889         COMPILER_LOG(FATAL) << "generate LLVM IR for para: " << argth << "fail";
890         return;
891     }
892     COMPILER_LOG(DEBUG) << "para arg:" << argth << "value IR:" << LLVMValueToString(value);
893 }
894 
HandleBranch(GateRef gate)895 void LLVMIRBuilder::HandleBranch(GateRef gate)
896 {
897     std::vector<GateRef> ins = circuit_->GetInVector(gate);
898     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
899     GateRef bTrue = (circuit_->GetOpCode(outs[0]) == OpCode::IF_TRUE) ? outs[0] : outs[1];
900     GateRef bFalse = (circuit_->GetOpCode(outs[0]) == OpCode::IF_FALSE) ? outs[0] : outs[1];
901     int bbTrue = instIdMapBbId_[circuit_->GetId(bTrue)];
902     int bbFalse = instIdMapBbId_[circuit_->GetId(bFalse)];
903     VisitBranch(gate, ins[1], bbTrue, bbFalse);
904 }
905 
HandleMod(GateRef gate)906 void LLVMIRBuilder::HandleMod(GateRef gate)
907 {
908     auto g0 = circuit_->GetIn(gate, 0);
909     auto g1 = circuit_->GetIn(gate, 1);
910     VisitMod(gate, g0, g1);
911 }
912 
VisitMod(GateRef gate,GateRef e1,GateRef e2)913 void LLVMIRBuilder::VisitMod(GateRef gate, GateRef e1, GateRef e2)
914 {
915     COMPILER_LOG(DEBUG) << "mod gate:" << gate;
916     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
917     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
918     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
919     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
920     LLVMValueRef result = nullptr;
921     ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e1));
922     ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e2));
923     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
924     if (machineType == MachineType::I32) {
925         result = LLVMBuildSRem(builder_, e1Value, e2Value, "");
926     } else if (machineType == MachineType::F64) {
927         result = LLVMBuildFRem(builder_, e1Value, e2Value, "");
928     } else {
929         abort();
930     }
931     gateToLLVMMaps_[gate] = result;
932     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
933 }
934 
VisitBranch(GateRef gate,GateRef cmp,int btrue,int bfalse)935 void LLVMIRBuilder::VisitBranch(GateRef gate, GateRef cmp, int btrue, int bfalse)
936 {
937     COMPILER_LOG(DEBUG) << "cmp gate:" << cmp;
938     if (gateToLLVMMaps_.count(cmp) == 0) {
939         COMPILER_LOG(ERROR) << "Branch condition gate is nullptr!";
940         return;
941     }
942     LLVMValueRef cond = gateToLLVMMaps_[cmp];
943 
944     BasicBlock *trueBB = EnsureBasicBlock(btrue);
945     BasicBlock *falseBB = EnsureBasicBlock(bfalse);
946     EnsureBasicBlock(trueBB);
947     EnsureBasicBlock(falseBB);
948 
949     LLVMBasicBlockRef llvmTrueBB = trueBB->GetImpl<LLVMTFBuilderBasicBlockImpl>()->llvm_bb_;
950     LLVMBasicBlockRef llvmFalseBB = falseBB->GetImpl<LLVMTFBuilderBasicBlockImpl>()->llvm_bb_;
951     LLVMValueRef result = LLVMBuildCondBr(builder_, cond, llvmTrueBB, llvmFalseBB);
952     EndCurrentBlock();
953     gateToLLVMMaps_[gate] = result;
954 }
955 
HandleSwitch(GateRef gate)956 void LLVMIRBuilder::HandleSwitch(GateRef gate)
957 {
958     std::vector<GateRef> ins = circuit_->GetInVector(gate);
959     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
960     VisitSwitch(gate, ins[1], outs);
961 }
962 
VisitSwitch(GateRef gate,GateRef input,const std::vector<GateRef> & outList)963 void LLVMIRBuilder::VisitSwitch(GateRef gate, GateRef input, const std::vector<GateRef> &outList)
964 {
965     LLVMValueRef cond = gateToLLVMMaps_[input];
966     unsigned caseNum = outList.size();
967     BasicBlock *curOutBB = nullptr;
968     LLVMBasicBlockRef llvmDefaultOutBB = nullptr;
969     for (int i = 0; i < static_cast<int>(caseNum); i++) {
970         curOutBB = EnsureBasicBlock(instIdMapBbId_[circuit_->GetId(outList[i])]);
971         EnsureBasicBlock(curOutBB);
972         if (circuit_->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) {
973             llvmDefaultOutBB = curOutBB->GetImpl<LLVMTFBuilderBasicBlockImpl>()->llvm_bb_;
974         }
975     }
976     LLVMValueRef result = LLVMBuildSwitch(builder_, cond, llvmDefaultOutBB, caseNum - 1);
977     LLVMBasicBlockRef llvmCurOutBB = nullptr;
978     for (int i = 0; i < static_cast<int>(caseNum); i++) {
979         if (circuit_->GetOpCode(outList[i]) == OpCode::DEFAULT_CASE) {
980             continue;
981         }
982         curOutBB = EnsureBasicBlock(instIdMapBbId_[circuit_->GetId(outList[i])]);
983         llvmCurOutBB = curOutBB->GetImpl<LLVMTFBuilderBasicBlockImpl>()->llvm_bb_;
984         LLVMAddCase(result, LLVMConstInt(ConvertLLVMTypeFromGate(input), circuit_->GetBitField(outList[i]), 0),
985                     llvmCurOutBB);
986     }
987     EndCurrentBlock();
988     gateToLLVMMaps_[gate] = result;
989 }
990 
VisitLoad(GateRef gate,GateRef base)991 void LLVMIRBuilder::VisitLoad(GateRef gate, GateRef base)
992 {
993     COMPILER_LOG(DEBUG) << "Load base gate:" << base;
994     LLVMValueRef baseAddr = gateToLLVMMaps_[base];
995     LLVMTypeRef returnType;
996     baseAddr = CanonicalizeToPtr(baseAddr);
997     returnType = ConvertLLVMTypeFromGate(gate);
998     baseAddr = LLVMBuildPointerCast(builder_, baseAddr,
999         LLVMPointerType(returnType, LLVMGetPointerAddressSpace(LLVMTypeOf(baseAddr))), "");
1000     LLVMValueRef result = LLVMBuildLoad(builder_, baseAddr, "");
1001     gateToLLVMMaps_[gate] = result;
1002 }
1003 
VisitStore(GateRef gate,GateRef base,GateRef dataToStore)1004 void LLVMIRBuilder::VisitStore(GateRef gate, GateRef base, GateRef dataToStore)
1005 {
1006     COMPILER_LOG(DEBUG) << "store base gate:" << base;
1007     LLVMValueRef baseAddr = gateToLLVMMaps_[base];
1008     baseAddr = CanonicalizeToPtr(baseAddr);
1009     LLVMValueRef data = gateToLLVMMaps_[dataToStore];
1010     baseAddr = LLVMBuildPointerCast(builder_, baseAddr,
1011         LLVMPointerType(ConvertLLVMTypeFromGate(dataToStore), LLVMGetPointerAddressSpace(LLVMTypeOf(baseAddr))), "");
1012     LLVMValueRef value = LLVMBuildStore(builder_, data, baseAddr);
1013     gateToLLVMMaps_[gate] = value;
1014     COMPILER_LOG(DEBUG) << "store value:" << value << " " << "value type" << LLVMTypeOf(value);
1015 }
1016 
CanonicalizeToInt(LLVMValueRef value)1017 LLVMValueRef LLVMIRBuilder::CanonicalizeToInt(LLVMValueRef value)
1018 {
1019     if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMVectorTypeKind) {
1020         LLVMValueRef e1Value0 = LLVMBuildExtractElement(builder_, value, LLVMConstInt(LLVMInt32Type(), 0, 1), "");
1021         LLVMValueRef e1Value1 = LLVMBuildExtractElement(builder_, value, LLVMConstInt(LLVMInt32Type(), 1, 1), "");
1022         LLVMValueRef tmp1 = LLVMBuildPtrToInt(builder_, e1Value1, LLVMInt64Type(), "");
1023         LLVMValueRef constValue = LLVMConstInt(LLVMInt64Type(), 32, 0); // 32: offset
1024         LLVMValueRef tmp1Value = LLVMBuildShl(builder_, tmp1, constValue, "");
1025         LLVMValueRef tmp2Value = LLVMBuildPtrToInt(builder_, e1Value0, LLVMInt64Type(), "");
1026         LLVMValueRef resultValue = LLVMBuildAdd(builder_, tmp1Value, tmp2Value, "");
1027         return resultValue;
1028     } else if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind) {
1029         return LLVMBuildPtrToInt(builder_, value, LLVMInt64Type(), "");
1030     } else if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMIntegerTypeKind) {
1031         return value;
1032     } else {
1033         COMPILER_LOG(DEBUG) << "can't Canonicalize to Int64: ";
1034         abort();
1035     }
1036 }
1037 
CanonicalizeToPtr(LLVMValueRef value)1038 LLVMValueRef LLVMIRBuilder::CanonicalizeToPtr(LLVMValueRef value)
1039 {
1040     if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMVectorTypeKind) {
1041         LLVMValueRef tmp = LLVMBuildExtractElement(builder_, value, LLVMConstInt(LLVMInt32Type(), 0, 1), "");
1042         return LLVMBuildPointerCast(builder_, tmp, LLVMPointerType(LLVMInt8Type(), 1), "");
1043     } else if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind) {
1044         return LLVMBuildPointerCast(builder_, value,
1045             LLVMPointerType(LLVMInt8Type(), LLVMGetPointerAddressSpace(LLVMTypeOf(value))), "");
1046     } else if (LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMIntegerTypeKind) {
1047         LLVMValueRef tmp = LLVMBuildIntToPtr(builder_, value, LLVMPointerType(LLVMInt64Type(), 0), "");
1048         return LLVMBuildPointerCast(builder_, tmp, LLVMPointerType(LLVMInt8Type(), 0), "");
1049     } else {
1050         COMPILER_LOG(DEBUG) << "can't Canonicalize to Ptr: ";
1051         abort();
1052     }
1053 }
1054 
HandleIntRev(GateRef gate)1055 void LLVMIRBuilder::HandleIntRev(GateRef gate)
1056 {
1057     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1058     VisitIntRev(gate, ins[0]);
1059 }
1060 
VisitIntRev(GateRef gate,GateRef e1)1061 void LLVMIRBuilder::VisitIntRev(GateRef gate, GateRef e1)
1062 {
1063     COMPILER_LOG(DEBUG) << "int sign invert gate:" << gate;
1064     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1065     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1066     ASSERT(ConvertLLVMTypeFromGate(gate) == ConvertLLVMTypeFromGate(e1));
1067     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
1068     LLVMValueRef result = nullptr;
1069     if (machineType <= MachineType::I64 && machineType >= MachineType::I1) {
1070         result = LLVMBuildNot(builder_, e1Value, "");
1071     } else {
1072         abort();
1073     }
1074     gateToLLVMMaps_[gate] = result;
1075     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1076 }
1077 
PointerAdd(LLVMValueRef baseAddr,LLVMValueRef offset,LLVMTypeRef rep)1078 LLVMValueRef LLVMIRBuilder::PointerAdd(LLVMValueRef baseAddr, LLVMValueRef offset, LLVMTypeRef rep)
1079 {
1080     LLVMValueRef ptr = CanonicalizeToPtr(baseAddr);
1081     LLVMValueRef dstRef8 = LLVMBuildGEP(builder_, ptr, &offset, 1, "");
1082     LLVMValueRef result = LLVMBuildPointerCast(builder_, dstRef8, rep, "");
1083     return result;
1084 }
1085 
VectorAdd(LLVMValueRef baseAddr,LLVMValueRef offset,LLVMTypeRef rep)1086 LLVMValueRef LLVMIRBuilder::VectorAdd(LLVMValueRef baseAddr, LLVMValueRef offset, LLVMTypeRef rep)
1087 {
1088     LLVMValueRef ptr = CanonicalizeToPtr(baseAddr);
1089     LLVMValueRef dstRef8 = LLVMBuildGEP(builder_, ptr, &offset, 1, "");
1090     LLVMValueRef result = LLVMBuildInsertElement(builder_, baseAddr, dstRef8, LLVMConstInt(LLVMInt32Type(), 0, 0), "");
1091     return result;
1092 }
1093 
IsGCRelated(GateType typeCode) const1094 bool LLVMIRBuilder::IsGCRelated(GateType typeCode) const
1095 {
1096     if ((typeCode & (~GC_MASK)) == 0) {
1097         return true;
1098     }
1099     return false;
1100 }
1101 
ConvertLLVMTypeFromGate(GateRef gate) const1102 LLVMTypeRef LLVMIRBuilder::ConvertLLVMTypeFromGate(GateRef gate) const
1103 {
1104     if (IsGCRelated(circuit_->GetGateType(gate))) {
1105         if (compCfg_->Is32Bit()) {
1106             return LLVMVectorType(LLVMPointerType(LLVMInt8Type(), 1), 2);
1107         } else {
1108             return LLVMPointerType(LLVMInt64Type(), 1);
1109         }
1110     }
1111     switch (circuit_->LoadGatePtrConst(gate)->GetMachineType()) {
1112         case MachineType::NOVALUE:
1113             return LLVMVoidType();
1114         case MachineType::I1:
1115             return LLVMInt1Type();
1116         case MachineType::I8:
1117             return LLVMInt8Type();
1118         case MachineType::I16:
1119             return LLVMInt16Type();
1120         case MachineType::I32:
1121             return LLVMInt32Type();
1122         case MachineType::I64:
1123             return LLVMInt64Type();
1124         case MachineType::F32:
1125             return LLVMFloatType();
1126         case MachineType::F64:
1127             return LLVMDoubleType();
1128         case MachineType::ARCH: {
1129             if (compCfg_->Is32Bit()) {
1130                 return LLVMInt32Type();
1131             } else {
1132                 return LLVMInt64Type();
1133             }
1134         }
1135         default:
1136             abort();
1137     }
1138 }
1139 
GetBitWidthFromMachineType(MachineType machineType) const1140 int64_t LLVMIRBuilder::GetBitWidthFromMachineType(MachineType machineType) const
1141 {
1142     switch (machineType) {
1143         case NOVALUE:
1144             return 0;
1145         case ARCH:
1146             return 48;  // 48: Pointer representation in different architectures
1147         case I1:
1148             return 1;
1149         case I8:
1150             return 8; // 8: bit width
1151         case I16:
1152             return 16; // 16: bit width
1153         case I32:
1154             return 32; // 32: bit width
1155         case I64:
1156             return 64; // 64: bit width
1157         case F32:
1158             return 32; // 32: bit width
1159         case F64:
1160             return 64; // 64: bit width
1161         case FLEX:
1162         case ANYVALUE:
1163             abort();
1164             break;
1165     }
1166 }
1167 
HandleAdd(GateRef gate)1168 void LLVMIRBuilder::HandleAdd(GateRef gate)
1169 {
1170     auto g0 = circuit_->GetIn(gate, 0);
1171     auto g1 = circuit_->GetIn(gate, 1);
1172     VisitAdd(gate, g0, g1);
1173 }
1174 
VisitAdd(GateRef gate,GateRef e1,GateRef e2)1175 void LLVMIRBuilder::VisitAdd(GateRef gate, GateRef e1, GateRef e2)
1176 {
1177     COMPILER_LOG(DEBUG) << "add gate:" << gate;
1178     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1179     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1180     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1181     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1182     LLVMValueRef result = nullptr;
1183     /* pointer                          int
1184       vector{i8 * x 2}          int
1185     */
1186     LLVMTypeRef returnType = ConvertLLVMTypeFromGate(gate);
1187 
1188     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
1189     if (machineType == MachineType::I32 || machineType == MachineType::I64 ||
1190         machineType == MachineType::I8 || machineType == MachineType::I16) {
1191         auto e1Type = LLVMGetTypeKind(ConvertLLVMTypeFromGate(e1));
1192         if (e1Type == LLVMVectorTypeKind) {
1193             result = VectorAdd(e1Value, e2Value, returnType);
1194         } else if (e1Type == LLVMPointerTypeKind) {
1195             result = PointerAdd(e1Value, e2Value, returnType);
1196         } else {
1197             LLVMValueRef tmp1Value = LLVMBuildIntCast2(builder_, e1Value, returnType, 0, "");
1198             LLVMValueRef tmp2Value = LLVMBuildIntCast2(builder_, e2Value, returnType, 0, "");
1199             result = LLVMBuildAdd(builder_, tmp1Value, tmp2Value, "");
1200             if (LLVMTypeOf(tmp1Value) != LLVMTypeOf(tmp2Value)) {
1201                 ASSERT(LLVMTypeOf(tmp1Value) == LLVMTypeOf(tmp2Value));
1202             }
1203         }
1204     } else if (machineType == MachineType::F64) {
1205         result = LLVMBuildFAdd(builder_, e1Value, e2Value, "");
1206     } else {
1207         abort();
1208     }
1209     gateToLLVMMaps_[gate] = result;
1210     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1211 }
1212 
HandleSub(GateRef gate)1213 void LLVMIRBuilder::HandleSub(GateRef gate)
1214 {
1215     auto g0 = circuit_->GetIn(gate, 0);
1216     auto g1 = circuit_->GetIn(gate, 1);
1217     VisitSub(gate, g0, g1);
1218 }
1219 
VisitSub(GateRef gate,GateRef e1,GateRef e2)1220 void LLVMIRBuilder::VisitSub(GateRef gate, GateRef e1, GateRef e2)
1221 {
1222     COMPILER_LOG(DEBUG) << "sub gate:" << gate;
1223     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1224     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1225     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1226     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1227     LLVMValueRef result = nullptr;
1228     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
1229     if (machineType == MachineType::I32 || machineType == MachineType::I64) {
1230         result = LLVMBuildSub(builder_, e1Value, e2Value, "");
1231     } else if (machineType == MachineType::F64) {
1232         result = LLVMBuildFSub(builder_, e1Value, e2Value, "");
1233     } else {
1234         abort();
1235     }
1236     gateToLLVMMaps_[gate] = result;
1237     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1238 }
1239 
HandleMul(GateRef gate)1240 void LLVMIRBuilder::HandleMul(GateRef gate)
1241 {
1242     auto g0 = circuit_->GetIn(gate, 0);
1243     auto g1 = circuit_->GetIn(gate, 1);
1244     VisitMul(gate, g0, g1);
1245 }
1246 
VisitMul(GateRef gate,GateRef e1,GateRef e2)1247 void LLVMIRBuilder::VisitMul(GateRef gate, GateRef e1, GateRef e2)
1248 {
1249     COMPILER_LOG(DEBUG) << "mul gate:" << gate;
1250     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1251     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1252     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1253     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1254     LLVMValueRef result = nullptr;
1255     auto machineType = circuit_->LoadGatePtrConst(gate)->GetMachineType();
1256     if (machineType == MachineType::I32 || machineType == MachineType::I64) {
1257         result = LLVMBuildMul(builder_, e1Value, e2Value, "");
1258     } else if (machineType == MachineType::F64) {
1259         result = LLVMBuildFMul(builder_, e1Value, e2Value, "");
1260     } else {
1261         abort();
1262     }
1263     gateToLLVMMaps_[gate] = result;
1264     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1265 }
1266 
HandleFloatDiv(GateRef gate)1267 void LLVMIRBuilder::HandleFloatDiv(GateRef gate)
1268 {
1269     auto g0 = circuit_->GetIn(gate, 0);
1270     auto g1 = circuit_->GetIn(gate, 1);
1271     VisitFloatDiv(gate, g0, g1);
1272 }
1273 
HandleIntDiv(GateRef gate)1274 void LLVMIRBuilder::HandleIntDiv(GateRef gate)
1275 {
1276     auto g0 = circuit_->GetIn(gate, 0);
1277     auto g1 = circuit_->GetIn(gate, 1);
1278     VisitIntDiv(gate, g0, g1);
1279 }
1280 
HandleUDiv(GateRef gate)1281 void LLVMIRBuilder::HandleUDiv(GateRef gate)
1282 {
1283     auto g0 = circuit_->GetIn(gate, 0);
1284     auto g1 = circuit_->GetIn(gate, 1);
1285     VisitUDiv(gate, g0, g1);
1286 }
1287 
HandleIntOr(GateRef gate)1288 void LLVMIRBuilder::HandleIntOr(GateRef gate)
1289 {
1290     auto g0 = circuit_->GetIn(gate, 0);
1291     auto g1 = circuit_->GetIn(gate, 1);
1292     VisitIntOr(gate, g0, g1);
1293 }
1294 
HandleIntXor(GateRef gate)1295 void LLVMIRBuilder::HandleIntXor(GateRef gate)
1296 {
1297     auto g0 = circuit_->GetIn(gate, 0);
1298     auto g1 = circuit_->GetIn(gate, 1);
1299     VisitIntXor(gate, g0, g1);
1300 }
1301 
HandleIntLsr(GateRef gate)1302 void LLVMIRBuilder::HandleIntLsr(GateRef gate)
1303 {
1304     auto g0 = circuit_->GetIn(gate, 0);
1305     auto g1 = circuit_->GetIn(gate, 1);
1306     VisitIntLsr(gate, g0, g1);
1307 }
1308 
HandleCmp(GateRef gate)1309 void LLVMIRBuilder::HandleCmp(GateRef gate)
1310 {
1311     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1312     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
1313     VisitCmp(gate, ins[0], ins[1]);
1314 }
1315 
VisitCmp(GateRef gate,GateRef e1,GateRef e2)1316 void LLVMIRBuilder::VisitCmp(GateRef gate, GateRef e1, GateRef e2)
1317 {
1318     COMPILER_LOG(DEBUG) << "cmp gate:" << gate;
1319     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1320     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1321     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1322     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1323     LLVMValueRef result = nullptr;
1324     auto e1ValCode = circuit_->LoadGatePtrConst(e1)->GetMachineType();
1325     [[maybe_unused]]auto e2ValCode = circuit_->LoadGatePtrConst(e2)->GetMachineType();
1326     ASSERT((e1ValCode == e2ValCode) ||
1327         (compCfg_->Is32Bit() && (e1ValCode == MachineType::ARCH) && (e2ValCode == MachineType::I32)) ||
1328         (compCfg_->Is64Bit() && (e1ValCode == MachineType::ARCH) && (e2ValCode == MachineType::I64)) ||
1329         (compCfg_->Is32Bit() && (e2ValCode == MachineType::ARCH) && (e1ValCode == MachineType::I32)) ||
1330         (compCfg_->Is64Bit() && (e2ValCode == MachineType::ARCH) && (e1ValCode == MachineType::I64)));
1331     LLVMIntPredicate intOpcode = LLVMIntEQ;
1332     LLVMRealPredicate realOpcode = LLVMRealPredicateFalse;
1333     switch (circuit_->GetOpCode(gate)) {
1334         case OpCode::SLT: {
1335             intOpcode = LLVMIntSLT;
1336             realOpcode = LLVMRealOLT;
1337             break;
1338         }
1339         case OpCode::ULT: {
1340             intOpcode = LLVMIntULT;
1341             realOpcode = LLVMRealOLT;
1342             break;
1343         }
1344         case OpCode::SLE: {
1345             intOpcode = LLVMIntSLE;
1346             realOpcode = LLVMRealOLE;
1347             break;
1348         }
1349         case OpCode::SGT: {
1350             intOpcode = LLVMIntSGT;
1351             realOpcode = LLVMRealOGT;
1352             break;
1353         }
1354         case OpCode::SGE: {
1355             intOpcode = LLVMIntSGE;
1356             realOpcode = LLVMRealOGE;
1357             break;
1358         }
1359         case OpCode::NE: {
1360             intOpcode = LLVMIntNE;
1361             realOpcode = LLVMRealONE;
1362             break;
1363         }
1364         case OpCode::EQ: {
1365             intOpcode = LLVMIntEQ;
1366             realOpcode = LLVMRealOEQ;
1367             break;
1368         }
1369         default: {
1370             abort();
1371             break;
1372         }
1373     }
1374     if (e1ValCode == MachineType::I32 || e1ValCode == MachineType::I64 || e1ValCode == MachineType::ARCH) {
1375         e1Value = CanonicalizeToInt(e1Value);
1376         e2Value = CanonicalizeToInt(e2Value);
1377         result = LLVMBuildICmp(builder_, intOpcode, e1Value, e2Value, "");
1378     } else if (e1ValCode == MachineType::F64) {
1379         result = LLVMBuildFCmp(builder_, realOpcode, e1Value, e2Value, "");
1380     } else {
1381         abort();
1382     }
1383     gateToLLVMMaps_[gate] = result;
1384     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1385 }
1386 
HandleLoad(GateRef gate)1387 void LLVMIRBuilder::HandleLoad(GateRef gate)
1388 {
1389     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1390     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
1391     GateRef base = ins[1];
1392     VisitLoad(gate, base);
1393 }
1394 
HandleStore(GateRef gate)1395 void LLVMIRBuilder::HandleStore(GateRef gate)
1396 {
1397     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1398     std::vector<GateRef> outs = circuit_->GetOutVector(gate);
1399     VisitStore(gate, ins[2], ins[1]);  // 2:baseAddr gate, 1:data gate
1400 }
1401 
HandleChangeInt32ToDouble(GateRef gate)1402 void LLVMIRBuilder::HandleChangeInt32ToDouble(GateRef gate)
1403 {
1404     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1405     VisitChangeInt32ToDouble(gate, ins[0]);
1406 }
1407 
HandleChangeDoubleToInt32(GateRef gate)1408 void LLVMIRBuilder::HandleChangeDoubleToInt32(GateRef gate)
1409 {
1410     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1411     VisitChangeDoubleToInt32(gate, ins[0]);
1412 }
1413 
HandleChangeTaggedPointerToInt64(GateRef gate)1414 void LLVMIRBuilder::HandleChangeTaggedPointerToInt64(GateRef gate)
1415 {
1416     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1417     VisitChangeTaggedPointerToInt64(gate, ins[0]);
1418 }
1419 
HandleChangeInt64ToTagged(GateRef gate)1420 void LLVMIRBuilder::HandleChangeInt64ToTagged(GateRef gate)
1421 {
1422     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1423     VisitChangeInt64ToTagged(gate, ins[0]);
1424 }
1425 
VisitIntDiv(GateRef gate,GateRef e1,GateRef e2)1426 void LLVMIRBuilder::VisitIntDiv(GateRef gate, GateRef e1, GateRef e2)
1427 {
1428     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1429     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1430     LLVMValueRef result = LLVMBuildSDiv(builder_, e1Value, e2Value, "");
1431     gateToLLVMMaps_[gate] = result;
1432 }
1433 
VisitUDiv(GateRef gate,GateRef e1,GateRef e2)1434 void LLVMIRBuilder::VisitUDiv(GateRef gate, GateRef e1, GateRef e2)
1435 {
1436     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1437     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1438     LLVMValueRef result = LLVMBuildUDiv(builder_, e1Value, e2Value, "");
1439     gateToLLVMMaps_[gate] = result;
1440 }
1441 
VisitFloatDiv(GateRef gate,GateRef e1,GateRef e2)1442 void LLVMIRBuilder::VisitFloatDiv(GateRef gate, GateRef e1, GateRef e2)
1443 {
1444     COMPILER_LOG(DEBUG) << "float div gate:" << gate;
1445     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1446     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1447     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1448     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1449 
1450     LLVMValueRef result = LLVMBuildFDiv(builder_, e1Value, e2Value, "");
1451     gateToLLVMMaps_[gate] = result;
1452     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1453 }
1454 
VisitIntOr(GateRef gate,GateRef e1,GateRef e2)1455 void LLVMIRBuilder::VisitIntOr(GateRef gate, GateRef e1, GateRef e2)
1456 {
1457     COMPILER_LOG(DEBUG) << "int or gate:" << gate;
1458     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1459     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1460     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1461     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1462 
1463     e1Value = CanonicalizeToInt(e1Value);
1464     e2Value = CanonicalizeToInt(e2Value);
1465     LLVMValueRef result = LLVMBuildOr(builder_, e1Value, e2Value, "");
1466     gateToLLVMMaps_[gate] = result;
1467     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1468 }
1469 
HandleIntAnd(GateRef gate)1470 void LLVMIRBuilder::HandleIntAnd(GateRef gate)
1471 {
1472     auto g0 = circuit_->GetIn(gate, 0);
1473     auto g1 = circuit_->GetIn(gate, 1);
1474     VisitIntAnd(gate, g0, g1);
1475 }
1476 
VisitIntAnd(GateRef gate,GateRef e1,GateRef e2)1477 void LLVMIRBuilder::VisitIntAnd(GateRef gate, GateRef e1, GateRef e2)
1478 {
1479     COMPILER_LOG(DEBUG) << "int and gate:" << gate;
1480     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1481     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1482     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1483     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1484     e1Value = CanonicalizeToInt(e1Value);
1485     e2Value = CanonicalizeToInt(e2Value);
1486     LLVMValueRef result = LLVMBuildAnd(builder_, e1Value, e2Value, "");
1487     gateToLLVMMaps_[gate] = result;
1488     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1489 }
1490 
VisitIntXor(GateRef gate,GateRef e1,GateRef e2)1491 void LLVMIRBuilder::VisitIntXor(GateRef gate, GateRef e1, GateRef e2)
1492 {
1493     COMPILER_LOG(DEBUG) << "int xor gate:" << gate;
1494     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1495     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1496     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1497     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1498     e1Value = CanonicalizeToInt(e1Value);
1499     e2Value = CanonicalizeToInt(e2Value);
1500     LLVMValueRef result = LLVMBuildXor(builder_, e1Value, e2Value, "");
1501     gateToLLVMMaps_[gate] = result;
1502     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1503 }
1504 
VisitIntLsr(GateRef gate,GateRef e1,GateRef e2)1505 void LLVMIRBuilder::VisitIntLsr(GateRef gate, GateRef e1, GateRef e2)
1506 {
1507     COMPILER_LOG(DEBUG) << "int lsr gate:" << gate;
1508     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1509     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1510     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1511     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1512     e1Value = CanonicalizeToInt(e1Value);
1513     e2Value = CanonicalizeToInt(e2Value);
1514     LLVMValueRef result = LLVMBuildLShr(builder_, e1Value, e2Value, "");
1515     gateToLLVMMaps_[gate] = result;
1516     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1517 }
1518 
HandleIntLsl(GateRef gate)1519 void LLVMIRBuilder::HandleIntLsl(GateRef gate)
1520 {
1521     auto g0 = circuit_->GetIn(gate, 0);
1522     auto g1 = circuit_->GetIn(gate, 1);
1523     VisitIntLsl(gate, g0, g1);
1524 }
1525 
VisitIntLsl(GateRef gate,GateRef e1,GateRef e2)1526 void LLVMIRBuilder::VisitIntLsl(GateRef gate, GateRef e1, GateRef e2)
1527 {
1528     COMPILER_LOG(DEBUG) << "int lsl gate:" << gate;
1529     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1530     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1531     LLVMValueRef e2Value = gateToLLVMMaps_[e2];
1532     COMPILER_LOG(DEBUG) << "operand 1: " << LLVMValueToString(e2Value);
1533     e1Value = CanonicalizeToInt(e1Value);
1534     e2Value = CanonicalizeToInt(e2Value);
1535     LLVMValueRef result = LLVMBuildShl(builder_, e1Value, e2Value, "");
1536     gateToLLVMMaps_[gate] = result;
1537     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1538 }
1539 
VisitZExtInt(GateRef gate,GateRef e1)1540 void LLVMIRBuilder::VisitZExtInt(GateRef gate, GateRef e1)
1541 {
1542     COMPILER_LOG(DEBUG) << "int zero extension gate:" << gate;
1543     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1544     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1545     ASSERT(GetBitWidthFromMachineType(circuit_->LoadGatePtrConst(e1)->GetMachineType()) <=
1546         GetBitWidthFromMachineType(circuit_->LoadGatePtrConst(gate)->GetMachineType()));
1547     LLVMValueRef result = LLVMBuildZExt(builder_, e1Value, ConvertLLVMTypeFromGate(gate), "");
1548     gateToLLVMMaps_[gate] = result;
1549     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1550 }
1551 
VisitSExtInt(GateRef gate,GateRef e1)1552 void LLVMIRBuilder::VisitSExtInt(GateRef gate, GateRef e1)
1553 {
1554     COMPILER_LOG(DEBUG) << "int sign extension gate:" << gate;
1555     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1556     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1557     LLVMValueRef result = LLVMBuildSExt(builder_, e1Value, ConvertLLVMTypeFromGate(gate), "");
1558     gateToLLVMMaps_[gate] = result;
1559     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1560 }
1561 
HandleCastIntXToIntY(GateRef gate)1562 void LLVMIRBuilder::HandleCastIntXToIntY(GateRef gate)
1563 {
1564     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1565     VisitCastIntXToIntY(gate, ins[0]);
1566 }
1567 
VisitCastIntXToIntY(GateRef gate,GateRef e1)1568 void LLVMIRBuilder::VisitCastIntXToIntY(GateRef gate, GateRef e1)
1569 {
1570     COMPILER_LOG(DEBUG) << "int cast2 int gate:" << gate;
1571     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1572     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1573     LLVMValueRef result = LLVMBuildIntCast2(builder_, e1Value, ConvertLLVMTypeFromGate(gate), 1, "");
1574     gateToLLVMMaps_[gate] = result;
1575     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1576 }
1577 
VisitChangeInt32ToDouble(GateRef gate,GateRef e1)1578 void LLVMIRBuilder::VisitChangeInt32ToDouble(GateRef gate, GateRef e1)
1579 {
1580     COMPILER_LOG(DEBUG) << "int cast2 double gate:" << gate;
1581     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1582     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1583     LLVMValueRef result = LLVMBuildSIToFP(builder_, e1Value, LLVMDoubleType(), "");
1584     gateToLLVMMaps_[gate] = result;
1585     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1586 }
1587 
VisitChangeDoubleToInt32(GateRef gate,GateRef e1)1588 void LLVMIRBuilder::VisitChangeDoubleToInt32(GateRef gate, GateRef e1)
1589 {
1590     COMPILER_LOG(DEBUG) << "double cast2 int32 gate:" << gate;
1591     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1592     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1593     LLVMValueRef result = LLVMBuildFPToSI(builder_, e1Value, LLVMInt32Type(), "");
1594     gateToLLVMMaps_[gate] = result;
1595     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1596 }
1597 
VisitChangeTaggedPointerToInt64(GateRef gate,GateRef e1)1598 void LLVMIRBuilder::VisitChangeTaggedPointerToInt64(GateRef gate, GateRef e1)
1599 {
1600     COMPILER_LOG(DEBUG) << "tagged pointer cast2 int64 gate:" << gate;
1601     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1602     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1603     LLVMValueRef result = CanonicalizeToInt(e1Value);
1604     gateToLLVMMaps_[gate] = result;
1605     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1606 }
1607 
VisitChangeInt64ToTagged(GateRef gate,GateRef e1)1608 void LLVMIRBuilder::VisitChangeInt64ToTagged(GateRef gate, GateRef e1)
1609 {
1610     COMPILER_LOG(DEBUG) << "int64 cast2 tagged gate:" << gate;
1611     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1612     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1613     ASSERT(LLVMGetTypeKind(LLVMTypeOf(e1Value)) == LLVMIntegerTypeKind);
1614     LLVMValueRef result;
1615     if (compCfg_->Is32Bit()) {
1616         LLVMValueRef tmp1Value =
1617             LLVMBuildLShr(builder_, e1Value, LLVMConstInt(LLVMInt32Type(), 32, 0), ""); // 32: offset
1618         LLVMValueRef tmp2Value = LLVMBuildIntCast(builder_, e1Value, LLVMInt32Type(), ""); // low
1619         LLVMTypeRef vectorType = LLVMVectorType(LLVMPointerType(LLVMInt8Type(), 1), 2);  // 2: packed vector type
1620         LLVMValueRef emptyValue = LLVMGetUndef(vectorType);
1621         tmp1Value = LLVMBuildIntToPtr(builder_, tmp1Value, LLVMPointerType(LLVMInt8Type(), 1), "");
1622         tmp2Value = LLVMBuildIntToPtr(builder_, tmp2Value, LLVMPointerType(LLVMInt8Type(), 1), "");
1623         result = LLVMBuildInsertElement(builder_, emptyValue, tmp2Value, LLVMConstInt(LLVMInt32Type(), 0, 0), "");
1624         result = LLVMBuildInsertElement(builder_, result, tmp1Value, LLVMConstInt(LLVMInt32Type(), 1, 0), "");
1625     } else {
1626         result = LLVMBuildIntToPtr(builder_, e1Value, LLVMPointerType(LLVMInt64Type(), 1), "");
1627     }
1628     gateToLLVMMaps_[gate] = result;
1629     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1630 }
1631 
HandleBitCast(GateRef gate)1632 void LLVMIRBuilder::HandleBitCast(GateRef gate)
1633 {
1634     std::vector<GateRef> ins = circuit_->GetInVector(gate);
1635     VisitBitCast(gate, ins[0]);
1636 }
1637 
VisitBitCast(GateRef gate,GateRef e1)1638 void LLVMIRBuilder::VisitBitCast(GateRef gate, GateRef e1)
1639 {
1640     COMPILER_LOG(DEBUG) << "bitcast gate:" << gate;
1641     LLVMValueRef e1Value = gateToLLVMMaps_[e1];
1642     COMPILER_LOG(DEBUG) << "operand 0: " << LLVMValueToString(e1Value);
1643     [[maybe_unused]] auto gateValCode = circuit_->LoadGatePtrConst(gate)->GetMachineType();
1644     [[maybe_unused]] auto e1ValCode = circuit_->LoadGatePtrConst(e1)->GetMachineType();
1645     ASSERT(GetBitWidthFromMachineType(gateValCode) == GetBitWidthFromMachineType(e1ValCode));
1646     auto returnType = ConvertLLVMTypeFromGate(gate);
1647     LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, returnType, "");
1648     gateToLLVMMaps_[gate] = result;
1649     COMPILER_LOG(DEBUG) << "result: " << LLVMValueToString(result);
1650 }
1651 
LLVMStubModule(const std::string & name,const std::string & triple)1652 LLVMStubModule::LLVMStubModule(const std::string &name, const std::string &triple)
1653     : compCfg_(triple)
1654 {
1655     module_ = LLVMModuleCreateWithName(name.c_str());
1656     LLVMSetTarget(module_, triple.c_str());
1657 }
1658 
~LLVMStubModule()1659 LLVMStubModule::~LLVMStubModule()
1660 {
1661     if (module_ != nullptr) {
1662         LLVMDisposeModule(module_);
1663         module_ = nullptr;
1664     }
1665 }
1666 
Initialize(const std::vector<int> & stubIndices)1667 void LLVMStubModule::Initialize(const std::vector<int> &stubIndices)
1668 {
1669     uint32_t i;
1670     for (i = 0; i < CALL_STUB_MAXCOUNT; i++) {
1671         auto stubDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(i);
1672         if (!stubDescriptor->GetName().empty()) {
1673             stubFunctionType_[i] = GetLLVMFunctionTypeStubDescriptor(stubDescriptor);
1674         }
1675     }
1676     for (i = 0; i < FAST_STUB_MAXCOUNT; i++) {
1677         uint32_t index = stubIndices[i];
1678         auto stubDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(index);
1679         if (!stubDescriptor->GetName().empty()) {
1680             stubFunctions_[i] = GetLLVMFunctionByStubDescriptor(stubDescriptor);
1681         }
1682     }
1683 #define DEF_STUB_FUNCTION(name, argc)                                                       \
1684     {                                                                                       \
1685         auto funcType = stubFunctionType_[CallStubId::NAME_BytecodeHandler];                \
1686         stubFunctions_[StubId::STUB_##name] = LLVMAddFunction(module_, #name, funcType);    \
1687     }
1688 #if ECMASCRIPT_COMPILE_INTERPRETER_ASM
1689     INTERPRETER_STUB_LIST(DEF_STUB_FUNCTION)
1690 #endif
1691 #undef DEF_STUB_FUNCTION
1692 
1693 #ifndef NDEBUG
1694     for (i = 0; i < TEST_FUNC_MAXCOUNT; i++) {
1695         auto testFuncDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(i + TEST_FUNC_OFFSET);
1696         if (!testFuncDescriptor->GetName().empty()) {
1697             testFunctions_[i] = GetLLVMFunctionByStubDescriptor(testFuncDescriptor);
1698         }
1699     }
1700 #endif
1701 }
1702 
GetLLVMFunctionByStubDescriptor(StubDescriptor * stubDescriptor)1703 LLVMValueRef LLVMStubModule::GetLLVMFunctionByStubDescriptor(StubDescriptor *stubDescriptor)
1704 {
1705     auto funcType = GetLLVMFunctionTypeStubDescriptor(stubDescriptor);
1706     return LLVMAddFunction(module_, stubDescriptor->GetName().c_str(), funcType);
1707 }
1708 
GetLLVMFunctionTypeStubDescriptor(StubDescriptor * stubDescriptor)1709 LLVMTypeRef LLVMStubModule::GetLLVMFunctionTypeStubDescriptor(StubDescriptor *stubDescriptor)
1710 {
1711     LLVMTypeRef returnType = ConvertLLVMTypeFromStubMachineType(stubDescriptor->GetReturnType());
1712     std::vector<LLVMTypeRef> paramTys;
1713     auto paramCount = stubDescriptor->GetParametersCount();
1714     for (int i = 0; i < paramCount; i++) {
1715         auto paramsType = stubDescriptor->GetParametersType();
1716         paramTys.push_back(ConvertLLVMTypeFromStubMachineType(paramsType[i]));
1717     }
1718     auto functype = LLVMFunctionType(returnType, paramTys.data(), paramCount, stubDescriptor->GetVariableArgs());
1719     return functype;
1720 }
1721 
ConvertLLVMTypeFromStubMachineType(StubMachineType type)1722 LLVMTypeRef LLVMStubModule::ConvertLLVMTypeFromStubMachineType(StubMachineType type)
1723 {
1724     static std::map<StubMachineType, LLVMTypeRef> machineTypeMap = {
1725         {StubMachineType::NONE,           LLVMVoidType()},
1726         {StubMachineType::BOOL,           LLVMInt1Type()},
1727         {StubMachineType::INT8,           LLVMInt8Type()},
1728         {StubMachineType::INT16,          LLVMInt16Type()},
1729         {StubMachineType::INT32,          LLVMInt32Type()},
1730         {StubMachineType::INT64,          LLVMInt64Type()},
1731         {StubMachineType::UINT8,          LLVMInt8Type()},
1732         {StubMachineType::UINT16,         LLVMInt16Type()},
1733         {StubMachineType::UINT32,         LLVMInt32Type()},
1734         {StubMachineType::UINT64,         LLVMInt64Type()},
1735         {StubMachineType::FLOAT32,        LLVMFloatType()},
1736         {StubMachineType::FLOAT64,        LLVMDoubleType()},
1737         {StubMachineType::NATIVE_POINTER, LLVMInt64Type()},
1738         {StubMachineType::TAGGED_POINTER, LLVMPointerType(LLVMInt64Type(), 1)},
1739         {StubMachineType::TAGGED,         LLVMPointerType(LLVMInt64Type(), 1)},
1740     };
1741     if (compCfg_.Is32Bit()) {
1742         machineTypeMap[StubMachineType::NATIVE_POINTER] = LLVMInt32Type();
1743         LLVMTypeRef vectorType = LLVMVectorType(LLVMPointerType(LLVMInt8Type(), 1), 2);  // 2: packed vector type
1744         machineTypeMap[StubMachineType::TAGGED_POINTER] = vectorType;
1745         machineTypeMap[StubMachineType::TAGGED] = vectorType;
1746     }
1747     return machineTypeMap[type];
1748 }
1749 }  // namespace panda::ecmascript::kungfu
1750