Browse code

bb#11414 - integrate patch for LLVM 3.6 support

Kevin Lin authored on 2015/10/29 06:11:23
Showing 3 changed files
... ...
@@ -55,7 +55,13 @@
55 55
 #include "llvm/Analysis/TargetFolder.h"
56 56
 #endif
57 57
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
58
+#if LLVM_VERSION < 36
58 59
 #include "llvm/ExecutionEngine/JIT.h"
60
+#else
61
+#include "llvm/ExecutionEngine/MCJIT.h"
62
+#include "llvm/Support/DynamicLibrary.h"
63
+#include "llvm/Object/ObjectFile.h"
64
+#endif
59 65
 #include "llvm/ExecutionEngine/JITEventListener.h"
60 66
 #include "llvm/PassManager.h"
61 67
 #include "llvm/Support/Compiler.h"
... ...
@@ -424,13 +430,19 @@ static void* noUnknownFunctions(const std::string& name) {
424 424
     if (addr)
425 425
 	return addr;
426 426
 
427
+#if LLVM_VERSION < 36
427 428
     std::string reason((Twine("Attempt to call external function ")+name).str());
428 429
     llvm_error_handler(0, reason);
430
+#else
431
+    // noUnknownFunctions relies on addGlobalMapping, which doesn't work with MCJIT.
432
+    // Now the function pointers are found with SymbolSearching.
433
+#endif
429 434
     return 0;
430 435
 }
431 436
 
432 437
 class NotifyListener : public JITEventListener {
433 438
 public:
439
+#if LLVM_VERSION < 36
434 440
     virtual void NotifyFunctionEmitted(const Function &F,
435 441
 				       void *Code, size_t Size,
436 442
 				       const EmittedFunctionDetails &Details)
... ...
@@ -444,6 +456,18 @@ public:
444 444
 			    F.getName().str().c_str(), (long)Size, Code);
445 445
 #endif
446 446
     }
447
+#else
448
+    // MCJIT doesn't emit single functions, but instead whole objects.
449
+    virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
450
+                                     const RuntimeDyld::LoadedObjectInfo &L)
451
+    {
452
+        if (!cli_debug_flag)
453
+            return;
454
+        cli_dbgmsg_internal("[Bytecode JIT]; emitted %s %s of %zd bytes\n",
455
+                            Obj.getFileFormatName().str().c_str(),
456
+                            Obj.getFileName().str().c_str(), Obj.getData().size());
457
+    }
458
+#endif
447 459
 };
448 460
 
449 461
 class TimerWrapper {
... ...
@@ -1172,10 +1196,18 @@ public:
1172 1172
 	    mdnodes.resize(i+1);
1173 1173
 	assert(i < mdnodes.size());
1174 1174
 	const struct cli_bc_dbgnode *node = &bc->dbgnodes[i];
1175
+#if LLVM_VERSION < 36
1175 1176
 	Value **Vals = new Value*[node->numelements];
1177
+#else
1178
+	Metadata **Vals = new Metadata*[node->numelements];
1179
+#endif
1176 1180
 	for (unsigned j=0;j<node->numelements;j++) {
1177 1181
 	    const struct cli_bc_dbgnode_element* el = &node->elements[j];
1182
+#if LLVM_VERSION < 36
1178 1183
 	    Value *V;
1184
+#else
1185
+	    Metadata *V;
1186
+#endif
1179 1187
 	    if (!el->len) {
1180 1188
 		if (el->nodeid == ~0u)
1181 1189
 		    V = 0;
... ...
@@ -1186,12 +1218,21 @@ public:
1186 1186
 	    } else if (el->string) {
1187 1187
 		V = MDString::get(Context, StringRef(el->string, el->len));
1188 1188
 	    } else {
1189
+#if LLVM_VERSION < 36
1189 1190
 		V = ConstantInt::get(IntegerType::get(Context, el->len),
1190 1191
 				     el->constant);
1192
+#else
1193
+		V = ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(Context, el->len),
1194
+				     el->constant));
1195
+#endif
1191 1196
 	    }
1192 1197
 	    Vals[j] = V;
1193 1198
 	}
1199
+#if LLVM_VERSION < 36
1194 1200
 	MDNode *N = MDNode::get(Context, ARRAYREF(Value*,Vals, node->numelements));
1201
+#else
1202
+	MDNode *N = MDNode::get(Context, ARRAYREF(Metadata*,Vals, node->numelements));
1203
+#endif
1195 1204
 	delete[] Vals;
1196 1205
 	mdnodes[i] = N;
1197 1206
 	return N;
... ...
@@ -2000,11 +2041,19 @@ class LLVMApiScopedLock {
2000 2000
 	    // it is not like we are going to codegen from multiple threads
2001 2001
 	    // at a time anyway.
2002 2002
 //	    if (!llvm_is_multithreaded())
2003
+#if LLVM_VERSION < 36
2003 2004
 		llvm_api_lock.acquire();
2005
+#else
2006
+		llvm_api_lock.lock();
2007
+#endif
2004 2008
 	}
2005 2009
 	~LLVMApiScopedLock() {
2006 2010
 //	    if (!llvm_is_multithreaded())
2011
+#if LLVM_VERSION < 36
2007 2012
 		llvm_api_lock.release();
2013
+#else
2014
+		llvm_api_lock.unlock();
2015
+#endif
2008 2016
 	}
2009 2017
 };
2010 2018
 
... ...
@@ -2022,7 +2071,12 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
2022 2022
 #else
2023 2023
     CF->FHandler->addFnAttr(Attribute::NoInline);
2024 2024
 #endif
2025
+#if LLVM_VERSION < 36
2026
+    // addGlobalMapping still exists in LLVM 3.6, but it doesn't work with MCJIT, which now replaces the JIT implementation.
2025 2027
     EE->addGlobalMapping(CF->FHandler, (void*)(intptr_t)jit_exception_handler);
2028
+#else
2029
+    sys::DynamicLibrary::AddSymbol(CF->FHandler->getName(), (void*)(intptr_t)jit_exception_handler);
2030
+#endif
2026 2031
     EE->InstallLazyFunctionCreator(noUnknownFunctions);
2027 2032
     EE->getPointerToFunction(CF->FHandler);
2028 2033
 
... ...
@@ -2112,15 +2166,27 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
2112 2112
     FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false);
2113 2113
     CF->FRealmemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
2114 2114
 					     "memset", M);
2115
+#if LLVM_VERSION < 36
2115 2116
     EE->addGlobalMapping(CF->FRealmemset, (void*)(intptr_t)memset);
2117
+#else
2118
+    sys::DynamicLibrary::AddSymbol(CF->FRealmemset->getName(), (void*)(intptr_t)memset);
2119
+#endif
2116 2120
     EE->getPointerToFunction(CF->FRealmemset);
2117 2121
     CF->FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
2118 2122
 					      "memmove", M);
2123
+#if LLVM_VERSION < 36
2119 2124
     EE->addGlobalMapping(CF->FRealMemmove, (void*)(intptr_t)memmove);
2125
+#else
2126
+    sys::DynamicLibrary::AddSymbol(CF->FRealMemmove->getName(), (void*)(intptr_t)memmove);
2127
+#endif
2120 2128
     EE->getPointerToFunction(CF->FRealMemmove);
2121 2129
     CF->FRealmemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
2122 2130
 					     "memcpy", M);
2131
+#if LLVM_VERSION < 36
2123 2132
     EE->addGlobalMapping(CF->FRealmemcpy, (void*)(intptr_t)memcpy);
2133
+#else
2134
+    sys::DynamicLibrary::AddSymbol(CF->FRealmemcpy->getName(), (void*)(intptr_t)memcpy);
2135
+#endif
2124 2136
     EE->getPointerToFunction(CF->FRealmemcpy);
2125 2137
 
2126 2138
     args.clear();
... ...
@@ -2134,7 +2200,11 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
2134 2134
     FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context),
2135 2135
 				 args, false);
2136 2136
     CF->FRealmemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M);
2137
+#if LLVM_VERSION < 36
2137 2138
     EE->addGlobalMapping(CF->FRealmemcmp, (void*)(intptr_t)memcmp);
2139
+#else
2140
+    sys::DynamicLibrary::AddSymbol(CF->FRealmemcmp->getName(), (void*)(intptr_t)memcmp);
2141
+#endif
2138 2142
     EE->getPointerToFunction(CF->FRealmemcmp);
2139 2143
 }
2140 2144
 
... ...
@@ -2365,8 +2435,10 @@ static void setGuard(unsigned char* guardbuf)
2365 2365
 static void addFPasses(FunctionPassManager &FPM, bool trusted, const TargetData *TD)
2366 2366
 #elif LLVM_VERSION < 35
2367 2367
 static void addFPasses(FunctionPassManager &FPM, bool trusted, const DataLayout *TD)
2368
-#else
2368
+#elif LLVM_VERSION < 36
2369 2369
 static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
2370
+#else
2371
+static void addFPasses(FunctionPassManager &FPM, bool trusted, Module *M)
2370 2372
 #endif
2371 2373
 {
2372 2374
     // Set up the optimizer pipeline.  Start with registering info about how
... ...
@@ -2375,8 +2447,12 @@ static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
2375 2375
     FPM.add(new TargetData(*TD));
2376 2376
 #elif LLVM_VERSION < 35
2377 2377
     FPM.add(new DataLayout(*TD));
2378
-#else
2378
+#elif LLVM_VERSION < 36
2379 2379
     FPM.add(new DataLayoutPass(M));
2380
+#else
2381
+    DataLayoutPass *DLP = new DataLayoutPass();
2382
+    DLP->doInitialization(*M);
2383
+    FPM.add(DLP);
2380 2384
 #endif
2381 2385
     // Promote allocas to registers.
2382 2386
     FPM.add(createPromoteMemoryToRegisterPass());
... ...
@@ -2398,7 +2474,11 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2398 2398
     {
2399 2399
 	// Create the JIT.
2400 2400
 	std::string ErrorMsg;
2401
+#if LLVM_VERSION < 36
2401 2402
 	EngineBuilder builder(M);
2403
+#else
2404
+	EngineBuilder builder(std::move(std::unique_ptr<Module>(M)));
2405
+#endif
2402 2406
 
2403 2407
 #if LLVM_VERSION >= 31
2404 2408
 	TargetOptions Options;
... ...
@@ -2435,7 +2515,12 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2435 2435
 	// Due to LLVM PR4816 only X86 supports non-lazy compilation, disable
2436 2436
 	// for now.
2437 2437
 	EE->DisableLazyCompilation();
2438
+#if LLVM_VERSION < 36
2438 2439
 	EE->DisableSymbolSearching();
2440
+#else
2441
+	// This must be enabled for AddSymbol to work.
2442
+	EE->DisableSymbolSearching(false);
2443
+#endif
2439 2444
 
2440 2445
 	struct CommonFunctions CF;
2441 2446
 	addFunctionProtos(&CF, EE, M);
... ...
@@ -2513,7 +2598,12 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2513 2513
 		std::string reason((Twine("No mapping for builtin api ")+api->name).str());
2514 2514
 		llvm_error_handler(0, reason);
2515 2515
 	    }
2516
+#if LLVM_VERSION < 36
2516 2517
 	    EE->addGlobalMapping(F, dest);
2518
+#else
2519
+    // addGlobalMapping doesn't work with MCJIT, so use symbol searching instead.
2520
+    sys::DynamicLibrary::AddSymbol(F->getName(), dest);
2521
+#endif
2517 2522
 	    EE->getPointerToFunction(F);
2518 2523
 	    apiFuncs[i] = F;
2519 2524
 	}
... ...
@@ -2527,13 +2617,21 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2527 2527
 	if (2*sizeof(void*) <= 16 && cli_rndnum(2)==2) {
2528 2528
 	    plus = sizeof(void*);
2529 2529
 	}
2530
+#if LLVM_VERSION < 36
2530 2531
 	EE->addGlobalMapping(Guard, (void*)(&bcs->engine->guard.b[plus]));
2532
+#else
2533
+    sys::DynamicLibrary::AddSymbol(Guard->getName(), (void*)(&bcs->engine->guard.b[plus]));
2534
+#endif
2531 2535
 	setGuard(bcs->engine->guard.b);
2532 2536
 	bcs->engine->guard.b[plus+sizeof(void*)-1] = 0x00;
2533 2537
 //	printf("%p\n", *(void**)(&bcs->engine->guard.b[plus]));
2534 2538
 	Function *SFail = Function::Create(FTy, Function::ExternalLinkage,
2535 2539
 					      "__stack_chk_fail", M);
2540
+#if LLVM_VERSION < 36
2536 2541
 	EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler);
2542
+#else
2543
+    sys::DynamicLibrary::AddSymbol(SFail->getName(), (void*)(intptr_t)jit_ssp_handler);
2544
+#endif
2537 2545
         EE->getPointerToFunction(SFail);
2538 2546
 
2539 2547
 	llvm::Function **Functions = new Function*[bcs->count];
... ...
@@ -2572,12 +2670,26 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2572 2572
 	PM.add(new TargetData(*EE->getTargetData()));
2573 2573
 #elif LLVM_VERSION < 35
2574 2574
 	PM.add(new DataLayout(*EE->getDataLayout()));
2575
-#else
2575
+#elif LLVM_VERSION < 36
2576 2576
 	PM.add(new DataLayoutPass(M));
2577
+#else
2578
+    DataLayoutPass *DLP = new DataLayoutPass();
2579
+    DLP->doInitialization(*M);
2580
+    PM.add(DLP);
2577 2581
 #endif
2578 2582
 	// TODO: only run this on the untrusted bytecodes, not all of them...
2579 2583
 	if (has_untrusted)
2580 2584
 	    PM.add(createClamBCRTChecks());
2585
+#if LLVM_VERSION >= 36
2586
+	// With LLVM 3.6 (MCJIT) this Pass is required to work around
2587
+	// a crash in LLVM caused by the SCCP Pass:
2588
+	// Pass 'Sparse Conditional Constant Propagation' is not initialized.
2589
+	// Verify if there is a pass dependency cycle.
2590
+	// Required Passes:
2591
+	//
2592
+	// Program received signal SIGSEGV, Segmentation fault.
2593
+	PM.add(createGVNPass());
2594
+#endif
2581 2595
 	PM.add(createSCCPPass());
2582 2596
 	PM.add(createCFGSimplificationPass());
2583 2597
 	PM.add(createGlobalOptimizerPass());
... ...
@@ -2591,6 +2703,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2591 2591
 	pmTimer2.stopTimer();
2592 2592
 	DEBUG(M->dump());
2593 2593
 
2594
+#if LLVM_VERSION >= 36
2595
+	EE->finalizeObject();
2596
+#endif
2597
+
2594 2598
 	{
2595 2599
 	    PrettyStackTraceString CrashInfo2("Native machine codegen");
2596 2600
 	    TimerWrapper codegenTimer("Native codegen");
... ...
@@ -2676,6 +2792,10 @@ int bytecode_init(void)
2676 2676
     // usable by the JIT.
2677 2677
 #ifndef AC_APPLE_UNIVERSAL_BUILD
2678 2678
     InitializeNativeTarget();
2679
+#if LLVM_VERSION >= 36
2680
+    InitializeNativeTargetAsmPrinter();
2681
+    InitializeNativeTargetAsmParser();
2682
+#endif
2679 2683
 #else
2680 2684
     InitializeAllTargets();
2681 2685
 #endif
... ...
@@ -2853,7 +2973,11 @@ void stop(const char *msg, llvm::Function* F, llvm::Instruction* I)
2853 2853
 }
2854 2854
 
2855 2855
 #if LLVM_VERSION >= 29
2856
+#if LLVM_VERSION < 36
2856 2857
 static Value *findDbgGlobalDeclare(GlobalVariable *V) {
2858
+#else
2859
+static Metadata *findDbgGlobalDeclare(GlobalVariable *V) {
2860
+#endif
2857 2861
   const Module *M = V->getParent();
2858 2862
   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
2859 2863
   if (!NMD)
... ...
@@ -2870,7 +2994,11 @@ static Value *findDbgGlobalDeclare(GlobalVariable *V) {
2870 2870
 }
2871 2871
 
2872 2872
 /// Find the debug info descriptor corresponding to this function.
2873
+#if LLVM_VERSION < 36
2873 2874
 static Value *findDbgSubprogramDeclare(Function *V) {
2875
+#else
2876
+static Metadata *findDbgSubprogramDeclare(Function *V) {
2877
+#endif
2874 2878
   const Module *M = V->getParent();
2875 2879
   NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
2876 2880
   if (!NMD)
... ...
@@ -2924,7 +3052,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
2924 2924
   StringRef T;
2925 2925
 
2926 2926
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
2927
+#if LLVM_VERSION < 36
2927 2928
     Value *DIGV = findDbgGlobalDeclare(GV);
2929
+#else
2930
+    Metadata *DIGV = findDbgGlobalDeclare(GV);
2931
+#endif
2928 2932
     if (!DIGV) return false;
2929 2933
     DIGlobalVariable Var(cast<MDNode>(DIGV));
2930 2934
 
... ...
@@ -2944,7 +3076,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
2944 2944
     T = Var.getType().getName();
2945 2945
 #endif
2946 2946
   } else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
2947
+#if LLVM_VERSION < 36
2947 2948
     Value *DIF = findDbgSubprogramDeclare(F);
2949
+#else
2950
+    Metadata *DIF = findDbgSubprogramDeclare(F);
2951
+#endif
2948 2952
     if (!DIF) return false;
2949 2953
     DISubprogram Var(cast<MDNode>(DIF));
2950 2954
 
... ...
@@ -127,9 +127,9 @@ if test "x$packaged_llvm" = "xyes"; then
127 127
 elif test $llvmver_test -lt 290; then
128 128
     AC_MSG_RESULT([no ($llvmver)])
129 129
     AC_MSG_ERROR([LLVM >= 2.9 required, but "$llvmver"($llvmver_test) found])
130
-elif test $llvmver_test -ge 360; then
130
+elif test $llvmver_test -ge 370; then
131 131
     AC_MSG_RESULT([no ($llvmver)])
132
-    AC_MSG_ERROR([LLVM < 3.6 required, but "$llvmver"($llvmver_test) found])
132
+    AC_MSG_ERROR([LLVM < 3.7 required, but "$llvmver"($llvmver_test) found])
133 133
 else
134 134
     AC_MSG_RESULT([ok ($llvmver)])
135 135
 fi
... ...
@@ -147,14 +147,16 @@ void cli_detect_env_jit(struct cli_environment *env)
147 147
 	case Triple::UnknownOS:
148 148
 	    env->os = llvm_os_UnknownOS;
149 149
 	    break;
150
+#if LLVM_VERSION < 36
150 151
 	CASE_OS(AuroraUX, os_solaris);
151 152
 	CASE_OS(Cygwin, os_win32);
153
+	CASE_OS(MinGW32, os_win32);
154
+#endif
152 155
 	CASE_OS(Darwin, os_darwin);
153 156
 	CASE_OS(DragonFly, os_bsd);
154 157
 	CASE_OS(FreeBSD, os_bsd);
155 158
 	CASE_OS(Linux, os_linux);
156 159
 	CASE_OS(Lv2, os_unknown);
157
-	CASE_OS(MinGW32, os_win32);
158 160
 #if LLVM_VERSION < 29
159 161
 	CASE_OS(MinGW64, os_win64);
160 162
 #endif