Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
feds01 committed Dec 20, 2024
2 parents b64c336 + 8bd9f08 commit 7f861b5
Show file tree
Hide file tree
Showing 29 changed files with 1,971 additions and 124 deletions.
20 changes: 14 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ on: [push, pull_request]

env:
CARGO_TERM_COLOR: always
DOC_LLVM_FEATURE: llvm17-0
DOC_LLVM_VERSION: "17.0"
DOC_LLVM_FEATURE: llvm18-0
DOC_LLVM_VERSION: "18.1"
DOC_PATH: target/doc

jobs:
Expand All @@ -29,6 +29,7 @@ jobs:
- ["5.0", "5-0"]
- ["6.0", "6-0"]
- ["7.0", "7-0"]
- ["7.1", "7-0"]
- ["8.0", "8-0"]
- ["9.0", "9-0"]
- ["10.0", "10-0"]
Expand All @@ -39,18 +40,25 @@ jobs:
- ["15.0", "15-0"]
- ["16.0", "16-0"]
- ["17.0", "17-0"]
- ["18.1", "18-0"]
include:
- os: ubuntu-20.04
# only use ubuntu-22.04 for llvm 16 and higher
# only use ubuntu-22.04 for llvm 16 and llvm 17
- os: ubuntu-22.04
llvm-version: ["16.0", "16-0"]
- os: ubuntu-22.04
llvm-version: ["17.0", "17-0"]
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Install LLVM and Clang
- name: Install LLVM and Clang (LLVM >= 7.1)
uses: KyleMayes/install-llvm-action@v2
if: ${{ matrix.llvm-version[0] > 7 }}
with:
version: ${{ matrix.llvm-version[0] }}
- name: Install LLVM and Clang (LLVM <= 7)
uses: KyleMayes/install-llvm-action@v1
if: ${{ matrix.llvm-version[0] <= 7 }}
with:
version: ${{ matrix.llvm-version[0] }}
- name: llvm-config
Expand All @@ -65,12 +73,12 @@ jobs:
run: cargo build --example kaleidoscope --features llvm${{ matrix.llvm-version[1] }} --verbose
doc:
name: Documentation
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
needs: [typos, tests]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
- uses: KyleMayes/install-llvm-action@v1
- uses: KyleMayes/install-llvm-action@v2
with:
version: ${{ env.DOC_LLVM_VERSION }}
- name: Install Rust Nightly
Expand Down
23 changes: 0 additions & 23 deletions CHANGELOG.md

This file was deleted.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "inkwell"
version = "0.4.0"
version = "0.5.0"
authors = ["Daniel Kolsoi <[email protected]>"]
description = "Inkwell aims to help you pen your own programming languages by safely wrapping llvm-sys."
documentation = "https://thedan64.github.io/inkwell/"
Expand Down Expand Up @@ -135,7 +135,7 @@ experimental = ["static-alloc"]
nightly = ["inkwell_internals/nightly"]

[dependencies]
inkwell_internals = { path = "./internal_macros", version = "0.9.0" }
inkwell_internals = { path = "./internal_macros", version = "0.10.0" }

llvm-sys-40 = { package = "llvm-sys", version = "40.4", optional = true }
llvm-sys-50 = { package = "llvm-sys", version = "50.4", optional = true }
Expand All @@ -150,8 +150,8 @@ llvm-sys-130 = { package = "llvm-sys", version = "130.0.4", optional = true }
llvm-sys-140 = { package = "llvm-sys", version = "140.0.2", optional = true }
llvm-sys-150 = { package = "llvm-sys", version = "150.0.3", optional = true }
llvm-sys-160 = { package = "llvm-sys", version = "160.1.0", optional = true }
llvm-sys-170 = { package = "llvm-sys", version = "170.0.1", optional = true }
llvm-sys-180 = { package = "llvm-sys", version = "180.0.0", optional = true }
llvm-sys-170 = { package = "llvm-sys", version = "170.2.0", optional = true }
llvm-sys-180 = { package = "llvm-sys", version = "181.2.0", optional = true }

either = "1.5"
libc = "0.2"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ You'll need to point your Cargo.toml to use a single LLVM version feature flag c

```toml
[dependencies]
inkwell = { version = "0.4.0", features = ["llvm18-0"] }
inkwell = { version = "0.5.0", features = ["llvm18-0"] }
```

Supported versions:
Expand Down
2 changes: 1 addition & 1 deletion internal_macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ license = "Apache-2.0"
name = "inkwell_internals"
readme = "README.md"
repository = "https://github.com/TheDan64/inkwell"
version = "0.9.0"
version = "0.10.0"

[dependencies]
proc-macro2 = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion src/basic_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ impl<'ctx> BasicBlock<'ctx> {
{
use llvm_sys::core::LLVMSetValueName2;

unsafe { LLVMSetValueName2(LLVMBasicBlockAsValue(self.basic_block), c_string.as_ptr(), name.len()) };
unsafe { LLVMSetValueName2(LLVMBasicBlockAsValue(self.basic_block), c_string.as_ptr(), c_string.to_bytes().len()) };
}
}

Expand Down
158 changes: 144 additions & 14 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! A `Builder` enables you to build instructions.
#[llvm_versions(18..)]
use llvm_sys::core::LLVMBuildCallWithOperandBundles;
use llvm_sys::core::{
LLVMAddCase, LLVMAddClause, LLVMAddDestination, LLVMBuildAShr, LLVMBuildAdd, LLVMBuildAddrSpaceCast,
LLVMBuildAggregateRet, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildArrayMalloc,
LLVMBuildAtomicCmpXchg, LLVMBuildAtomicRMW, LLVMBuildBitCast, LLVMBuildBr, LLVMBuildCast, LLVMBuildCondBr,
LLVMBuildAtomicCmpXchg, LLVMBuildAtomicRMW, LLVMBuildBinOp, LLVMBuildBitCast, LLVMBuildBr, LLVMBuildCast, LLVMBuildCondBr,
LLVMBuildExactSDiv, LLVMBuildExtractElement, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFCmp, LLVMBuildFDiv,
LLVMBuildFMul, LLVMBuildFNeg, LLVMBuildFPCast, LLVMBuildFPExt, LLVMBuildFPToSI, LLVMBuildFPToUI, LLVMBuildFPTrunc,
LLVMBuildFRem, LLVMBuildFSub, LLVMBuildFence, LLVMBuildFree, LLVMBuildGlobalString, LLVMBuildGlobalStringPtr,
Expand Down Expand Up @@ -42,12 +44,14 @@ use crate::context::AsContextRef;
use crate::debug_info::DILocation;
use crate::support::to_c_str;
use crate::types::{AsTypeRef, BasicType, FloatMathType, FunctionType, IntMathType, PointerMathType, PointerType};
#[llvm_versions(18..)]
use crate::values::operand_bundle::OperandBundle;
#[llvm_versions(..=14)]
use crate::values::CallableValue;
use crate::values::{
AggregateValue, AggregateValueEnum, AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue,
FloatMathValue, FunctionValue, GlobalValue, InstructionOpcode, InstructionValue, IntMathValue, IntValue, PhiValue,
PointerMathValue, PointerValue, StructValue, VectorValue,
PointerMathValue, PointerValue, StructValue, VectorBaseValue,
};

use crate::{AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate};
Expand Down Expand Up @@ -308,6 +312,57 @@ impl<'ctx> Builder<'ctx> {
self.build_call_help(function.get_type(), function.as_value_ref(), args, name)
}

/// Build a function call instruction, with attached operand bundles.
///
/// # Example
///
/// ```
/// use inkwell::context::Context;
/// use inkwell::values::OperandBundle;
///
/// let context = Context::create();
/// let module = context.create_module("call_with_op_bundles");
/// let builder = context.create_builder();
/// let i32_type = context.i32_type();
///
/// // declare i32 @func(i32)
/// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
/// let fn_value = module.add_function("func", fn_type, None);
///
/// let basic_block = context.append_basic_block(fn_value, "entry");
/// builder.position_at_end(basic_block);
///
/// // %func_ret = call i32 @func(i32 0) [ "tag"(i32 0) ]
/// let ret_val = builder.build_direct_call_with_operand_bundles(
/// fn_value,
/// &[i32_type.const_zero().into()],
/// &[OperandBundle::create("tag", &[i32_type.const_zero().into()])],
/// "func_ret"
/// )
/// .unwrap()
/// .try_as_basic_value()
/// .unwrap_left();
/// builder.build_return(Some(&ret_val)).unwrap();
///
/// # module.verify().unwrap();
/// ```
#[llvm_versions(18..)]
pub fn build_direct_call_with_operand_bundles(
&self,
function: FunctionValue<'ctx>,
args: &[BasicMetadataValueEnum<'ctx>],
operand_bundles: &[OperandBundle<'ctx>],
name: &str,
) -> Result<CallSiteValue<'ctx>, BuilderError> {
self.build_call_with_operand_bundles_help(
function.get_type(),
function.as_value_ref(),
args,
operand_bundles,
name,
)
}

/// Call a function pointer. Because a pointer does not carry a type, the type of the function
/// must be specified explicitly.
///
Expand Down Expand Up @@ -352,6 +407,28 @@ impl<'ctx> Builder<'ctx> {
self.build_call_help(function_type, function_pointer.as_value_ref(), args, name)
}

/// Build a call instruction to a function pointer, with attached operand bundles.
///
/// See [Builder::build_direct_call_with_operand_bundles] for a usage example
/// with operand bundles.
#[llvm_versions(18..)]
pub fn build_indirect_call_with_operand_bundles(
&self,
function_type: FunctionType<'ctx>,
function_pointer: PointerValue<'ctx>,
args: &[BasicMetadataValueEnum<'ctx>],
operand_bundles: &[OperandBundle<'ctx>],
name: &str,
) -> Result<CallSiteValue<'ctx>, BuilderError> {
self.build_call_with_operand_bundles_help(
function_type,
function_pointer.as_value_ref(),
args,
operand_bundles,
name,
)
}

#[llvm_versions(15..)]
fn build_call_help(
&self,
Expand Down Expand Up @@ -388,6 +465,49 @@ impl<'ctx> Builder<'ctx> {
unsafe { Ok(CallSiteValue::new(value)) }
}

#[llvm_versions(18..)]
fn build_call_with_operand_bundles_help(
&self,
function_type: FunctionType<'ctx>,
fn_val_ref: LLVMValueRef,
args: &[BasicMetadataValueEnum<'ctx>],
operand_bundles: &[OperandBundle<'ctx>],
name: &str,
) -> Result<CallSiteValue<'ctx>, BuilderError> {
use llvm_sys::prelude::LLVMOperandBundleRef;

if self.positioned.get() != PositionState::Set {
return Err(BuilderError::UnsetPosition);
}
// LLVM gets upset when void return calls are named because they don't return anything
let name = match function_type.get_return_type() {
None => "",
Some(_) => name,
};

let fn_ty_ref = function_type.as_type_ref();

let c_string = to_c_str(name);
let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
let mut operand_bundles: Vec<LLVMOperandBundleRef> =
operand_bundles.iter().map(|val| val.as_mut_ptr()).collect();

let value = unsafe {
LLVMBuildCallWithOperandBundles(
self.builder,
fn_ty_ref,
fn_val_ref,
args.as_mut_ptr(),
args.len() as u32,
operand_bundles.as_mut_ptr(),
operand_bundles.len() as u32,
c_string.as_ptr(),
)
};

unsafe { Ok(CallSiteValue::new(value)) }
}

/// An invoke is similar to a normal function call, but used to
/// call functions that may throw an exception, and then respond to the exception.
///
Expand Down Expand Up @@ -2502,6 +2622,16 @@ impl<'ctx> Builder<'ctx> {
unsafe { Ok(T::new(value)) }
}

pub fn build_binop<T: BasicValue<'ctx>>(&self, op: InstructionOpcode, lhs: T, rhs: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError> {
if self.positioned.get() != PositionState::Set {
return Err(BuilderError::UnsetPosition);
}
let c_string = to_c_str(name);
let value = unsafe { LLVMBuildBinOp(self.builder, op.into(), lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };

unsafe { Ok(BasicValueEnum::new(value)) }
}

pub fn build_cast<T: BasicType<'ctx>, V: BasicValue<'ctx>>(
&self,
op: InstructionOpcode,
Expand Down Expand Up @@ -2934,9 +3064,9 @@ impl<'ctx> Builder<'ctx> {
///
/// builder.build_return(Some(&extracted)).unwrap();
/// ```
pub fn build_extract_element(
pub fn build_extract_element<V: VectorBaseValue<'ctx>>(
&self,
vector: VectorValue<'ctx>,
vector: V,
index: IntValue<'ctx>,
name: &str,
) -> Result<BasicValueEnum<'ctx>, BuilderError> {
Expand Down Expand Up @@ -2982,13 +3112,13 @@ impl<'ctx> Builder<'ctx> {
/// builder.build_insert_element(vector_param, i32_seven, i32_zero, "insert").unwrap();
/// builder.build_return(None).unwrap();
/// ```
pub fn build_insert_element<V: BasicValue<'ctx>>(
pub fn build_insert_element<V: BasicValue<'ctx>, W: VectorBaseValue<'ctx>>(
&self,
vector: VectorValue<'ctx>,
vector: W,
element: V,
index: IntValue<'ctx>,
name: &str,
) -> Result<VectorValue<'ctx>, BuilderError> {
) -> Result<W, BuilderError> {
if self.positioned.get() != PositionState::Set {
return Err(BuilderError::UnsetPosition);
}
Expand All @@ -3004,7 +3134,7 @@ impl<'ctx> Builder<'ctx> {
)
};

unsafe { Ok(VectorValue::new(value)) }
unsafe { Ok(W::new(value)) }
}

pub fn build_unreachable(&self) -> Result<InstructionValue<'ctx>, BuilderError> {
Expand Down Expand Up @@ -3199,13 +3329,13 @@ impl<'ctx> Builder<'ctx> {
}

// REVIEW: Do we need to constrain types here? subtypes?
pub fn build_shuffle_vector(
pub fn build_shuffle_vector<V: VectorBaseValue<'ctx>>(
&self,
left: VectorValue<'ctx>,
right: VectorValue<'ctx>,
mask: VectorValue<'ctx>,
left: V,
right: V,
mask: V,
name: &str,
) -> Result<VectorValue<'ctx>, BuilderError> {
) -> Result<V, BuilderError> {
if self.positioned.get() != PositionState::Set {
return Err(BuilderError::UnsetPosition);
}
Expand All @@ -3220,7 +3350,7 @@ impl<'ctx> Builder<'ctx> {
)
};

unsafe { Ok(VectorValue::new(value)) }
unsafe { Ok(V::new(value)) }
}

// REVIEW: Is return type correct?
Expand Down
Loading

0 comments on commit 7f861b5

Please sign in to comment.