From 03f86ae9829a0a5c6f4fbef0530809b1d24ede3c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:01:36 -0800 Subject: [PATCH 1/7] llvm6: CodeModel::{JIT,}Default no longer exists LLVM has since removed the `CodeModel::Default` enum value in favor of an `Optional` implementationg throughout LLVM. Let's mirror the same change in Rust and update the various bindings we call accordingly. Removed in llvm-mirror/llvm@9aafb854c --- src/librustc_back/target/mod.rs | 8 ++++---- src/librustc_llvm/ffi.rs | 3 +-- src/librustc_trans/back/write.rs | 32 +++++++++++++++++--------------- src/rustllvm/PassWrapper.cpp | 22 ++++++++++++++-------- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index b65b18d0caa8c..2e860f940a7a7 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -320,8 +320,8 @@ pub struct TargetOptions { /// Relocation model to use in object file. Corresponds to `llc /// -relocation-model=$relocation_model`. Defaults to "pic". pub relocation_model: String, - /// Code model to use. Corresponds to `llc -code-model=$code_model`. Defaults to "default". - pub code_model: String, + /// Code model to use. Corresponds to `llc -code-model=$code_model`. + pub code_model: Option, /// TLS model to use. Options are "global-dynamic" (default), "local-dynamic", "initial-exec" /// and "local-exec". This is similar to the -ftls-model option in GCC/Clang. pub tls_model: String, @@ -483,7 +483,7 @@ impl Default for TargetOptions { only_cdylib: false, executables: false, relocation_model: "pic".to_string(), - code_model: "default".to_string(), + code_model: None, tls_model: "global-dynamic".to_string(), disable_redzone: false, eliminate_frame_pointer: true, @@ -736,7 +736,7 @@ impl Target { key!(only_cdylib, bool); key!(executables, bool); key!(relocation_model); - key!(code_model); + key!(code_model, optional); key!(tls_model); key!(disable_redzone, bool); key!(eliminate_frame_pointer, bool); diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index f51e51a88b10f..9ce34a95eff62 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -299,12 +299,11 @@ pub enum RelocMode { #[repr(C)] pub enum CodeModel { Other, - Default, - JITDefault, Small, Kernel, Medium, Large, + None, } /// LLVMRustDiagnosticKind diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index a013af7a4600e..863f006985349 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -68,8 +68,7 @@ pub const RELOC_MODEL_ARGS : [(&'static str, llvm::RelocMode); 7] = [ ("ropi-rwpi", llvm::RelocMode::ROPI_RWPI), ]; -pub const CODE_GEN_MODEL_ARGS : [(&'static str, llvm::CodeModel); 5] = [ - ("default", llvm::CodeModel::Default), +pub const CODE_GEN_MODEL_ARGS: &[(&str, llvm::CodeModel)] = &[ ("small", llvm::CodeModel::Small), ("kernel", llvm::CodeModel::Kernel), ("medium", llvm::CodeModel::Medium), @@ -170,20 +169,23 @@ pub fn target_machine_factory(sess: &Session) let ffunction_sections = sess.target.target.options.function_sections; let fdata_sections = ffunction_sections; - let code_model_arg = match sess.opts.cg.code_model { - Some(ref s) => &s, - None => &sess.target.target.options.code_model, - }; - - let code_model = match CODE_GEN_MODEL_ARGS.iter().find( - |&&arg| arg.0 == code_model_arg) { - Some(x) => x.1, - _ => { - sess.err(&format!("{:?} is not a valid code model", - code_model_arg)); - sess.abort_if_errors(); - bug!(); + let code_model_arg = sess.opts.cg.code_model.as_ref().or( + sess.target.target.options.code_model.as_ref(), + ); + + let code_model = match code_model_arg { + Some(s) => { + match CODE_GEN_MODEL_ARGS.iter().find(|arg| arg.0 == s) { + Some(x) => x.1, + _ => { + sess.err(&format!("{:?} is not a valid code model", + code_model_arg)); + sess.abort_if_errors(); + bug!(); + } + } } + None => llvm::CodeModel::None, }; let singlethread = sess.target.target.options.singlethread; diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 54a73a04bfa9e..b501f6150bef8 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -23,9 +23,14 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#if LLVM_VERSION_GE(6, 0) +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#else +#include "llvm/Target/TargetSubtargetInfo.h" +#endif + #if LLVM_VERSION_GE(4, 0) #include "llvm/Transforms/IPO/AlwaysInliner.h" #include "llvm/Transforms/IPO/FunctionImport.h" @@ -210,20 +215,15 @@ extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM, enum class LLVMRustCodeModel { Other, - Default, - JITDefault, Small, Kernel, Medium, Large, + None, }; static CodeModel::Model fromRust(LLVMRustCodeModel Model) { switch (Model) { - case LLVMRustCodeModel::Default: - return CodeModel::Default; - case LLVMRustCodeModel::JITDefault: - return CodeModel::JITDefault; case LLVMRustCodeModel::Small: return CodeModel::Small; case LLVMRustCodeModel::Kernel: @@ -360,7 +360,6 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool TrapUnreachable, bool Singlethread) { - auto CM = fromRust(RustCM); auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -399,6 +398,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( Options.ThreadModel = ThreadModel::Single; } +#if LLVM_VERSION_GE(6, 0) + Optional CM; +#else + CodeModel::Model CM = CodeModel::Model::Default; +#endif + if (RustCM != LLVMRustCodeModel::None) + CM = fromRust(RustCM); TargetMachine *TM = TheTarget->createTargetMachine( Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel); return wrap(TM); From 2a7ed74d96168fe1c187fbaa0d74dc52974b6ecf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:28:09 -0800 Subject: [PATCH 2/7] llvm6: Missing include for LLVM 6 in PassWrapper.cpp Just bog-standard compile error fixed by adding some new header files --- src/rustllvm/PassWrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index b501f6150bef8..b2f1229891d26 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -27,6 +27,7 @@ #if LLVM_VERSION_GE(6, 0) #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/IR/IntrinsicInst.h" #else #include "llvm/Target/TargetSubtargetInfo.h" #endif From 9eeecd2adad8c5c94348dbd1c61709fa49f65ff8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:28:23 -0800 Subject: [PATCH 3/7] llvm6: Tweak fast math intrinsics Looks like they did some refactoring of flags in the backend and this should catch us up! The "unsafe algebra" boolean has been split into a number of boolean flags for various operations, and this updates to use the `setFast` function which should hopefully have the same behavior as before. This was updated in llvm-mirror/llvm@00e900afd --- src/rustllvm/RustWrapper.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 0fe533d447bc3..3491e5a4aed5a 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -315,7 +315,11 @@ extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn, // enable fpmath flag UnsafeAlgebra extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) { if (auto I = dyn_cast(unwrap(V))) { +#if LLVM_VERSION_GE(6, 0) + I->setFast(true); +#else I->setHasUnsafeAlgebra(true); +#endif } } From b6fe1127e4b28aded8a1b0f95340e2de7dc12716 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:30:22 -0800 Subject: [PATCH 4/7] llvm6: Remove MIPS64 archive variant It looks like LLVM also removed it in llvm-mirror/llvm@f45adc29d in favor of the name "GNU64". This was added in the thought that we'd need such a variant when adding mips64 support but we ended up not needing it! For now let's just removing the various support on the Rust side of things. --- src/librustc_llvm/ffi.rs | 1 - src/librustc_llvm/lib.rs | 1 - src/rustllvm/ArchiveWrapper.cpp | 3 --- 3 files changed, 5 deletions(-) diff --git a/src/librustc_llvm/ffi.rs b/src/librustc_llvm/ffi.rs index 9ce34a95eff62..f5989a77fa925 100644 --- a/src/librustc_llvm/ffi.rs +++ b/src/librustc_llvm/ffi.rs @@ -330,7 +330,6 @@ pub enum DiagnosticKind { pub enum ArchiveKind { Other, K_GNU, - K_MIPS64, K_BSD, K_COFF, } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index c75a026a0f8b9..8dcf7444dd18f 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -105,7 +105,6 @@ impl FromStr for ArchiveKind { fn from_str(s: &str) -> Result { match s { "gnu" => Ok(ArchiveKind::K_GNU), - "mips64" => Ok(ArchiveKind::K_MIPS64), "bsd" => Ok(ArchiveKind::K_BSD), "coff" => Ok(ArchiveKind::K_COFF), _ => Err(()), diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index b110013ceaed3..d185da9c2f83e 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -42,7 +42,6 @@ struct RustArchiveIterator { enum class LLVMRustArchiveKind { Other, GNU, - MIPS64, BSD, COFF, }; @@ -51,8 +50,6 @@ static Archive::Kind fromRust(LLVMRustArchiveKind Kind) { switch (Kind) { case LLVMRustArchiveKind::GNU: return Archive::K_GNU; - case LLVMRustArchiveKind::MIPS64: - return Archive::K_MIPS64; case LLVMRustArchiveKind::BSD: return Archive::K_BSD; case LLVMRustArchiveKind::COFF: From caedb36f081334451ba83e9524af025891208592 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 22 Jan 2018 17:59:27 -0800 Subject: [PATCH 5/7] llvm6: Different return value for writeArchive Updated in llvm-mirror/llvm@203c90ba this function now just returns an `Error`, so this updates the C++ bindings accordingly --- src/rustllvm/ArchiveWrapper.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/rustllvm/ArchiveWrapper.cpp b/src/rustllvm/ArchiveWrapper.cpp index d185da9c2f83e..93157cd681942 100644 --- a/src/rustllvm/ArchiveWrapper.cpp +++ b/src/rustllvm/ArchiveWrapper.cpp @@ -232,9 +232,16 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers, Members.push_back(std::move(*MOrErr)); } } - auto Pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false); - if (!Pair.second) + auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false); +#if LLVM_VERSION_GE(6, 0) + if (!Result) return LLVMRustResult::Success; - LLVMRustSetLastError(Pair.second.message().c_str()); + LLVMRustSetLastError(toString(std::move(Result)).c_str()); +#else + if (!Result.second) + return LLVMRustResult::Success; + LLVMRustSetLastError(Result.second.message().c_str()); +#endif + return LLVMRustResult::Failure; } From 63b3168448061a510915d76630c6803de8cac595 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 23 Jan 2018 21:59:53 -0800 Subject: [PATCH 6/7] llvm6: Don't clone LLVM modules on wasm The comment for why cloning exists doesn't actually apply for wasm today and apparently cloning is causing subtle bugs in LLVM, so let's just avoid it altogether. More specifically after we emit the assembly for the wasm target we don't actually use the module again, so there's no need to keep both around. This seemed to be causing some scary verifier assertions in LLVM which seemed to be uncovered by presumably (?) buggy behavior. Let's just avoid it for now and make the wasm target slightly more lean in the process. --- src/librustc_trans/back/write.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 863f006985349..957b97fc8a042 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -733,7 +733,7 @@ unsafe fn codegen(cgcx: &CodegenContext, // We can't use the same module for asm and binary output, because that triggers // various errors like invalid IR or broken binaries, so we might have to clone the // module to produce the asm output - let llmod = if config.emit_obj { + let llmod = if config.emit_obj && !asm2wasm { llvm::LLVMCloneModule(llmod) } else { llmod @@ -742,7 +742,7 @@ unsafe fn codegen(cgcx: &CodegenContext, write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile) })?; - if config.emit_obj { + if config.emit_obj && !asm2wasm { llvm::LLVMDisposeModule(llmod); } timeline.record("asm"); From e9a64996bedbc224d1edb401162d2c3cc15eb7c1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 23 Jan 2018 10:25:50 -0800 Subject: [PATCH 7/7] llvm6: Update FreeBSD images to Ubuntu 18.04 Looks like the clang with 16.04 fails to compile LLVM 6, but it looks like clang in 18.04 can indeed compile LLVM 6. --- src/ci/docker/dist-i686-freebsd/Dockerfile | 2 +- src/ci/docker/dist-x86_64-freebsd/Dockerfile | 2 +- src/llvm-emscripten | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 160000 src/llvm-emscripten diff --git a/src/ci/docker/dist-i686-freebsd/Dockerfile b/src/ci/docker/dist-i686-freebsd/Dockerfile index 686afc97289b1..673fa4c0c4bc0 100644 --- a/src/ci/docker/dist-i686-freebsd/Dockerfile +++ b/src/ci/docker/dist-i686-freebsd/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 RUN apt-get update && apt-get install -y --no-install-recommends \ clang \ diff --git a/src/ci/docker/dist-x86_64-freebsd/Dockerfile b/src/ci/docker/dist-x86_64-freebsd/Dockerfile index 7483d395622c8..f9f5b7062f8a4 100644 --- a/src/ci/docker/dist-x86_64-freebsd/Dockerfile +++ b/src/ci/docker/dist-x86_64-freebsd/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:16.04 +FROM ubuntu:18.04 RUN apt-get update && apt-get install -y --no-install-recommends \ clang \ diff --git a/src/llvm-emscripten b/src/llvm-emscripten new file mode 160000 index 0000000000000..2717444753318 --- /dev/null +++ b/src/llvm-emscripten @@ -0,0 +1 @@ +Subproject commit 2717444753318e461e0c3b30dacd03ffbac96903