Skip to content

Commit

Permalink
Merge pull request rust-lang#38 from TheDan64/three_eight
Browse files Browse the repository at this point in the history
Support LLVM 3.8
  • Loading branch information
TheDan64 committed Apr 17, 2018
2 parents e3a6f54 + cb6f413 commit 782f217
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
rustflags = ["-lffi"]
21 changes: 17 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-3.7-dev
- env:
- LLVM_VERSION="3.8"
<<: *BASE
addons:
apt:
sources:
- *BASE_SOURCES
- llvm-toolchain-precise-3.8
packages:
- *BASE_PACKAGES
- llvm-3.8-dev
- deploy: # Documentation build; Only latest supported LLVM version for now
provider: pages
skip-cleanup: true
Expand All @@ -64,7 +75,7 @@ matrix:
on:
branch: master
script:
- cargo doc --no-default-features --features llvm3-7
- cargo doc --no-default-features --features llvm3-8
- echo '<meta http-equiv="refresh" content="1; url=inkwell/index.html">' > target/doc/index.html
after_success:
rust: nightly
Expand All @@ -73,15 +84,17 @@ matrix:
sources:
- *BASE_SOURCES
# - llvm-toolchain-precise-3.6
- llvm-toolchain-precise-3.7
# - llvm-toolchain-precise-3.7
- llvm-toolchain-precise-3.8
packages:
- *BASE_PACKAGES
# - llvm-3.6-dev
- llvm-3.7-dev
# - llvm-3.7-dev
- llvm-3.8-dev

env:
global:
- RUSTFLAGS="-C link-dead-code -C target-cpu=native"
- RUSTFLAGS="-C link-dead-code -C target-cpu=native -l ffi"

after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ categories = ["development-tools::ffi"]
default = []
llvm3-6 = []
llvm3-7 = []
llvm3-8 = []

[dependencies]
either = "1.4.0"
enum-methods = "0.0.8"
libc = "*"
llvm-sys = "37"
llvm-sys = "38"

[[example]]
name = "kaleidoscope"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Inkwell aims to help you pen your own programming languages by safely wrapping l

* Any Rust version released in the last year or so
* Rust Stable, Beta, or Nightly
* LLVM 3.6 or 3.7 (3.8+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1))
* LLVM 3.6, 3.7, or 3.8 (3.9+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1))

## Usage

Expand All @@ -31,6 +31,7 @@ Supported versions:
| :-----------: | :----------: |
| llvm3-6 | llvm3-6 |
| llvm3-7 | llvm3-7 |
| llvm3-8 | llvm3-8 |

In the root of your source code you will have to add an extern crate to begin using Inkwell:

Expand Down
12 changes: 9 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ pub mod types;
pub mod values;

use llvm_sys::{LLVMIntPredicate, LLVMRealPredicate, LLVMVisibility, LLVMThreadLocalMode, LLVMDLLStorageClass};
use llvm_sys::core::LLVMResetFatalErrorHandler;
use llvm_sys::support::LLVMLoadLibraryPermanently;

use std::ffi::CString;

#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8")))]
compile_error!("A LLVM feature flag must be provided. See the README for more details.");

// TODO: Probably move into error handling module
pub fn enable_llvm_pretty_stack_trace() {
// use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; // v3.8
#[cfg(any(feature = "llvm3-6", feature = "llvm3-7"))]
use llvm_sys::core::LLVMEnablePrettyStackTrace;
#[cfg(feature = "llvm3-8")]
use llvm_sys::error_handling::LLVMEnablePrettyStackTrace;

unsafe {
LLVMEnablePrettyStackTrace()
Expand Down Expand Up @@ -88,6 +89,11 @@ pub fn shutdown_llvm() {

/// Resets LLVM's fatal error handler back to the default
pub fn reset_fatal_error_handler() {
#[cfg(any(feature = "llvm3-6", feature = "llvm3-7"))]
use llvm_sys::core::LLVMResetFatalErrorHandler;
#[cfg(feature = "llvm3-8")]
use llvm_sys::error_handling::LLVMResetFatalErrorHandler;

unsafe {
LLVMResetFatalErrorHandler()
}
Expand Down
5 changes: 2 additions & 3 deletions src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use targets::TargetData;
use values::{AsValueRef, FunctionValue};

// REVIEW: Opt Level might be identical to targets::Option<CodeGenOptLevel>
// REVIEW: size_level 0-2 according to llvmlite
#[derive(Debug)]
pub struct PassManagerBuilder {
pass_manager_builder: LLVMPassManagerBuilderRef,
Expand All @@ -28,7 +27,7 @@ impl PassManagerBuilder {
assert!(!pass_manager_builder.is_null());

PassManagerBuilder {
pass_manager_builder: pass_manager_builder,
pass_manager_builder,
}
}

Expand Down Expand Up @@ -118,7 +117,7 @@ impl PassManager {
assert!(!pass_manager.is_null());

PassManager {
pass_manager: pass_manager
pass_manager,
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/types/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ impl AnyTypeEnum {
LLVMTypeKind::LLVMVectorTypeKind => AnyTypeEnum::VectorType(VectorType::new(type_)),
LLVMTypeKind::LLVMMetadataTypeKind => panic!("FIXME: Unsupported type: Metadata"),
LLVMTypeKind::LLVMX86_MMXTypeKind => panic!("FIXME: Unsupported type: MMX"),
// LLVMTypeKind::LLVMTokenTypeKind => panic!("FIXME: Unsupported type: Token"), // Different version?
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMTypeKind::LLVMTokenTypeKind => panic!("FIXME: Unsupported type: Token"),
}
}
}
Expand Down Expand Up @@ -89,6 +90,8 @@ impl BasicTypeEnum {
LLVMTypeKind::LLVMLabelTypeKind => unreachable!("Unsupported type: Label"),
LLVMTypeKind::LLVMVoidTypeKind => unreachable!("Unsupported type: VoidType"),
LLVMTypeKind::LLVMFunctionTypeKind => unreachable!("Unsupported type: FunctionType"),
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMTypeKind::LLVMTokenTypeKind => panic!("FIXME: Unsupported type: Token"),
}
}
}
48 changes: 30 additions & 18 deletions src/values/instruction_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ pub enum InstructionOpcode {
BitCast,
Br,
Call,
// Later versions:
// CatchPad,
// CatchRet,
// CatchSwitch,
// CleanupPad,
// CleanupRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
CatchPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
CatchRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
CatchSwitch,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
CleanupPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
CleanupRet,
ExtractElement,
ExtractValue,
FAdd,
Expand Down Expand Up @@ -92,12 +96,16 @@ impl InstructionOpcode {
LLVMOpcode::LLVMBitCast => InstructionOpcode::BitCast,
LLVMOpcode::LLVMBr => InstructionOpcode::Br,
LLVMOpcode::LLVMCall => InstructionOpcode::Call,
// Newer versions:
// LLVMOpcode::LLVMCatchPad => InstructionOpcode::CatchPad,
// LLVMOpcode::LLVMCatchRet => InstructionOpcode::CatchRet,
// LLVMOpcode::LLVMCatchSwitch => InstructionOpcode::CatchSwitch,
// LLVMOpcode::LLVMCleanupPad => InstructionOpcode::CleanupPad,
// LLVMOpcode::LLVMCleanupRet => InstructionOpcode::CleanupRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMOpcode::LLVMCatchPad => InstructionOpcode::CatchPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMOpcode::LLVMCatchRet => InstructionOpcode::CatchRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMOpcode::LLVMCatchSwitch => InstructionOpcode::CatchSwitch,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMOpcode::LLVMCleanupPad => InstructionOpcode::CleanupPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
LLVMOpcode::LLVMCleanupRet => InstructionOpcode::CleanupRet,
LLVMOpcode::LLVMExtractElement => InstructionOpcode::ExtractElement,
LLVMOpcode::LLVMExtractValue => InstructionOpcode::ExtractValue,
LLVMOpcode::LLVMFAdd => InstructionOpcode::FAdd,
Expand Down Expand Up @@ -162,12 +170,16 @@ impl InstructionOpcode {
InstructionOpcode::BitCast => LLVMOpcode::LLVMBitCast,
InstructionOpcode::Br => LLVMOpcode::LLVMBr,
InstructionOpcode::Call => LLVMOpcode::LLVMCall,
// Newer versions:
// InstructionOpcode::CatchPad => LLVMOpcode::LLVMCatchPad,
// InstructionOpcode::CatchRet => LLVMOpcode::LLVMCatchRet,
// InstructionOpcode::CatchSwitch => LLVMOpcode::LLVMCatchSwitch,
// InstructionOpcode::CleanupPad => LLVMOpcode::LLVMCleanupPad,
// InstructionOpcode::CleanupRet => LLVMOpcode::LLVMCleanupRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
InstructionOpcode::CatchPad => LLVMOpcode::LLVMCatchPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
InstructionOpcode::CatchRet => LLVMOpcode::LLVMCatchRet,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
InstructionOpcode::CatchSwitch => LLVMOpcode::LLVMCatchSwitch,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
InstructionOpcode::CleanupPad => LLVMOpcode::LLVMCleanupPad,
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
InstructionOpcode::CleanupRet => LLVMOpcode::LLVMCleanupRet,
InstructionOpcode::ExtractElement => LLVMOpcode::LLVMExtractElement,
InstructionOpcode::ExtractValue => LLVMOpcode::LLVMExtractValue,
InstructionOpcode::FAdd => LLVMOpcode::LLVMFAdd,
Expand Down
2 changes: 2 additions & 0 deletions src/values/metadata_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use std::slice::from_raw_parts;
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 12;
#[cfg(feature = "llvm3-7")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 14;
#[cfg(feature = "llvm3-8")]
pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 18;

#[derive(PartialEq, Eq, Clone, Copy)]
pub struct MetadataValue {
Expand Down
5 changes: 4 additions & 1 deletion tests/test_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,11 @@ fn test_no_builder_double_free2() {
builder.position_at_end(&entry);
builder.build_unreachable();

#[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8"))]
assert_eq!(module.print_to_string(), &*CString::new("; ModuleID = \'my_mod\'\n\ndefine void @my_fn() {\nentry:\n unreachable\n}\n").unwrap());
// llvm 6.0?:
// assert_eq!(module.print_to_string(), &*CString::new("; ModuleID = \'my_mod\'\nsource_filename = \"my_mod\"\n\ndefine void @my_fn() {\nentry:\n unreachable\n}\n").unwrap());

// 2nd Context drops fine
// Builds drops fine
// Builder drops fine
}
8 changes: 4 additions & 4 deletions tests/test_passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ fn test_pass_manager_builder() {

pass_manager_builder.populate_module_pass_manager(&module_pass_manager);

// REVIEW: Seems to return true in 3.7, even though no changes were made.
// In 3.6 it returns false. LLVM bug?
#[cfg(feature = "llvm3-6")]
// TODOC: Seems to return true in 3.7, even though no changes were made.
// In 3.6 and 3.8 it returns false. Seems like an LLVM bug
#[cfg(not(feature = "llvm3-7"))]
assert!(!module_pass_manager.run_on_module(&module));
#[cfg(not(feature = "llvm3-6"))]
#[cfg(feature = "llvm3-7")]
assert!(module_pass_manager.run_on_module(&module));

// TODO: Populate LTO pass manager?
Expand Down
43 changes: 24 additions & 19 deletions tests/test_values.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,25 +400,28 @@ fn test_metadata() {
assert_eq!(MetadataValue::get_kind_id("dereferenceable_or_null"), 13);
}

#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
{
assert_eq!(context.get_kind_id("make.implicit"), 14);
assert_eq!(MetadataValue::get_kind_id("make.implicit"), 14);
assert_eq!(context.get_kind_id("unpredictable"), 15);
assert_eq!(MetadataValue::get_kind_id("unpredictable"), 15);
assert_eq!(context.get_kind_id("invariant.group"), 16);
assert_eq!(MetadataValue::get_kind_id("invariant.group"), 16);
assert_eq!(context.get_kind_id("align"), 17);
assert_eq!(MetadataValue::get_kind_id("align"), 17);
}
// TODO: Predefined, but only newer versions we don't support yet
// assert_eq!(context.get_kind_id("make.implicit"), 14);
// assert_eq!(MetadataValue::get_kind_id("make.implicit"), 14);
// assert_eq!(context.get_kind_id("unpredictable"), 15);
// assert_eq!(MetadataValue::get_kind_id("unpredictable"), 15);
// assert_eq!(context.get_kind_id("invariant.group"), 16);
// assert_eq!(MetadataValue::get_kind_id("invariant.group"), 16);
// assert_eq!(context.get_kind_id("align"), 16);
// assert_eq!(MetadataValue::get_kind_id("align"), 16);
// assert_eq!(context.get_kind_id("llvm.loop"), 17);
// assert_eq!(MetadataValue::get_kind_id("llvm.loop"), 17);
// assert_eq!(context.get_kind_id("type"), 18);
// assert_eq!(MetadataValue::get_kind_id("type"), 18);
// assert_eq!(context.get_kind_id("section_prefix"), 19);
// assert_eq!(MetadataValue::get_kind_id("section_prefix"), 19);
// assert_eq!(context.get_kind_id("absolute_symbol"), 20);
// assert_eq!(MetadataValue::get_kind_id("absolute_symbol"), 20);
// assert_eq!(context.get_kind_id("associated"), 21);
// assert_eq!(MetadataValue::get_kind_id("associated"), 21);
// assert_eq!(context.get_kind_id("llvm.loop"), 18);
// assert_eq!(MetadataValue::get_kind_id("llvm.loop"), 18);
// assert_eq!(context.get_kind_id("type"), 19);
// assert_eq!(MetadataValue::get_kind_id("type"), 19);
// assert_eq!(context.get_kind_id("section_prefix"), 20);
// assert_eq!(MetadataValue::get_kind_id("section_prefix"), 20);
// assert_eq!(context.get_kind_id("absolute_symbol"), 21);
// assert_eq!(MetadataValue::get_kind_id("absolute_symbol"), 21);
// assert_eq!(context.get_kind_id("associated"), 22);
// assert_eq!(MetadataValue::get_kind_id("associated"), 22);

assert_eq!(module.get_global_metadata_size("my_string_md"), 0);
assert_eq!(module.get_global_metadata("my_string_md").len(), 0);
Expand Down Expand Up @@ -686,7 +689,9 @@ fn test_function_value_no_params() {
assert!(fn_value.get_first_param().is_none());
assert!(fn_value.get_last_param().is_none());
assert!(fn_value.get_nth_param(0).is_none());
#[cfg(not(feature = "llvm3-6"))]
// REVIEW: get_personality_function causes segfault in 3.8 Probably LLVM bug
// if so, should document
#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-8")))]
assert!(fn_value.get_personality_function().is_none());
assert!(!fn_value.is_null());
assert!(!fn_value.is_undef());
Expand Down

0 comments on commit 782f217

Please sign in to comment.