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 ¬_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