From 5ec2efcf2fc50f9efaf3d7b234325dc5323c2f55 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Sun, 14 Oct 2018 22:45:57 -0700 Subject: [PATCH] add support for building LLVM 7.0 from downloaded source --- .dockerignore | 1 + .gitignore | 3 +- Dockerfile | 10 +- shader-compiler-llvm-7/Cargo.toml | 12 +- shader-compiler-llvm-7/build.rs | 298 ++++++++++++++++++++++++++ shader-compiler-llvm-7/src/backend.rs | 196 ++++++++--------- shader-compiler-llvm-7/src/lib.rs | 9 +- shader-compiler/src/backend/mod.rs | 5 +- 8 files changed, 413 insertions(+), 121 deletions(-) create mode 100644 shader-compiler-llvm-7/build.rs diff --git a/.dockerignore b/.dockerignore index d4c901f..0c49855 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,3 +5,4 @@ /VK-GL-CTS /TestResults.qpa /.git +/external/llvm-7 diff --git a/.gitignore b/.gitignore index 8889c73..5a9610f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /Cargo.lock /VK-GL-CTS /TestResults.qpa -/.vscode \ No newline at end of file +/.vscode +/external/llvm-7 diff --git a/Dockerfile b/Dockerfile index c3509d3..6a57621 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,15 @@ # SPDX-License-Identifier: LGPL-2.1-or-later # Copyright 2018 Jacob Lifshay FROM rust:stretch -# Note that APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE makes apt-key ignore the output not being a terminal RUN set -e; \ - printf "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-7 main\ndeb-src http://apt.llvm.org/stretch/ llvm-toolchain-stretch-7 main" > /etc/apt/sources.list.d/llvm.list; \ - (wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add -) 2>&1; \ apt-get update; \ apt-get install -y \ - clang-7 \ - libclang-7-dev \ - llvm-7-dev \ cmake \ ninja-build \ libgl1-mesa-dev \ libxcb-shm0 \ + libclang-dev \ + clang \ ; \ rm -rf /var/lib/apt/lists/* WORKDIR /build @@ -35,7 +31,7 @@ RUN set -e; \ echo "// empty" > vulkan-driver/src/lib.rs; \ echo "// empty" > shader-compiler/src/lib.rs; \ echo "// empty" > shader-compiler-llvm-7/src/lib.rs; \ - cargo build; \ + cargo build -vv; \ rm */src/lib.rs COPY . . RUN touch -c */src/lib.rs && cargo build diff --git a/shader-compiler-llvm-7/Cargo.toml b/shader-compiler-llvm-7/Cargo.toml index 676d9d9..b353559 100644 --- a/shader-compiler-llvm-7/Cargo.toml +++ b/shader-compiler-llvm-7/Cargo.toml @@ -11,4 +11,14 @@ crate-type = ["rlib"] [dependencies] shader-compiler = {path = "../shader-compiler"} -llvm-sys = "70" + +[build-dependencies] +cmake = "0.1.35" +bindgen = "0.42" +tar = "0.4.17" +reqwest = "0.9" +xz2 = "0.1.6" +ring = "0.13" +cc = "1.0" +fs2 = "0.4.3" +which = "2.0.0" diff --git a/shader-compiler-llvm-7/build.rs b/shader-compiler-llvm-7/build.rs new file mode 100644 index 0000000..df7bceb --- /dev/null +++ b/shader-compiler-llvm-7/build.rs @@ -0,0 +1,298 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// Copyright 2018 Jacob Lifshay + +// Partially based on llvm-sys; llvm-sys's license is reproduced below: + +// Copyright (c) 2015 Peter Marheine +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +extern crate bindgen; +extern crate cc; +extern crate cmake; +extern crate fs2; +extern crate reqwest; +extern crate ring; +extern crate tar; +extern crate which; +extern crate xz2; +use fs2::FileExt; +use std::env; +use std::ffi::OsStr; +use std::fs; +use std::io; +use std::io::prelude::*; +use std::path::{Path, PathBuf}; +use std::process::Command; + +const LLVM_7_SOURCE_TAR_XZ_URL: &'static str = + "http://releases.llvm.org/7.0.0/llvm-7.0.0.src.tar.xz"; + +const LLVM_7_SOURCE_TAR_XZ_SHA256_HASH: &'static [u8; 32] = &[ + 0x8b, 0xc1, 0xf8, 0x44, 0xe6, 0xcb, 0xde, 0x1b, 0x65, 0x2c, 0x19, 0xc1, 0xed, 0xeb, 0xc1, 0x86, + 0x44, 0x56, 0xfd, 0x9c, 0x78, 0xb8, 0xc1, 0xbe, 0xa0, 0x38, 0xe5, 0x1b, 0x36, 0x3f, 0xe2, 0x22, +]; + +const LLVM_7_SOURCE_DIR_SUFFIX: &'static str = "llvm-7.0.0.src"; + +fn verify_sha256(mut f: fs::File, file_path: &Path) -> fs::File { + f.seek(io::SeekFrom::Start(0)).unwrap(); + let mut context = ring::digest::Context::new(&ring::digest::SHA256); + let mut buffer = [0; 1 << 12]; // 4KiB + loop { + let count = f.read(&mut buffer).unwrap(); + if count == 0 { + break; + } + context.update(&buffer[..count]); + } + let hash = context.finish(); + if hash.as_ref() != LLVM_7_SOURCE_TAR_XZ_SHA256_HASH { + panic!( + "file is corrupted: SHA256 doesn't match; try deleting {} and rerunning cargo", + file_path.display(), + ); + } + f.seek(io::SeekFrom::Start(0)).unwrap(); + f +} + +fn download_llvm_7(out_dir: &Path) -> io::Result { + let filename = LLVM_7_SOURCE_TAR_XZ_URL.rsplit('/').next().unwrap(); + let file_path = out_dir.join(filename); + match fs::File::open(&file_path) { + Ok(file) => return Ok(verify_sha256(file, &file_path)), + Err(ref error) if error.kind() == io::ErrorKind::NotFound => {} + Err(error) => return Err(error), + }; + let response = reqwest::get(LLVM_7_SOURCE_TAR_XZ_URL) + .map_err(|v| io::Error::new(io::ErrorKind::Other, v))?; + let file = fs::OpenOptions::new() + .write(true) + .create_new(true) + .open(&file_path)?; + { response } + .copy_to(&mut { file }) + .map_err(|v| io::Error::new(io::ErrorKind::Other, v))?; + Ok(verify_sha256(fs::File::open(&file_path)?, &file_path)) +} + +fn extract_tar_xz>(r: R, target_path: T) -> io::Result<()> { + tar::Archive::new(xz2::read::XzDecoder::new(r)).unpack(target_path) +} + +fn download_and_extract_llvm_7_if_needed(llvm_dir: &Path) -> io::Result { + let source_dir = llvm_dir.join(LLVM_7_SOURCE_DIR_SUFFIX); + match fs::File::open(source_dir.join("CMakeLists.txt")) { + Ok(_) => return Ok(source_dir), + Err(ref error) if error.kind() == io::ErrorKind::NotFound => {} + Err(error) => return Err(error), + } + extract_tar_xz(download_llvm_7(llvm_dir)?, llvm_dir)?; + Ok(source_dir) +} + +fn make_config(llvm_dir: &Path) -> cmake::Config { + let mut retval = cmake::Config::new(llvm_dir.join(LLVM_7_SOURCE_DIR_SUFFIX)); + let found_ccache = match which::which("ccache") { + Err(ref error) if error.kind() == which::ErrorKind::CannotFindBinaryPath => false, + result => { + result.unwrap(); + true + } + }; + retval + .generator("Ninja") + .define("LLVM_TARGETS_TO_BUILD", "host") + .define("LLVM_CCACHE_BUILD", if found_ccache { "ON" } else { "OFF" }) + .define( + "LLVM_TARGET_ARCH", + env::var("TARGET").unwrap().split("-").next().unwrap(), + ) + .out_dir(llvm_dir) + .profile("RelWithDebInfo") + .always_configure(false); + retval +} + +fn llvm_config, S: AsRef>( + llvm_config_path: &Path, + args: A, +) -> String { + String::from_utf8( + Command::new(llvm_config_path) + .arg("--link-static") + .args(args) + .output() + .unwrap() + .stdout, + ) + .unwrap() +} + +fn get_libs, S: AsRef>( + llvm_config_path: &Path, + args: A, +) -> Vec { + llvm_config(&llvm_config_path, args) + .split_whitespace() + .filter_map(|flag| { + if flag == "" { + None + } else if cfg!(target_env = "msvc") { + // Same as --libnames, foo.lib + assert!(flag.ends_with(".lib")); + Some(&flag[..flag.len() - 4]) + } else { + // Linker flags style, -lfoo + assert!(flag.starts_with("-l")); + Some(&flag[2..]) + } + }) + .map(Into::into) + .collect() +} + +struct LockedFile(fs::File); + +impl Drop for LockedFile { + fn drop(&mut self) { + let _ = self.0.unlock(); + } +} + +impl LockedFile { + fn new>(file_path: T) -> io::Result { + let file = fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .open(file_path)?; + file.lock_exclusive()?; + Ok(LockedFile(file)) + } +} + +fn build_llvm() -> PathBuf { + assert_eq!( + env::var_os("TARGET"), + env::var_os("HOST"), + "cross-compilation is not supported" + ); + let llvm_dir = env::current_dir() + .unwrap() + .join("..") + .join("external") + .join("llvm-7") + .join(env::var_os("TARGET").unwrap()); + fs::create_dir_all(&llvm_dir).unwrap(); + let _locked_file = LockedFile::new(llvm_dir.join(".build-lock")).unwrap(); + download_and_extract_llvm_7_if_needed(&llvm_dir).unwrap(); + make_config(&llvm_dir).build_target("install").build(); + #[cfg(windows)] + let llvm_config_path = llvm_dir.join("bin").join("llvm-config.exe"); + #[cfg(not(windows))] + let llvm_config_path = llvm_dir.join("bin").join("llvm-config"); + llvm_config_path +} + +fn main() { + let out_dir = Path::new(&env::var_os("OUT_DIR").unwrap()).to_path_buf(); + let llvm_config_path = build_llvm(); + println!( + "cargo:rustc-link-search=native={}", + llvm_config(&llvm_config_path, Some("--libdir")) + ); + let llvm_libs = get_libs(&llvm_config_path, Some("--libs")); + for lib in llvm_libs { + println!("cargo:rustc-link-lib=static={}", lib); + } + let header = r#" +#include "llvm-c/Core.h" +#include "llvm-c/OrcBindings.h" +#include "llvm-c/Target.h" +#include "llvm-c/Analysis.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +void LLVM_InitializeNativeTarget(void); +void LLVM_InitializeNativeAsmParser(void); +void LLVM_InitializeNativeAsmPrinter(void); +void LLVM_InitializeNativeDisassembler(void); + +#ifdef __cplusplus +} +#endif +"#; + let header_path = out_dir.join("llvm_bindings.h"); + fs::write(&header_path, header).unwrap(); + let llvm_bindings_source = format!("#include {:?}\n", header_path) + r#" +void LLVM_InitializeNativeTarget(void) +{ + LLVM_NATIVE_TARGETINFO(); + LLVM_NATIVE_TARGET(); + LLVM_NATIVE_TARGETMC(); +} + +void LLVM_InitializeNativeAsmParser(void) +{ + LLVM_NATIVE_ASMPARSER(); +} + +void LLVM_InitializeNativeAsmPrinter(void) +{ + LLVM_NATIVE_ASMPRINTER(); +} + +void LLVM_InitializeNativeDisassembler(void) +{ + LLVM_NATIVE_DISASSEMBLER(); +} +"#; + let llvm_bindings_path = out_dir.join("llvm_bindings.c"); + fs::write(&llvm_bindings_path, llvm_bindings_source).unwrap(); + let include_dir: String = llvm_config(&llvm_config_path, Some("--includedir")) + .trim_right() + .into(); + let builder = bindgen::Builder::default() + .header(header_path.to_str().unwrap()) + .clang_arg("-I") + .clang_arg(&include_dir as &str) + .rustfmt_bindings(true) + .whitelist_type("LLVM.*") + .whitelist_function("LLVM.*") + .whitelist_var("LLVM.*") + .blacklist_type("^__.*") + .prepend_enum_name(false) + .constified_enum("LLVM.*"); + builder + .generate() + .unwrap() + .write_to_file(out_dir.join("llvm_c.rs")) + .unwrap(); + cc::Build::new() + .cpp(true) + .file(llvm_bindings_path) + .include(&include_dir) + .compile("llvm_bindings"); +} diff --git a/shader-compiler-llvm-7/src/backend.rs b/shader-compiler-llvm-7/src/backend.rs index cbb7b51..a1c3af5 100644 --- a/shader-compiler-llvm-7/src/backend.rs +++ b/shader-compiler-llvm-7/src/backend.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: LGPL-2.1-or-later // Copyright 2018 Jacob Lifshay -use llvm_sys; +use llvm; use shader_compiler::backend; use std::cell::Cell; use std::ffi::{CStr, CString}; @@ -11,7 +11,7 @@ use std::ptr::null_mut; use std::ptr::NonNull; use std::sync::{Once, ONCE_INIT}; -fn to_bool(v: llvm_sys::prelude::LLVMBool) -> bool { +fn to_bool(v: llvm::LLVMBool) -> bool { v != 0 } @@ -43,7 +43,7 @@ struct LLVM7String(NonNull); impl Drop for LLVM7String { fn drop(&mut self) { unsafe { - llvm_sys::core::LLVMDisposeMessage(self.0.as_ptr()); + llvm::LLVMDisposeMessage(self.0.as_ptr()); } } } @@ -63,7 +63,7 @@ impl Clone for LLVM7String { impl LLVM7String { fn new(v: &CStr) -> Self { - unsafe { Self::from_ptr(llvm_sys::core::LLVMCreateMessage(v.as_ptr())).unwrap() } + unsafe { Self::from_ptr(llvm::LLVMCreateMessage(v.as_ptr())).unwrap() } } unsafe fn from_nonnull(v: NonNull) -> Self { LLVM7String(v) @@ -81,13 +81,13 @@ impl fmt::Debug for LLVM7String { #[derive(Clone, Eq, PartialEq, Hash)] #[repr(transparent)] -pub struct LLVM7Type(llvm_sys::prelude::LLVMTypeRef); +pub struct LLVM7Type(llvm::LLVMTypeRef); impl fmt::Debug for LLVM7Type { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { unsafe { - let string = LLVM7String::from_ptr(llvm_sys::core::LLVMPrintTypeToString(self.0)) - .ok_or(fmt::Error)?; + let string = + LLVM7String::from_ptr(llvm::LLVMPrintTypeToString(self.0)).ok_or(fmt::Error)?; f.write_str(&string.to_string_lossy()) } } @@ -98,38 +98,38 @@ impl<'a> backend::types::Type<'a> for LLVM7Type { } pub struct LLVM7TypeBuilder { - context: llvm_sys::prelude::LLVMContextRef, + context: llvm::LLVMContextRef, variable_vector_length_multiplier: u32, } impl<'a> backend::types::TypeBuilder<'a, LLVM7Type> for LLVM7TypeBuilder { fn build_bool(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMInt1TypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMInt1TypeInContext(self.context)) } } fn build_i8(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMInt8TypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMInt8TypeInContext(self.context)) } } fn build_i16(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMInt16TypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMInt16TypeInContext(self.context)) } } fn build_i32(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMInt32TypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMInt32TypeInContext(self.context)) } } fn build_i64(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMInt64TypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMInt64TypeInContext(self.context)) } } fn build_f32(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMFloatTypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMFloatTypeInContext(self.context)) } } fn build_f64(&self) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMDoubleTypeInContext(self.context)) } + unsafe { LLVM7Type(llvm::LLVMDoubleTypeInContext(self.context)) } } fn build_pointer(&self, target: LLVM7Type) -> LLVM7Type { - unsafe { LLVM7Type(llvm_sys::core::LLVMPointerType(target.0, 0)) } + unsafe { LLVM7Type(llvm::LLVMPointerType(target.0, 0)) } } fn build_array(&self, element: LLVM7Type, count: usize) -> LLVM7Type { assert_eq!(count as u32 as usize, count); - unsafe { LLVM7Type(llvm_sys::core::LLVMArrayType(element.0, count as u32)) } + unsafe { LLVM7Type(llvm::LLVMArrayType(element.0, count as u32)) } } fn build_vector(&self, element: LLVM7Type, length: backend::types::VectorLength) -> LLVM7Type { use self::backend::types::VectorLength::*; @@ -140,31 +140,29 @@ impl<'a> backend::types::TypeBuilder<'a, LLVM7Type> for LLVM7TypeBuilder { .unwrap(), }; assert_ne!(length, 0); - unsafe { LLVM7Type(llvm_sys::core::LLVMVectorType(element.0, length)) } + unsafe { LLVM7Type(llvm::LLVMVectorType(element.0, length)) } } fn build_struct(&self, members: &[LLVM7Type]) -> LLVM7Type { assert_eq!(members.len() as c_uint as usize, members.len()); unsafe { - LLVM7Type(llvm_sys::core::LLVMStructTypeInContext( + LLVM7Type(llvm::LLVMStructTypeInContext( self.context, - members.as_ptr() as *mut llvm_sys::prelude::LLVMTypeRef, + members.as_ptr() as *mut llvm::LLVMTypeRef, members.len() as c_uint, - false as llvm_sys::prelude::LLVMBool, + false as llvm::LLVMBool, )) } } fn build_function(&self, arguments: &[LLVM7Type], return_type: Option) -> LLVM7Type { assert_eq!(arguments.len() as c_uint as usize, arguments.len()); unsafe { - LLVM7Type(llvm_sys::core::LLVMFunctionType( + LLVM7Type(llvm::LLVMFunctionType( return_type - .unwrap_or_else(|| { - LLVM7Type(llvm_sys::core::LLVMVoidTypeInContext(self.context)) - }) + .unwrap_or_else(|| LLVM7Type(llvm::LLVMVoidTypeInContext(self.context))) .0, - arguments.as_ptr() as *mut llvm_sys::prelude::LLVMTypeRef, + arguments.as_ptr() as *mut llvm::LLVMTypeRef, arguments.len() as c_uint, - false as llvm_sys::prelude::LLVMBool, + false as llvm::LLVMBool, )) } } @@ -172,13 +170,13 @@ impl<'a> backend::types::TypeBuilder<'a, LLVM7Type> for LLVM7TypeBuilder { #[derive(Clone)] #[repr(transparent)] -pub struct LLVM7Value(llvm_sys::prelude::LLVMValueRef); +pub struct LLVM7Value(llvm::LLVMValueRef); impl fmt::Debug for LLVM7Value { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { unsafe { - let string = LLVM7String::from_ptr(llvm_sys::core::LLVMPrintValueToString(self.0)) - .ok_or(fmt::Error)?; + let string = + LLVM7String::from_ptr(llvm::LLVMPrintValueToString(self.0)).ok_or(fmt::Error)?; f.write_str(&string.to_string_lossy()) } } @@ -190,15 +188,14 @@ impl<'a> backend::Value<'a> for LLVM7Value { #[derive(Clone)] #[repr(transparent)] -pub struct LLVM7BasicBlock(llvm_sys::prelude::LLVMBasicBlockRef); +pub struct LLVM7BasicBlock(llvm::LLVMBasicBlockRef); impl fmt::Debug for LLVM7BasicBlock { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::backend::BasicBlock; unsafe { - let string = - LLVM7String::from_ptr(llvm_sys::core::LLVMPrintValueToString(self.as_value().0)) - .ok_or(fmt::Error)?; + let string = LLVM7String::from_ptr(llvm::LLVMPrintValueToString(self.as_value().0)) + .ok_or(fmt::Error)?; f.write_str(&string.to_string_lossy()) } } @@ -207,7 +204,7 @@ impl fmt::Debug for LLVM7BasicBlock { impl<'a> backend::BasicBlock<'a> for LLVM7BasicBlock { type Context = LLVM7Context; fn as_value(&self) -> LLVM7Value { - unsafe { LLVM7Value(llvm_sys::core::LLVMBasicBlockAsValue(self.0)) } + unsafe { LLVM7Value(llvm::LLVMBasicBlockAsValue(self.0)) } } } @@ -219,16 +216,15 @@ impl<'a> backend::BuildableBasicBlock<'a> for LLVM7BasicBlock { } pub struct LLVM7Function { - context: llvm_sys::prelude::LLVMContextRef, - function: llvm_sys::prelude::LLVMValueRef, + context: llvm::LLVMContextRef, + function: llvm::LLVMValueRef, } impl fmt::Debug for LLVM7Function { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { unsafe { - let string = - LLVM7String::from_ptr(llvm_sys::core::LLVMPrintValueToString(self.function)) - .ok_or(fmt::Error)?; + let string = LLVM7String::from_ptr(llvm::LLVMPrintValueToString(self.function)) + .ok_or(fmt::Error)?; f.write_str(&string.to_string_lossy()) } } @@ -242,7 +238,7 @@ impl<'a> backend::Function<'a> for LLVM7Function { fn append_new_basic_block(&mut self, name: Option<&str>) -> LLVM7BasicBlock { let name = CString::new(name.unwrap_or("")).unwrap(); unsafe { - LLVM7BasicBlock(llvm_sys::core::LLVMAppendBasicBlockInContext( + LLVM7BasicBlock(llvm::LLVMAppendBasicBlockInContext( self.context, self.function, name.as_ptr(), @@ -252,8 +248,8 @@ impl<'a> backend::Function<'a> for LLVM7Function { } pub struct LLVM7Context { - context: llvm_sys::prelude::LLVMContextRef, - modules: Cell>, + context: llvm::LLVMContextRef, + modules: Cell>, config: LLVM7CompilerConfig, } @@ -261,9 +257,9 @@ impl Drop for LLVM7Context { fn drop(&mut self) { unsafe { for module in self.modules.get_mut().drain(..) { - llvm_sys::core::LLVMDisposeModule(module); + llvm::LLVMDisposeModule(module); } - llvm_sys::core::LLVMContextDispose(self.context); + llvm::LLVMContextDispose(self.context); } } } @@ -284,8 +280,7 @@ impl<'a> backend::Context<'a> for LLVM7Context { let mut modules = self.modules.take(); modules.reserve(1); // so we don't unwind without freeing the new module unsafe { - let module = - llvm_sys::core::LLVMModuleCreateWithNameInContext(name.as_ptr(), self.context); + let module = llvm::LLVMModuleCreateWithNameInContext(name.as_ptr(), self.context); modules.push(module); self.modules.set(modules); LLVM7Module { @@ -295,7 +290,7 @@ impl<'a> backend::Context<'a> for LLVM7Context { } } fn create_builder(&self) -> LLVM7Builder { - unsafe { LLVM7Builder(llvm_sys::core::LLVMCreateBuilderInContext(self.context)) } + unsafe { LLVM7Builder(llvm::LLVMCreateBuilderInContext(self.context)) } } fn create_type_builder(&self) -> LLVM7TypeBuilder { LLVM7TypeBuilder { @@ -306,12 +301,12 @@ impl<'a> backend::Context<'a> for LLVM7Context { } #[repr(transparent)] -pub struct LLVM7Builder(llvm_sys::prelude::LLVMBuilderRef); +pub struct LLVM7Builder(llvm::LLVMBuilderRef); impl Drop for LLVM7Builder { fn drop(&mut self) { unsafe { - llvm_sys::core::LLVMDisposeBuilder(self.0); + llvm::LLVMDisposeBuilder(self.0); } } } @@ -319,15 +314,15 @@ impl Drop for LLVM7Builder { impl<'a> backend::AttachedBuilder<'a> for LLVM7Builder { type Context = LLVM7Context; fn current_basic_block(&self) -> LLVM7BasicBlock { - unsafe { LLVM7BasicBlock(llvm_sys::core::LLVMGetInsertBlock(self.0)) } + unsafe { LLVM7BasicBlock(llvm::LLVMGetInsertBlock(self.0)) } } fn build_return(self, value: Option) -> LLVM7Builder { unsafe { match value { - Some(value) => llvm_sys::core::LLVMBuildRet(self.0, value.0), - None => llvm_sys::core::LLVMBuildRetVoid(self.0), + Some(value) => llvm::LLVMBuildRet(self.0, value.0), + None => llvm::LLVMBuildRetVoid(self.0), }; - llvm_sys::core::LLVMClearInsertionPosition(self.0); + llvm::LLVMClearInsertionPosition(self.0); } self } @@ -337,23 +332,22 @@ impl<'a> backend::DetachedBuilder<'a> for LLVM7Builder { type Context = LLVM7Context; fn attach(self, basic_block: LLVM7BasicBlock) -> LLVM7Builder { unsafe { - llvm_sys::core::LLVMPositionBuilderAtEnd(self.0, basic_block.0); + llvm::LLVMPositionBuilderAtEnd(self.0, basic_block.0); } self } } pub struct LLVM7Module { - context: llvm_sys::prelude::LLVMContextRef, - module: llvm_sys::prelude::LLVMModuleRef, + context: llvm::LLVMContextRef, + module: llvm::LLVMModuleRef, } impl fmt::Debug for LLVM7Module { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { unsafe { - let string = - LLVM7String::from_ptr(llvm_sys::core::LLVMPrintModuleToString(self.module)) - .ok_or(fmt::Error)?; + let string = LLVM7String::from_ptr(llvm::LLVMPrintModuleToString(self.module)) + .ok_or(fmt::Error)?; f.write_str(&string.to_string_lossy()) } } @@ -363,7 +357,7 @@ impl<'a> backend::Module<'a> for LLVM7Module { type Context = LLVM7Context; fn set_source_file_name(&mut self, source_file_name: &str) { unsafe { - llvm_sys::core::LLVMSetSourceFileName( + llvm::LLVMSetSourceFileName( self.module, source_file_name.as_ptr() as *const c_char, source_file_name.len(), @@ -375,25 +369,22 @@ impl<'a> backend::Module<'a> for LLVM7Module { unsafe { LLVM7Function { context: self.context, - function: llvm_sys::core::LLVMAddFunction(self.module, name.as_ptr(), ty.0), + function: llvm::LLVMAddFunction(self.module, name.as_ptr(), ty.0), } } } fn verify(self) -> Result> { unsafe { let mut message = null_mut(); - match to_bool(llvm_sys::analysis::LLVMVerifyModule( + match to_bool(llvm::LLVMVerifyModule( self.module, - llvm_sys::analysis::LLVMVerifierFailureAction::LLVMReturnStatusAction, + llvm::LLVMReturnStatusAction, &mut message, )) { broken if broken != false => { let message = LLVM7String::from_ptr(message).unwrap(); let message = message.to_string_lossy(); - Err(backend::VerificationFailure::new( - self, - message.into_owned(), - )) + Err(backend::VerificationFailure::new(self, message.as_ref())) } _ => Ok(self), } @@ -411,32 +402,32 @@ impl<'a> backend::VerifiedModule<'a> for LLVM7Module { } } -struct LLVM7TargetMachine(llvm_sys::target_machine::LLVMTargetMachineRef); +struct LLVM7TargetMachine(llvm::LLVMTargetMachineRef); impl Drop for LLVM7TargetMachine { fn drop(&mut self) { unsafe { - llvm_sys::target_machine::LLVMDisposeTargetMachine(self.0); + llvm::LLVMDisposeTargetMachine(self.0); } } } impl LLVM7TargetMachine { - fn take(mut self) -> llvm_sys::target_machine::LLVMTargetMachineRef { + fn take(mut self) -> llvm::LLVMTargetMachineRef { let retval = self.0; self.0 = null_mut(); retval } } -struct LLVM7OrcJITStack(llvm_sys::orc::LLVMOrcJITStackRef); +struct LLVM7OrcJITStack(llvm::LLVMOrcJITStackRef); impl Drop for LLVM7OrcJITStack { fn drop(&mut self) { unsafe { - match llvm_sys::orc::LLVMOrcDisposeInstance(self.0) { - llvm_sys::orc::LLVMOrcErrorCode::LLVMOrcErrSuccess => {} - llvm_sys::orc::LLVMOrcErrorCode::LLVMOrcErrGeneric => { + match llvm::LLVMOrcDisposeInstance(self.0) { + llvm::LLVMOrcErrSuccess => {} + _ => { panic!("LLVMOrcDisposeInstance failed"); } } @@ -447,8 +438,8 @@ impl Drop for LLVM7OrcJITStack { fn initialize_native_target() { static ONCE: Once = ONCE_INIT; ONCE.call_once(|| unsafe { - assert_eq!(llvm_sys::target::LLVM_InitializeNativeTarget(), 0); - assert_eq!(llvm_sys::target::LLVM_InitializeNativeAsmParser(), 0); + llvm::LLVM_InitializeNativeTarget(); + llvm::LLVM_InitializeNativeAsmParser(); }); } @@ -473,7 +464,7 @@ impl backend::Compiler for LLVM7Compiler { unsafe { initialize_native_target(); let context = LLVM7Context { - context: llvm_sys::core::LLVMContextCreate(), + context: llvm::LLVMContextCreate(), modules: Vec::new().into(), config: config.clone(), }; @@ -483,16 +474,14 @@ impl backend::Compiler for LLVM7Compiler { } = user.run(&context)?; for callable_function in callable_functions.values() { assert_eq!( - llvm_sys::core::LLVMGetGlobalParent(callable_function.function), + llvm::LLVMGetGlobalParent(callable_function.function), module.module ); } - let target_triple = - LLVM7String::from_ptr(llvm_sys::target_machine::LLVMGetDefaultTargetTriple()) - .unwrap(); + let target_triple = LLVM7String::from_ptr(llvm::LLVMGetDefaultTargetTriple()).unwrap(); let mut target = null_mut(); let mut error = null_mut(); - let success = !to_bool(llvm_sys::target_machine::LLVMGetTargetFromTriple( + let success = !to_bool(llvm::LLVMGetTargetFromTriple( target_triple.as_ptr(), &mut target, &mut error, @@ -501,38 +490,31 @@ impl backend::Compiler for LLVM7Compiler { let error = LLVM7String::from_ptr(error).unwrap(); return Err(U::create_error(error.to_string_lossy().into())); } - if !to_bool(llvm_sys::target_machine::LLVMTargetHasJIT(target)) { + if !to_bool(llvm::LLVMTargetHasJIT(target)) { return Err(U::create_error(format!( "target {:?} doesn't support JIT", target_triple ))); } - let host_cpu_name = - LLVM7String::from_ptr(llvm_sys::target_machine::LLVMGetHostCPUName()).unwrap(); - let host_cpu_features = - LLVM7String::from_ptr(llvm_sys::target_machine::LLVMGetHostCPUFeatures()).unwrap(); - let target_machine = - LLVM7TargetMachine(llvm_sys::target_machine::LLVMCreateTargetMachine( - target, - target_triple.as_ptr(), - host_cpu_name.as_ptr(), - host_cpu_features.as_ptr(), - match config.optimization_mode { - backend::OptimizationMode::NoOptimizations => { - llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelNone - } - backend::OptimizationMode::Normal => { - llvm_sys::target_machine::LLVMCodeGenOptLevel::LLVMCodeGenLevelDefault - } - }, - llvm_sys::target_machine::LLVMRelocMode::LLVMRelocDefault, - llvm_sys::target_machine::LLVMCodeModel::LLVMCodeModelJITDefault, - )); + let host_cpu_name = LLVM7String::from_ptr(llvm::LLVMGetHostCPUName()).unwrap(); + let host_cpu_features = LLVM7String::from_ptr(llvm::LLVMGetHostCPUFeatures()).unwrap(); + let target_machine = LLVM7TargetMachine(llvm::LLVMCreateTargetMachine( + target, + target_triple.as_ptr(), + host_cpu_name.as_ptr(), + host_cpu_features.as_ptr(), + match config.optimization_mode { + backend::OptimizationMode::NoOptimizations => llvm::LLVMCodeGenLevelNone, + backend::OptimizationMode::Normal => llvm::LLVMCodeGenLevelDefault, + }, + llvm::LLVMRelocDefault, + llvm::LLVMCodeModelJITDefault, + )); assert!(!target_machine.0.is_null()); let orc_jit_stack = - LLVM7OrcJITStack(llvm_sys::orc::LLVMOrcCreateInstance(target_machine.take())); + LLVM7OrcJITStack(llvm::LLVMOrcCreateInstance(target_machine.take())); let mut orc_module_handle = 0; - llvm_sys::orc::LLVMOrcAddEagerlyCompiledIR( + llvm::LLVMOrcAddEagerlyCompiledIR( orc_jit_stack.0, &mut orc_module_handle, module.module, diff --git a/shader-compiler-llvm-7/src/lib.rs b/shader-compiler-llvm-7/src/lib.rs index c582f50..7b2e375 100644 --- a/shader-compiler-llvm-7/src/lib.rs +++ b/shader-compiler-llvm-7/src/lib.rs @@ -1,8 +1,15 @@ // SPDX-License-Identifier: LGPL-2.1-or-later // Copyright 2018 Jacob Lifshay -extern crate llvm_sys; extern crate shader_compiler; +// TODO: #[allow(clippy::const_static_lifetime)] +#[allow(dead_code)] +#[allow(non_upper_case_globals)] +#[allow(non_camel_case_types)] +mod llvm { + include!(concat!(env!("OUT_DIR"), "/llvm_c.rs")); +} + mod backend; mod tests; diff --git a/shader-compiler/src/backend/mod.rs b/shader-compiler/src/backend/mod.rs index 1ff6b9e..0ba1b6c 100644 --- a/shader-compiler/src/backend/mod.rs +++ b/shader-compiler/src/backend/mod.rs @@ -3,7 +3,6 @@ //! Shader Compiler Backend traits -use std::borrow::Borrow; use std::collections::HashMap; use std::error::Error; use std::fmt; @@ -11,8 +10,6 @@ use std::fmt::Debug; use std::hash::Hash; use std::io; use std::marker::PhantomData; -use std::os::raw::c_void; -use std::ptr::NonNull; #[macro_use] pub mod types; @@ -89,7 +86,7 @@ pub struct VerificationFailure<'a, M: Module<'a>> { impl<'a, M: Module<'a>> VerificationFailure<'a, M> { /// create a new `VerificationFailure` - pub fn new(module: M, message: T) -> Self { + pub fn new(module: M, message: &T) -> Self { VerificationFailure { module, message: message.to_string(), -- 2.30.2