Skip to content

Commit

Permalink
Merge pull request rust-lang#247 from wasmerio/add-metadata-support
Browse files Browse the repository at this point in the history
Add metadata support
  • Loading branch information
TheDan64 committed Oct 21, 2021
2 parents 2d715ed + daf6ce2 commit bec0222
Show file tree
Hide file tree
Showing 20 changed files with 413 additions and 167 deletions.
22 changes: 11 additions & 11 deletions .travis.yml
Expand Up @@ -42,7 +42,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-3.6-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="3.7"
Expand All @@ -55,7 +55,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-3.7-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="3.8"
Expand All @@ -68,7 +68,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-3.8-dev
rust: 1.45.2
rust: 1.52
dist: trusty
# 3.9 seems to have a linking issue :/
# - env:
Expand Down Expand Up @@ -96,7 +96,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-4.0-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="5.0"
Expand All @@ -109,7 +109,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-5.0-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="6.0"
Expand All @@ -122,7 +122,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-6.0-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="7.0"
Expand All @@ -135,7 +135,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-7-dev
rust: 1.45.2
rust: 1.52
dist: trusty
- env:
- LLVM_VERSION="8.0"
Expand Down Expand Up @@ -163,7 +163,7 @@ matrix:
packages:
- *BASE_PACKAGES
- llvm-9-dev
rust: 1.45.2
rust: 1.52
dist: bionic
- env:
- LLVM_VERSION="10.0"
Expand All @@ -179,7 +179,7 @@ matrix:
- *BASE_PACKAGES
- llvm-10-dev
- libclang-common-10-dev
rust: 1.45.2
rust: 1.52
dist: bionic
- env:
- LLVM_VERSION="11.0"
Expand All @@ -195,7 +195,7 @@ matrix:
- *BASE_PACKAGES
- llvm-11-dev
- libclang-common-11-dev
rust: 1.45.2
rust: 1.52
dist: bionic
- env:
- LLVM_VERSION="12.0"
Expand All @@ -211,7 +211,7 @@ matrix:
- *BASE_PACKAGES
- llvm-12-dev
- libclang-common-12-dev
rust: 1.45.2
rust: 1.52
dist: bionic
- deploy: # Documentation build; Only latest supported LLVM version for now
provider: pages
Expand Down
8 changes: 4 additions & 4 deletions examples/kaleidoscope/main.rs
Expand Up @@ -25,8 +25,8 @@ use self::inkwell::builder::Builder;
use self::inkwell::context::Context;
use self::inkwell::module::Module;
use self::inkwell::passes::PassManager;
use self::inkwell::types::BasicTypeEnum;
use self::inkwell::values::{BasicValue, BasicValueEnum, FloatValue, FunctionValue, PointerValue};
use self::inkwell::types::BasicMetadataTypeEnum;
use self::inkwell::values::{BasicValue, BasicMetadataValueEnum, FloatValue, FunctionValue, PointerValue};
use self::inkwell::{OptimizationLevel, FloatPredicate};

use crate::Token::*;
Expand Down Expand Up @@ -982,7 +982,7 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
compiled_args.push(self.compile_expr(arg)?);
}

let argsv: Vec<BasicValueEnum> = compiled_args.iter().by_ref().map(|&val| val.into()).collect();
let argsv: Vec<BasicMetadataValueEnum> = compiled_args.iter().by_ref().map(|&val| val.into()).collect();

match self.builder.build_call(fun, argsv.as_slice(), "tmp").try_as_basic_value().left() {
Some(value) => Ok(value.into_float_value()),
Expand Down Expand Up @@ -1093,7 +1093,7 @@ impl<'a, 'ctx> Compiler<'a, 'ctx> {
let args_types = std::iter::repeat(ret_type)
.take(proto.args.len())
.map(|f| f.into())
.collect::<Vec<BasicTypeEnum>>();
.collect::<Vec<BasicMetadataTypeEnum>>();
let args_types = args_types.as_slice();

let fn_type = self.context.f64_type().fn_type(args_types, false);
Expand Down
7 changes: 4 additions & 3 deletions src/builder.rs
Expand Up @@ -10,7 +10,7 @@ use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef};
use crate::{AtomicOrdering, AtomicRMWBinOp, IntPredicate, FloatPredicate};
use crate::basic_block::BasicBlock;
use crate::support::to_c_str;
use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, FunctionValue, BasicValue, BasicValueEnum, PhiValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue};
use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, FunctionValue, BasicValue, BasicValueEnum, PhiValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue, BasicMetadataValueEnum};
#[llvm_versions(7.0..=latest)]
use crate::debug_info::DILocation;
#[llvm_versions(3.9..=latest)]
Expand Down Expand Up @@ -126,17 +126,18 @@ impl<'ctx> Builder<'ctx> {
/// let fn_value = module.add_function("ret", fn_type, None);
/// let entry = context.append_basic_block(fn_value, "entry");
/// let i32_arg = fn_value.get_first_param().unwrap();
/// let md_string = context.metadata_string("a metadata");
///
/// builder.position_at_end(entry);
///
/// let ret_val = builder.build_call(fn_value, &[i32_arg], "call")
/// let ret_val = builder.build_call(fn_value, &[i32_arg.into(), md_string.into()], "call")
/// .try_as_basic_value()
/// .left()
/// .unwrap();
///
/// builder.build_return(Some(&ret_val));
/// ```
pub fn build_call<F>(&self, function: F, args: &[BasicValueEnum<'ctx>], name: &str) -> CallSiteValue<'ctx>
pub fn build_call<F>(&self, function: F, args: &[BasicMetadataValueEnum<'ctx>], name: &str) -> CallSiteValue<'ctx>
where
F: Into<CallableValue<'ctx>>,
{
Expand Down
24 changes: 24 additions & 0 deletions src/context.rs
@@ -1,6 +1,8 @@
//! A `Context` is an opaque owner and manager of core global data.

use llvm_sys::core::{LLVMAppendBasicBlockInContext, LLVMContextCreate, LLVMContextDispose, LLVMCreateBuilderInContext, LLVMDoubleTypeInContext, LLVMFloatTypeInContext, LLVMFP128TypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMHalfTypeInContext, LLVMGetGlobalContext, LLVMPPCFP128TypeInContext, LLVMConstStructInContext, LLVMMDNodeInContext, LLVMMDStringInContext, LLVMGetMDKindIDInContext, LLVMX86FP80TypeInContext, LLVMConstStringInContext, LLVMContextSetDiagnosticHandler};
#[llvm_versions(6.0..=latest)]
use llvm_sys::core::LLVMMetadataTypeInContext;
#[llvm_versions(3.9..=latest)]
use llvm_sys::core::{LLVMCreateEnumAttribute, LLVMCreateStringAttribute};
#[llvm_versions(3.6..7.0)]
Expand Down Expand Up @@ -28,6 +30,8 @@ use crate::module::Module;
use crate::support::{to_c_str, LLVMString};
use crate::targets::TargetData;
use crate::types::{AnyTypeEnum, BasicTypeEnum, FloatType, IntType, StructType, VoidType, AsTypeRef, FunctionType};
#[llvm_versions(6.0..=latest)]
use crate::types::MetadataType;
use crate::values::{AsValueRef, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, StructValue, MetadataValue, VectorValue, PointerValue};

use std::marker::PhantomData;
Expand Down Expand Up @@ -427,6 +431,26 @@ impl Context {
}
}

/// Gets the `MetadataType` representing 128 bit width. It will be assigned the current context.
///
/// # Example
///
/// ```
/// use inkwell::context::Context;
/// use inkwell::values::IntValue;
///
/// let context = Context::create();
/// let md_type = context.metadata_type();
///
/// assert_eq!(*md_type.get_context(), context);
/// ```
#[llvm_versions(6.0..=latest)]
pub fn metadata_type(&self) -> MetadataType {
unsafe {
MetadataType::new(LLVMMetadataTypeInContext(self.context))
}
}

/// Gets the `IntType` representing a bit width of a pointer. It will be assigned the referenced context.
///
/// # Example
Expand Down
23 changes: 14 additions & 9 deletions src/module.rs
Expand Up @@ -818,8 +818,8 @@ impl<'ctx> Module<'ctx> {
/// let md_string = context.metadata_string("lots of metadata here");
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
///
/// module.add_global_metadata("my_md", &md_string);
/// module.add_global_metadata("my_md", &md_node);
/// module.add_global_metadata("my_md", &md_string).unwrap();
/// module.add_global_metadata("my_md", &md_node).unwrap();
///
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
///
Expand All @@ -835,12 +835,17 @@ impl<'ctx> Module<'ctx> {
/// assert_eq!(md_1[0].into_int_value(), bool_val);
/// assert_eq!(md_1[1].into_float_value(), f32_val);
/// ```
pub fn add_global_metadata(&self, key: &str, metadata: &MetadataValue<'ctx>) {
let c_string = to_c_str(key);
pub fn add_global_metadata(&self, key: &str, metadata: &MetadataValue<'ctx>) -> Result<(), &'static str> {
if !metadata.is_node() {
return Err("metadata is expected to be a node.")
}

let c_string = to_c_str(key);
unsafe {
LLVMAddNamedMetadataOperand(self.module.get(), c_string.as_ptr(), metadata.as_value_ref())
LLVMAddNamedMetadataOperand(self.module.get(), c_string.as_ptr(), metadata.as_value_ref());
}

Ok(())
}

// REVIEW: Better name? get_global_metadata_len or _count?
Expand All @@ -863,8 +868,8 @@ impl<'ctx> Module<'ctx> {
/// let md_string = context.metadata_string("lots of metadata here");
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
///
/// module.add_global_metadata("my_md", &md_string);
/// module.add_global_metadata("my_md", &md_node);
/// module.add_global_metadata("my_md", &md_string).unwrap();
/// module.add_global_metadata("my_md", &md_node).unwrap();
///
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
///
Expand Down Expand Up @@ -908,8 +913,8 @@ impl<'ctx> Module<'ctx> {
/// let md_string = context.metadata_string("lots of metadata here");
/// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
///
/// module.add_global_metadata("my_md", &md_string);
/// module.add_global_metadata("my_md", &md_node);
/// module.add_global_metadata("my_md", &md_string).unwrap();
/// module.add_global_metadata("my_md", &md_node).unwrap();
///
/// assert_eq!(module.get_global_metadata_size("my_md"), 2);
///
Expand Down
3 changes: 2 additions & 1 deletion src/types/array_type.rs
Expand Up @@ -6,6 +6,7 @@ use crate::context::ContextRef;
use crate::types::traits::AsTypeRef;
use crate::types::{Type, BasicTypeEnum, PointerType, FunctionType};
use crate::values::{AsValueRef, ArrayValue, IntValue};
use crate::types::enums::BasicMetadataTypeEnum;

/// An `ArrayType` is the type of contiguous constants or variables.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
Expand Down Expand Up @@ -103,7 +104,7 @@ impl<'ctx> ArrayType<'ctx> {
/// let i8_array_type = i8_type.array_type(3);
/// let fn_type = i8_array_type.fn_type(&[], false);
/// ```
pub fn fn_type(self, param_types: &[BasicTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> {
pub fn fn_type(self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> {
self.array_type.fn_type(param_types, is_var_args)
}

Expand Down

0 comments on commit bec0222

Please sign in to comment.