Skip to content

Commit

Permalink
Merge pull request rust-lang#31 from TheDan64/versioned_travis
Browse files Browse the repository at this point in the history
Support for multiple LLVM versions, starting with 3.6
  • Loading branch information
TheDan64 authored Feb 24, 2018
2 parents 81ce438 + 2a18304 commit d600abf
Show file tree
Hide file tree
Showing 20 changed files with 197 additions and 74 deletions.
70 changes: 48 additions & 22 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,63 @@
language: rust

sudo: false
cache:
- apt
- cargo

rust:
- stable
- beta
- nightly
include_base: &BASE
addons:
apt:
sources: &BASE_SOURCES
- ubuntu-toolchain-r-test
packages: &BASE_PACKAGES
- libelf-dev
- lib32z1-dev
- libedit-dev
- libdw-dev
- binutils-dev
- libiberty-dev
before_install:
- export LLVM_VERSION_DASH=${LLVM_VERSION/./-}
- export LLVM_VERSION_SHORT=${LLVM_VERSION/./}
- export PATH=/usr/lib/llvm-${LLVM_VERSION}/bin/:$HOME/.local/bin:$PATH
- export LLVM_PATH=/usr/share/llvm-${LLVM_VERSION}/cmake/
- sed -i -e 's/llvm-sys = ".*"/llvm-sys = "'${LLVM_VERSION_SHORT}'"/' Cargo.toml
script:
- cargo test --no-default-features --features "llvm${LLVM_VERSION_DASH}" --verbose

matrix:
allow_failures:
- rust: nightly
fast_finish: true
include:
- env:
- LLVM_VERSION="3.6"
<<: *BASE
addons:
apt:
sources:
- *BASE_SOURCES
- llvm-toolchain-precise-3.6
packages:
- *BASE_PACKAGES
- llvm-3.6-dev

- env:
- LLVM_VERSION="3.7"
<<: *BASE
addons:
apt:
sources:
- *BASE_SOURCES
- llvm-toolchain-precise-3.7
packages:
- *BASE_PACKAGES
- llvm-3.7-dev

env:
global:
- RUSTFLAGS="-C link-dead-code"

addons:
apt:
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
packages:
- llvm-3.7-dev
- libelf-dev
- lib32z1-dev
- libedit-dev
- libdw-dev
- binutils-dev
- libiberty-dev

before_install:
- export PATH=/usr/lib/llvm-3.7/bin/:$HOME/.local/bin:$PATH
- RUSTFLAGS="-C link-dead-code -C target-cpu=native"

after_success: |
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
Expand Down
11 changes: 8 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ keywords = ["llvm", "safe", "wrapper"]
license = "Apache-2.0"
categories = ["development-tools::ffi"]

[features]
default = []
llvm3-6 = []
llvm3-7 = []

[dependencies]
either = "1.1.0"
enum-methods = "0.0.7"
either = "1.4.0"
enum-methods = "0.0.8"
libc = "*"
llvm-sys = "37.0.5" # TODO: Configure based on feature toggle. GH#1
llvm-sys = "37"

[[example]]
name = "kaleidoscope"
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,25 @@ 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.7 (3.6 and 3.8+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1))
* LLVM 3.6 or 3.7 (3.8+ support is planned: [#1](https://github.com/TheDan64/inkwell/issues/1))

## Usage

You'll need to point your Cargo.toml to the master branch of Inkwell like so:
You'll need to point your Cargo.toml to a branch and use a feature flag corresponding to a supported LLVM version:

```toml
[dependencies]
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "master" }
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm3-7", features = ["llvm3-7"] }
```

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

| GitHub Branch | Feature Flag |
| :-----------: | :----------: |
| llvm3-6 | llvm3-6 |
| llvm3-7 | llvm3-7 |

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

```rust
extern crate inkwell;
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ use llvm_sys::support::LLVMLoadLibraryPermanently;

use std::ffi::CString;

#[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7")))]
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
Expand Down
9 changes: 7 additions & 2 deletions src/passes.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
use llvm_sys::core::{LLVMDisposePassManager, LLVMInitializeFunctionPassManager, LLVMFinalizeFunctionPassManager, LLVMRunFunctionPassManager, LLVMRunPassManager, LLVMCreatePassManager, LLVMCreateFunctionPassManagerForModule, LLVMGetGlobalPassRegistry};
use llvm_sys::initialization::{LLVMInitializeCore, LLVMInitializeTransformUtils, LLVMInitializeScalarOpts, LLVMInitializeObjCARCOpts, LLVMInitializeVectorization, LLVMInitializeInstCombine, LLVMInitializeIPO, LLVMInitializeInstrumentation, LLVMInitializeAnalysis, LLVMInitializeIPA, LLVMInitializeCodeGen, LLVMInitializeTarget};
use llvm_sys::prelude::{LLVMPassManagerRef, LLVMPassRegistryRef};
#[cfg(not(feature = "llvm3-6"))]
use llvm_sys::target::LLVMAddTargetData;
use llvm_sys::transforms::ipo::{LLVMAddArgumentPromotionPass, LLVMAddConstantMergePass, LLVMAddDeadArgEliminationPass, LLVMAddFunctionAttrsPass, LLVMAddFunctionInliningPass, LLVMAddAlwaysInlinerPass, LLVMAddGlobalDCEPass, LLVMAddGlobalOptimizerPass, LLVMAddIPConstantPropagationPass, LLVMAddIPSCCPPass, LLVMAddInternalizePass, LLVMAddStripDeadPrototypesPass, LLVMAddPruneEHPass, LLVMAddStripSymbolsPass};
use llvm_sys::transforms::pass_manager_builder::{LLVMPassManagerBuilderRef, LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderSetDisableUnitAtATime, LLVMPassManagerBuilderSetDisableUnrollLoops, LLVMPassManagerBuilderSetDisableSimplifyLibCalls, LLVMPassManagerBuilderUseInlinerWithThreshold, LLVMPassManagerBuilderPopulateFunctionPassManager, LLVMPassManagerBuilderPopulateModulePassManager, LLVMPassManagerBuilderPopulateLTOPassManager};
use llvm_sys::transforms::scalar::{LLVMAddAggressiveDCEPass, LLVMAddMemCpyOptPass, LLVMAddBitTrackingDCEPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddCFGSimplificationPass, LLVMAddDeadStoreEliminationPass, LLVMAddScalarizerPass, LLVMAddMergedLoadStoreMotionPass, LLVMAddGVNPass, LLVMAddIndVarSimplifyPass, LLVMAddInstructionCombiningPass, LLVMAddJumpThreadingPass, LLVMAddLICMPass, LLVMAddLoopDeletionPass, LLVMAddLoopIdiomPass, LLVMAddLoopRotatePass, LLVMAddLoopRerollPass, LLVMAddLoopUnrollPass, LLVMAddLoopUnswitchPass, LLVMAddPartiallyInlineLibCallsPass, LLVMAddLowerSwitchPass, LLVMAddPromoteMemoryToRegisterPass, LLVMAddSCCPPass, LLVMAddScalarReplAggregatesPass, LLVMAddScalarReplAggregatesPassSSA, LLVMAddScalarReplAggregatesPassWithThreshold, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddConstantPropagationPass, LLVMAddDemoteMemoryToRegisterPass, LLVMAddVerifierPass, LLVMAddCorrelatedValuePropagationPass, LLVMAddEarlyCSEPass, LLVMAddLowerExpectIntrinsicPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddScopedNoAliasAAPass, LLVMAddBasicAliasAnalysisPass, LLVMAddReassociatePass};
use llvm_sys::transforms::scalar::{LLVMAddAggressiveDCEPass, LLVMAddMemCpyOptPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddCFGSimplificationPass, LLVMAddDeadStoreEliminationPass, LLVMAddScalarizerPass, LLVMAddMergedLoadStoreMotionPass, LLVMAddGVNPass, LLVMAddIndVarSimplifyPass, LLVMAddInstructionCombiningPass, LLVMAddJumpThreadingPass, LLVMAddLICMPass, LLVMAddLoopDeletionPass, LLVMAddLoopIdiomPass, LLVMAddLoopRotatePass, LLVMAddLoopRerollPass, LLVMAddLoopUnrollPass, LLVMAddLoopUnswitchPass, LLVMAddPartiallyInlineLibCallsPass, LLVMAddLowerSwitchPass, LLVMAddPromoteMemoryToRegisterPass, LLVMAddSCCPPass, LLVMAddScalarReplAggregatesPass, LLVMAddScalarReplAggregatesPassSSA, LLVMAddScalarReplAggregatesPassWithThreshold, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddConstantPropagationPass, LLVMAddDemoteMemoryToRegisterPass, LLVMAddVerifierPass, LLVMAddCorrelatedValuePropagationPass, LLVMAddEarlyCSEPass, LLVMAddLowerExpectIntrinsicPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddScopedNoAliasAAPass, LLVMAddBasicAliasAnalysisPass, LLVMAddReassociatePass};
#[cfg(not(feature = "llvm3-6"))]
use llvm_sys::transforms::scalar::LLVMAddBitTrackingDCEPass;
use llvm_sys::transforms::vectorize::{LLVMAddBBVectorizePass, LLVMAddLoopVectorizePass, LLVMAddSLPVectorizePass};

use OptimizationLevel;
use module::Module;
#[cfg(not(feature = "llvm3-6"))]
use targets::TargetData;
use values::{AsValueRef, FunctionValue};

Expand Down Expand Up @@ -159,6 +163,7 @@ impl PassManager {
}
}

#[cfg(not(feature = "llvm3-6"))]
pub fn add_target_data(&self, target_data: &TargetData) {
unsafe {
LLVMAddTargetData(target_data.target_data, self.pass_manager)
Expand Down Expand Up @@ -274,7 +279,7 @@ impl PassManager {
}
}

// TODO: 3.7+ only
#[cfg(not(feature = "llvm3-6"))]
pub fn add_bit_tracking_dce_pass(&self) {
unsafe {
LLVMAddBitTrackingDCEPass(self.pass_manager)
Expand Down
34 changes: 33 additions & 1 deletion src/targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,36 @@ impl Target {
}
}

// TODOC: Called AMDGPU in 3.7+
#[cfg(feature = "llvm3-6")]
pub fn initialize_r600(config: &InitializationConfig) {
use llvm_sys::target::{LLVMInitializeR600Target, LLVMInitializeR600TargetInfo, LLVMInitializeR600TargetMC, LLVMInitializeR600AsmPrinter, LLVMInitializeR600AsmParser};

unsafe {
if config.base {
LLVMInitializeR600Target()
}

if config.info {
LLVMInitializeR600TargetInfo()
}

if config.asm_printer {
LLVMInitializeR600AsmPrinter()
}

if config.asm_parser {
LLVMInitializeR600AsmParser()
}

if config.machine_code {
LLVMInitializeR600TargetMC()
}
}
}

// TODOC: Called R600 in 3.6
#[cfg(not(feature = "llvm3-6"))]
pub fn initialize_amd_gpu(config: &InitializationConfig) {
use llvm_sys::target::{LLVMInitializeAMDGPUTarget, LLVMInitializeAMDGPUTargetInfo, LLVMInitializeAMDGPUTargetMC, LLVMInitializeAMDGPUAsmPrinter, LLVMInitializeAMDGPUAsmParser};

Expand Down Expand Up @@ -314,6 +344,7 @@ impl Target {
}
}

#[cfg(not(feature = "llvm3-6"))]
pub fn initialize_cpp_backend(config: &InitializationConfig) {
use llvm_sys::target::{LLVMInitializeCppBackendTarget, LLVMInitializeCppBackendTargetInfo, LLVMInitializeCppBackendTargetMC};

Expand Down Expand Up @@ -441,6 +472,7 @@ impl Target {
}

// TODOC: Disassembler only supported in LLVM 4.0+
#[cfg(not(feature = "llvm3-6"))]
pub fn initialize_bpf(config: &InitializationConfig) {
use llvm_sys::target::{LLVMInitializeBPFTarget, LLVMInitializeBPFTargetInfo, LLVMInitializeBPFTargetMC, LLVMInitializeBPFAsmPrinter};

Expand Down Expand Up @@ -860,7 +892,7 @@ impl TargetData {
TargetData::new(target_data)
}

// REVIEW: Maybe this should be pass_manager.add_target_data()?
// REVIEW: Maybe this should be pass_manager.add_target_data(&target_data)?
pub fn add_target_data(&self, pass_manager: &PassManager) {
unsafe {
LLVMAddTargetData(self.target_data, pass_manager.pass_manager)
Expand Down
1 change: 1 addition & 0 deletions src/types/array_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ impl ArrayType {
self.array_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.array_type.print_to_stderr()
}
Expand Down
1 change: 1 addition & 0 deletions src/types/float_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ impl FloatType {
self.float_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.float_type.print_to_stderr()
}
Expand Down
1 change: 1 addition & 0 deletions src/types/fn_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl FunctionType {
self.fn_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.fn_type.print_to_stderr()
}
Expand Down
1 change: 1 addition & 0 deletions src/types/int_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ impl IntType {
self.int_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.int_type.print_to_stderr()
}
Expand Down
5 changes: 4 additions & 1 deletion src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ pub use types::vec_type::VectorType;
pub use types::void_type::VoidType;
pub(crate) use types::traits::AsTypeRef;

use llvm_sys::core::{LLVMAlignOf, LLVMGetTypeContext, LLVMFunctionType, LLVMArrayType, LLVMDumpType, LLVMGetTypeKind, LLVMGetUndef, LLVMPointerType, LLVMPrintTypeToString, LLVMTypeIsSized, LLVMSizeOf, LLVMVectorType, LLVMConstPointerNull};
#[cfg(not(feature = "llvm3-6"))]
use llvm_sys::core::LLVMDumpType;
use llvm_sys::core::{LLVMAlignOf, LLVMGetTypeContext, LLVMFunctionType, LLVMArrayType, LLVMGetTypeKind, LLVMGetUndef, LLVMPointerType, LLVMPrintTypeToString, LLVMTypeIsSized, LLVMSizeOf, LLVMVectorType, LLVMConstPointerNull};
use llvm_sys::LLVMTypeKind;
use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef};

Expand Down Expand Up @@ -50,6 +52,7 @@ impl Type {
}
}

#[cfg(not(feature = "llvm3-6"))]
fn print_to_stderr(&self) {
unsafe {
LLVMDumpType(self.type_);
Expand Down
1 change: 1 addition & 0 deletions src/types/ptr_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl PointerType {
self.ptr_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.ptr_type.print_to_stderr()
}
Expand Down
13 changes: 8 additions & 5 deletions src/types/struct_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use llvm_sys::core::{LLVMStructGetTypeAtIndex, LLVMConstNamedStruct, LLVMConstStruct, LLVMConstNull, LLVMStructType, LLVMCountStructElementTypes, LLVMGetStructElementTypes, LLVMGetStructName, LLVMIsPackedStruct, LLVMIsOpaqueStruct, LLVMStructSetBody};
use llvm_sys::core::{LLVMConstNamedStruct, LLVMConstStruct, LLVMConstNull, LLVMStructType, LLVMCountStructElementTypes, LLVMGetStructElementTypes, LLVMGetStructName, LLVMIsPackedStruct, LLVMIsOpaqueStruct, LLVMStructSetBody};
#[cfg(not(feature = "llvm3-6"))]
use llvm_sys::core::LLVMStructGetTypeAtIndex;
use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef};

use std::ffi::CStr;
Expand All @@ -25,7 +27,7 @@ impl StructType {
}

// TODO: Would be great to be able to smartly be able to do this by field name
// TODO: LLVM 3.7+ only
#[cfg(not(feature = "llvm3-6"))]
pub fn get_field_type_at_index(&self, index: u32) -> Option<BasicTypeEnum> {
// LLVM doesn't seem to just return null if opaque.
// TODO: One day, with SubTypes (& maybe specialization?) we could just
Expand All @@ -40,7 +42,7 @@ impl StructType {
}

let type_ = unsafe {
LLVMStructGetTypeAtIndex(self.struct_type.type_, index)
LLVMStructGetTypeAtIndex(self.as_type_ref(), index)
};

Some(BasicTypeEnum::new(type_))
Expand Down Expand Up @@ -130,15 +132,15 @@ impl StructType {

pub fn is_packed(&self) -> bool {
unsafe {
LLVMIsPackedStruct(self.struct_type.type_) == 1
LLVMIsPackedStruct(self.as_type_ref()) == 1
}
}

// TODO: Worth documenting that a sturct is opaque when types are not
// yet assigned (empty array to struct_type)
pub fn is_opaque(&self) -> bool {
unsafe {
LLVMIsOpaqueStruct(self.struct_type.type_) == 1
LLVMIsOpaqueStruct(self.as_type_ref()) == 1
}
}

Expand Down Expand Up @@ -183,6 +185,7 @@ impl StructType {
self.struct_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.struct_type.print_to_stderr()
}
Expand Down
1 change: 1 addition & 0 deletions src/types/vec_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl VectorType {
self.vec_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.vec_type.print_to_stderr()
}
Expand Down
1 change: 1 addition & 0 deletions src/types/void_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ impl VoidType {
self.void_type.print_to_string()
}

#[cfg(not(feature = "llvm3-6"))]
pub fn print_to_stderr(&self) {
self.void_type.print_to_stderr()
}
Expand Down
6 changes: 5 additions & 1 deletion src/values/fn_value.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyFunction, LLVMViewFunctionCFG, LLVMViewFunctionCFGOnly};
use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetPersonalityFn, LLVMSetPersonalityFn, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC};
use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC};
#[cfg(not(feature = "llvm3-6"))]
use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn};
use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef};

use std::ffi::{CStr, CString};
Expand Down Expand Up @@ -259,6 +261,7 @@ impl FunctionValue {
// }
// }

#[cfg(not(feature = "llvm3-6"))]
pub fn get_personality_function(&self) -> Option<FunctionValue> {
let value = unsafe {
LLVMGetPersonalityFn(self.as_value_ref())
Expand All @@ -267,6 +270,7 @@ impl FunctionValue {
FunctionValue::new(value)
}

#[cfg(not(feature = "llvm3-6"))]
pub fn set_personality_function(&self, personality_fn: &FunctionValue) {
unsafe {
LLVMSetPersonalityFn(self.as_value_ref(), personality_fn.as_value_ref())
Expand Down
Loading

0 comments on commit d600abf

Please sign in to comment.