Common function prototypes must be added only once per Module, otherwise LLVM autorenames
them, and we get llvm.bswap.i326 instead of llvm.bswap.i32, which is of course
not valid and the verifier rejects.
... | ... |
@@ -286,6 +286,19 @@ public: |
286 | 286 |
} |
287 | 287 |
}; |
288 | 288 |
|
289 |
+struct CommonFunctions { |
|
290 |
+ Function *FHandler; |
|
291 |
+ Function *FMemset; |
|
292 |
+ Function *FMemmove; |
|
293 |
+ Function *FMemcpy; |
|
294 |
+ Function *FRealmemset; |
|
295 |
+ Function *FRealMemmove; |
|
296 |
+ Function *FRealmemcmp; |
|
297 |
+ Function *FRealmemcpy; |
|
298 |
+ Function *FBSwap16; |
|
299 |
+ Function *FBSwap32; |
|
300 |
+ Function *FBSwap64; |
|
301 |
+}; |
|
289 | 302 |
|
290 | 303 |
class VISIBILITY_HIDDEN LLVMCodegen { |
291 | 304 |
private: |
... | ... |
@@ -312,6 +325,8 @@ private: |
312 | 312 |
unsigned numArgs; |
313 | 313 |
std::vector<MDNode*> mdnodes; |
314 | 314 |
|
315 |
+ struct CommonFunctions *CF; |
|
316 |
+ |
|
315 | 317 |
Value *getOperand(const struct cli_bc_func *func, const Type *Ty, operand_t operand) |
316 | 318 |
{ |
317 | 319 |
unsigned map[] = {0, 1, 2, 3, 3, 4, 4, 4, 4}; |
... | ... |
@@ -417,7 +432,7 @@ private: |
417 | 417 |
Builder.CreateStore(V, Values[dest]); |
418 | 418 |
} |
419 | 419 |
|
420 |
- // Insert code that calls \arg FHandler if \arg FailCond is true. |
|
420 |
+ // Insert code that calls \arg CF->FHandler if \arg FailCond is true. |
|
421 | 421 |
void InsertVerify(Value *FailCond, BasicBlock *&Fail, Function *FHandler, |
422 | 422 |
Function *F) { |
423 | 423 |
if (!Fail) { |
... | ... |
@@ -483,13 +498,13 @@ private: |
483 | 483 |
|
484 | 484 |
|
485 | 485 |
public: |
486 |
- LLVMCodegen(const struct cli_bc *bc, Module *M, FunctionMapTy &cFuncs, |
|
486 |
+ LLVMCodegen(const struct cli_bc *bc, Module *M, struct CommonFunctions *CF, FunctionMapTy &cFuncs, |
|
487 | 487 |
ExecutionEngine *EE, FunctionPassManager &PM, |
488 | 488 |
Function **apiFuncs, LLVMTypeMapper &apiMap) |
489 | 489 |
: bc(bc), M(M), Context(M->getContext()), EE(EE), |
490 | 490 |
PM(PM), apiFuncs(apiFuncs),apiMap(apiMap), |
491 | 491 |
compiledFunctions(cFuncs), BytecodeID("bc"+Twine(bc->id)), |
492 |
- Folder(EE->getTargetData()), Builder(Context, Folder) { |
|
492 |
+ Folder(EE->getTargetData()), Builder(Context, Folder), CF(CF) { |
|
493 | 493 |
|
494 | 494 |
for (unsigned i=0;i<cli_apicall_maxglobal - _FIRST_GLOBAL;i++) { |
495 | 495 |
unsigned id = cli_globals[i].globalid; |
... | ... |
@@ -587,85 +602,6 @@ public: |
587 | 587 |
Ty = PointerType::getUnqual(ATy->getElementType());*/ |
588 | 588 |
GVtypeMap[id] = Ty; |
589 | 589 |
} |
590 |
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), |
|
591 |
- false); |
|
592 |
- Function *FHandler = Function::Create(FTy, Function::ExternalLinkage, |
|
593 |
- "clamjit.fail", M); |
|
594 |
- FHandler->setDoesNotReturn(); |
|
595 |
- FHandler->setDoesNotThrow(); |
|
596 |
- FHandler->addFnAttr(Attribute::NoInline); |
|
597 |
- EE->addGlobalMapping(FHandler, (void*)(intptr_t)jit_exception_handler); |
|
598 |
- EE->InstallLazyFunctionCreator(noUnknownFunctions); |
|
599 |
- |
|
600 |
- std::vector<const Type*> args; |
|
601 |
- args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
602 |
- args.push_back(Type::getInt8Ty(Context)); |
|
603 |
- args.push_back(Type::getInt32Ty(Context)); |
|
604 |
- args.push_back(Type::getInt32Ty(Context)); |
|
605 |
- FunctionType* FuncTy_3 = FunctionType::get(Type::getVoidTy(Context), |
|
606 |
- args, false); |
|
607 |
- Function *FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage, |
|
608 |
- "llvm.memset.i32", M); |
|
609 |
- FMemset->setDoesNotThrow(); |
|
610 |
- FMemset->setDoesNotCapture(1, true); |
|
611 |
- |
|
612 |
- args.clear(); |
|
613 |
- args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
614 |
- args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
615 |
- args.push_back(Type::getInt32Ty(Context)); |
|
616 |
- args.push_back(Type::getInt32Ty(Context)); |
|
617 |
- FunctionType* FuncTy_4 = FunctionType::get(Type::getVoidTy(Context), |
|
618 |
- args, false); |
|
619 |
- Function *FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
620 |
- "llvm.memmove.i32", M); |
|
621 |
- FMemmove->setDoesNotThrow(); |
|
622 |
- FMemmove->setDoesNotCapture(1, true); |
|
623 |
- |
|
624 |
- Function *FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
625 |
- "llvm.memcpy.i32", M); |
|
626 |
- FMemcpy->setDoesNotThrow(); |
|
627 |
- FMemcpy->setDoesNotCapture(1, true); |
|
628 |
- |
|
629 |
- args.clear(); |
|
630 |
- args.push_back(Type::getInt16Ty(Context)); |
|
631 |
- FunctionType *FuncTy_5 = FunctionType::get(Type::getInt16Ty(Context), args, false); |
|
632 |
- Function *FBSwap16 = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, |
|
633 |
- "llvm.bswap.i16", M); |
|
634 |
- FBSwap16->setDoesNotThrow(); |
|
635 |
- |
|
636 |
- args.clear(); |
|
637 |
- args.push_back(Type::getInt32Ty(Context)); |
|
638 |
- FunctionType *FuncTy_6 = FunctionType::get(Type::getInt32Ty(Context), args, false); |
|
639 |
- Function *FBSwap32 = Function::Create(FuncTy_6, GlobalValue::ExternalLinkage, |
|
640 |
- "llvm.bswap.i32", M); |
|
641 |
- FBSwap32->setDoesNotThrow(); |
|
642 |
- |
|
643 |
- args.clear(); |
|
644 |
- args.push_back(Type::getInt64Ty(Context)); |
|
645 |
- FunctionType *FuncTy_7 = FunctionType::get(Type::getInt64Ty(Context), args, false); |
|
646 |
- Function *FBSwap64 = Function::Create(FuncTy_7, GlobalValue::ExternalLinkage, |
|
647 |
- "llvm.bswap.i64", M); |
|
648 |
- FBSwap16->setDoesNotThrow(); |
|
649 |
- |
|
650 |
- FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false); |
|
651 |
- Function *FRealMemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
652 |
- "memset", M); |
|
653 |
- EE->addGlobalMapping(FRealMemset, (void*)(intptr_t)memset); |
|
654 |
- Function *FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
655 |
- "memmove", M); |
|
656 |
- EE->addGlobalMapping(FRealMemmove, (void*)(intptr_t)memmove); |
|
657 |
- Function *FRealMemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
658 |
- "memcpy", M); |
|
659 |
- EE->addGlobalMapping(FRealMemcpy, (void*)(intptr_t)memcpy); |
|
660 |
- |
|
661 |
- args.clear(); |
|
662 |
- args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
663 |
- args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
664 |
- args.push_back(EE->getTargetData()->getIntPtrType(Context)); |
|
665 |
- FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context), |
|
666 |
- args, false); |
|
667 |
- Function* FRealMemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M); |
|
668 |
- EE->addGlobalMapping(FRealMemcmp, (void*)(intptr_t)memcmp); |
|
669 | 590 |
|
670 | 591 |
// The hidden ctx param to all functions |
671 | 592 |
const Type *HiddenCtx = PointerType::getUnqual(Type::getInt8Ty(Context)); |
... | ... |
@@ -849,7 +785,7 @@ public: |
849 | 849 |
case OP_BC_UDIV: |
850 | 850 |
{ |
851 | 851 |
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0)); |
852 |
- InsertVerify(Bad, Fail, FHandler, F); |
|
852 |
+ InsertVerify(Bad, Fail, CF->FHandler, F); |
|
853 | 853 |
Store(inst->dest, Builder.CreateUDiv(Op0, Op1)); |
854 | 854 |
break; |
855 | 855 |
} |
... | ... |
@@ -857,14 +793,14 @@ public: |
857 | 857 |
{ |
858 | 858 |
//TODO: also verify Op0 == -1 && Op1 = INT_MIN |
859 | 859 |
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0)); |
860 |
- InsertVerify(Bad, Fail, FHandler, F); |
|
860 |
+ InsertVerify(Bad, Fail, CF->FHandler, F); |
|
861 | 861 |
Store(inst->dest, Builder.CreateSDiv(Op0, Op1)); |
862 | 862 |
break; |
863 | 863 |
} |
864 | 864 |
case OP_BC_UREM: |
865 | 865 |
{ |
866 | 866 |
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0)); |
867 |
- InsertVerify(Bad, Fail, FHandler, F); |
|
867 |
+ InsertVerify(Bad, Fail, CF->FHandler, F); |
|
868 | 868 |
Store(inst->dest, Builder.CreateURem(Op0, Op1)); |
869 | 869 |
break; |
870 | 870 |
} |
... | ... |
@@ -872,7 +808,7 @@ public: |
872 | 872 |
{ |
873 | 873 |
//TODO: also verify Op0 == -1 && Op1 = INT_MIN |
874 | 874 |
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0)); |
875 |
- InsertVerify(Bad, Fail, FHandler, F); |
|
875 |
+ InsertVerify(Bad, Fail, CF->FHandler, F); |
|
876 | 876 |
Store(inst->dest, Builder.CreateSRem(Op0, Op1)); |
877 | 877 |
break; |
878 | 878 |
} |
... | ... |
@@ -1063,7 +999,7 @@ public: |
1063 | 1063 |
Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
1064 | 1064 |
Value *Val = convertOperand(func, Type::getInt8Ty(Context), inst->u.three[1]); |
1065 | 1065 |
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
1066 |
- CallInst *c = Builder.CreateCall4(FMemset, Dst, Val, Len, |
|
1066 |
+ CallInst *c = Builder.CreateCall4(CF->FMemset, Dst, Val, Len, |
|
1067 | 1067 |
ConstantInt::get(Type::getInt32Ty(Context), 1)); |
1068 | 1068 |
c->setTailCall(true); |
1069 | 1069 |
c->setDoesNotThrow(); |
... | ... |
@@ -1074,7 +1010,7 @@ public: |
1074 | 1074 |
Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
1075 | 1075 |
Value *Src = convertOperand(func, inst, inst->u.three[1]); |
1076 | 1076 |
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
1077 |
- CallInst *c = Builder.CreateCall4(FMemcpy, Dst, Src, Len, |
|
1077 |
+ CallInst *c = Builder.CreateCall4(CF->FMemcpy, Dst, Src, Len, |
|
1078 | 1078 |
ConstantInt::get(Type::getInt32Ty(Context), 1)); |
1079 | 1079 |
c->setTailCall(true); |
1080 | 1080 |
c->setDoesNotThrow(); |
... | ... |
@@ -1085,7 +1021,7 @@ public: |
1085 | 1085 |
Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
1086 | 1086 |
Value *Src = convertOperand(func, inst, inst->u.three[1]); |
1087 | 1087 |
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]); |
1088 |
- CallInst *c = Builder.CreateCall4(FMemmove, Dst, Src, Len, |
|
1088 |
+ CallInst *c = Builder.CreateCall4(CF->FMemmove, Dst, Src, Len, |
|
1089 | 1089 |
ConstantInt::get(Type::getInt32Ty(Context), 1)); |
1090 | 1090 |
c->setTailCall(true); |
1091 | 1091 |
c->setDoesNotThrow(); |
... | ... |
@@ -1096,7 +1032,7 @@ public: |
1096 | 1096 |
Value *Dst = convertOperand(func, inst, inst->u.three[0]); |
1097 | 1097 |
Value *Src = convertOperand(func, inst, inst->u.three[1]); |
1098 | 1098 |
Value *Len = convertOperand(func, EE->getTargetData()->getIntPtrType(Context), inst->u.three[2]); |
1099 |
- CallInst *c = Builder.CreateCall3(FRealMemcmp, Dst, Src, Len); |
|
1099 |
+ CallInst *c = Builder.CreateCall3(CF->FRealmemcmp, Dst, Src, Len); |
|
1100 | 1100 |
c->setTailCall(true); |
1101 | 1101 |
c->setDoesNotThrow(); |
1102 | 1102 |
Store(inst->dest, c); |
... | ... |
@@ -1109,7 +1045,7 @@ public: |
1109 | 1109 |
break; |
1110 | 1110 |
case OP_BC_ABORT: |
1111 | 1111 |
if (!unreachable) { |
1112 |
- CallInst *CI = Builder.CreateCall(FHandler); |
|
1112 |
+ CallInst *CI = Builder.CreateCall(CF->FHandler); |
|
1113 | 1113 |
CI->setDoesNotReturn(); |
1114 | 1114 |
CI->setDoesNotThrow(); |
1115 | 1115 |
Builder.CreateUnreachable(); |
... | ... |
@@ -1118,7 +1054,7 @@ public: |
1118 | 1118 |
break; |
1119 | 1119 |
case OP_BC_BSWAP16: |
1120 | 1120 |
{ |
1121 |
- CallInst *C = Builder.CreateCall(FBSwap16, convertOperand(func, inst, inst->u.unaryop)); |
|
1121 |
+ CallInst *C = Builder.CreateCall(CF->FBSwap16, convertOperand(func, inst, inst->u.unaryop)); |
|
1122 | 1122 |
C->setTailCall(true); |
1123 | 1123 |
C->setDoesNotThrow(true); |
1124 | 1124 |
Store(inst->dest, C); |
... | ... |
@@ -1126,7 +1062,7 @@ public: |
1126 | 1126 |
} |
1127 | 1127 |
case OP_BC_BSWAP32: |
1128 | 1128 |
{ |
1129 |
- CallInst *C = Builder.CreateCall(FBSwap32, convertOperand(func, inst, inst->u.unaryop)); |
|
1129 |
+ CallInst *C = Builder.CreateCall(CF->FBSwap32, convertOperand(func, inst, inst->u.unaryop)); |
|
1130 | 1130 |
C->setTailCall(true); |
1131 | 1131 |
C->setDoesNotThrow(true); |
1132 | 1132 |
Store(inst->dest, C); |
... | ... |
@@ -1134,7 +1070,7 @@ public: |
1134 | 1134 |
} |
1135 | 1135 |
case OP_BC_BSWAP64: |
1136 | 1136 |
{ |
1137 |
- CallInst *C = Builder.CreateCall(FBSwap64, convertOperand(func, inst, inst->u.unaryop)); |
|
1137 |
+ CallInst *C = Builder.CreateCall(CF->FBSwap64, convertOperand(func, inst, inst->u.unaryop)); |
|
1138 | 1138 |
C->setTailCall(true); |
1139 | 1139 |
C->setDoesNotThrow(true); |
1140 | 1140 |
Store(inst->dest, C); |
... | ... |
@@ -1173,6 +1109,7 @@ public: |
1173 | 1173 |
|
1174 | 1174 |
DEBUG(M->dump()); |
1175 | 1175 |
delete TypeMap; |
1176 |
+ std::vector<const Type*> args; |
|
1176 | 1177 |
args.clear(); |
1177 | 1178 |
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
1178 | 1179 |
FunctionType *Callable = FunctionType::get(Type::getInt32Ty(Context), |
... | ... |
@@ -1236,6 +1173,91 @@ class LLVMApiScopedLock { |
1236 | 1236 |
} |
1237 | 1237 |
}; |
1238 | 1238 |
|
1239 |
+static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, Module *M) |
|
1240 |
+{ |
|
1241 |
+ LLVMContext &Context = M->getContext(); |
|
1242 |
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), |
|
1243 |
+ false); |
|
1244 |
+ CF->FHandler = Function::Create(FTy, Function::ExternalLinkage, |
|
1245 |
+ "clamjit.fail", M); |
|
1246 |
+ CF->FHandler->setDoesNotReturn(); |
|
1247 |
+ CF->FHandler->setDoesNotThrow(); |
|
1248 |
+ CF->FHandler->addFnAttr(Attribute::NoInline); |
|
1249 |
+ |
|
1250 |
+ EE->addGlobalMapping(CF->FHandler, (void*)(intptr_t)jit_exception_handler); |
|
1251 |
+ EE->InstallLazyFunctionCreator(noUnknownFunctions); |
|
1252 |
+ |
|
1253 |
+ std::vector<const Type*> args; |
|
1254 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
1255 |
+ args.push_back(Type::getInt8Ty(Context)); |
|
1256 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
1257 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
1258 |
+ FunctionType* FuncTy_3 = FunctionType::get(Type::getVoidTy(Context), |
|
1259 |
+ args, false); |
|
1260 |
+ CF->FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage, |
|
1261 |
+ "llvm.memset.i32", M); |
|
1262 |
+ CF->FMemset->setDoesNotThrow(); |
|
1263 |
+ CF->FMemset->setDoesNotCapture(1, true); |
|
1264 |
+ |
|
1265 |
+ args.clear(); |
|
1266 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
1267 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
1268 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
1269 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
1270 |
+ FunctionType* FuncTy_4 = FunctionType::get(Type::getVoidTy(Context), |
|
1271 |
+ args, false); |
|
1272 |
+ CF->FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
1273 |
+ "llvm.memmove.i32", M); |
|
1274 |
+ CF->FMemmove->setDoesNotThrow(); |
|
1275 |
+ CF->FMemmove->setDoesNotCapture(1, true); |
|
1276 |
+ |
|
1277 |
+ CF->FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage, |
|
1278 |
+ "llvm.memcpy.i32", M); |
|
1279 |
+ CF->FMemcpy->setDoesNotThrow(); |
|
1280 |
+ CF->FMemcpy->setDoesNotCapture(1, true); |
|
1281 |
+ |
|
1282 |
+ args.clear(); |
|
1283 |
+ args.push_back(Type::getInt16Ty(Context)); |
|
1284 |
+ FunctionType *FuncTy_5 = FunctionType::get(Type::getInt16Ty(Context), args, false); |
|
1285 |
+ CF->FBSwap16 = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, |
|
1286 |
+ "llvm.bswap.i16", M); |
|
1287 |
+ CF->FBSwap16->setDoesNotThrow(); |
|
1288 |
+ |
|
1289 |
+ args.clear(); |
|
1290 |
+ args.push_back(Type::getInt32Ty(Context)); |
|
1291 |
+ FunctionType *FuncTy_6 = FunctionType::get(Type::getInt32Ty(Context), args, false); |
|
1292 |
+ CF->FBSwap32 = Function::Create(FuncTy_6, GlobalValue::ExternalLinkage, |
|
1293 |
+ "llvm.bswap.i32", M); |
|
1294 |
+ CF->FBSwap32->setDoesNotThrow(); |
|
1295 |
+ |
|
1296 |
+ args.clear(); |
|
1297 |
+ args.push_back(Type::getInt64Ty(Context)); |
|
1298 |
+ FunctionType *FuncTy_7 = FunctionType::get(Type::getInt64Ty(Context), args, false); |
|
1299 |
+ CF->FBSwap64 = Function::Create(FuncTy_7, GlobalValue::ExternalLinkage, |
|
1300 |
+ "llvm.bswap.i64", M); |
|
1301 |
+ CF->FBSwap64->setDoesNotThrow(); |
|
1302 |
+ |
|
1303 |
+ FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false); |
|
1304 |
+ CF->FRealmemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
1305 |
+ "memset", M); |
|
1306 |
+ EE->addGlobalMapping(CF->FRealmemset, (void*)(intptr_t)memset); |
|
1307 |
+ CF->FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
1308 |
+ "memmove", M); |
|
1309 |
+ EE->addGlobalMapping(CF->FRealMemmove, (void*)(intptr_t)memmove); |
|
1310 |
+ CF->FRealmemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage, |
|
1311 |
+ "memcpy", M); |
|
1312 |
+ EE->addGlobalMapping(CF->FRealmemcpy, (void*)(intptr_t)memcpy); |
|
1313 |
+ |
|
1314 |
+ args.clear(); |
|
1315 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
1316 |
+ args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context))); |
|
1317 |
+ args.push_back(EE->getTargetData()->getIntPtrType(Context)); |
|
1318 |
+ FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context), |
|
1319 |
+ args, false); |
|
1320 |
+ CF->FRealmemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M); |
|
1321 |
+ EE->addGlobalMapping(CF->FRealmemcmp, (void*)(intptr_t)memcmp); |
|
1322 |
+} |
|
1323 |
+ |
|
1239 | 1324 |
} |
1240 | 1325 |
|
1241 | 1326 |
int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx, |
... | ... |
@@ -1322,6 +1344,9 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
1322 | 1322 |
EE->DisableLazyCompilation(); |
1323 | 1323 |
EE->DisableSymbolSearching(); |
1324 | 1324 |
|
1325 |
+ struct CommonFunctions CF; |
|
1326 |
+ addFunctionProtos(&CF, EE, M); |
|
1327 |
+ |
|
1325 | 1328 |
FunctionPassManager OurFPM(MP); |
1326 | 1329 |
// Set up the optimizer pipeline. Start with registering info about how |
1327 | 1330 |
// the target lays out data structures. |
... | ... |
@@ -1382,7 +1407,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
1382 | 1382 |
const struct cli_bc *bc = &bcs->all_bcs[i]; |
1383 | 1383 |
if (bc->state == bc_skip) |
1384 | 1384 |
continue; |
1385 |
- LLVMCodegen Codegen(bc, M, bcs->engine->compiledFunctions, EE, |
|
1385 |
+ LLVMCodegen Codegen(bc, M, &CF, bcs->engine->compiledFunctions, EE, |
|
1386 | 1386 |
OurFPM, apiFuncs, apiMap); |
1387 | 1387 |
if (!Codegen.generate()) { |
1388 | 1388 |
errs() << MODULE << "JIT codegen failed\n"; |