Browse code

Fix loading of multiple .cbc files.

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.

Török Edvin authored on 2010/02/02 21:01:38
Showing 1 changed files
... ...
@@ -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";