From 50c942a7a34c8dfe97d11d578394dd231120a449 Mon Sep 17 00:00:00 2001 From: Mike Rostecki Date: Fri, 10 Nov 2023 00:18:03 +0100 Subject: [PATCH] Support LLVM 17 This includes the following LLVM-C API changes: * Core * Removed functions: * LLVMContextSetOpaquePointers * LLVMConstSelect * Transforms * PassRegistry and pass initialization removed, as they were the part of legacy Pass Manager. This results in complete removal of the following modules: * instcombine * ipo * pass_manager_builder * scalar * util * vectorize * Debug info * New language: * Mojo Fixes: #444 --- Cargo.toml | 7 +++ internal_macros/src/lib.rs | 4 +- src/builder.rs | 24 +++++----- src/context.rs | 41 +++++++++++++++-- src/debug_info.rs | 24 +++++++--- src/lib.rs | 19 +++++++- src/module.rs | 12 +++-- src/passes.rs | 87 +++++++++++++++++++++++++++++++----- src/support/mod.rs | 2 +- src/types/enums.rs | 22 +++++---- src/values/int_value.rs | 11 +++-- src/values/metadata_value.rs | 2 +- src/values/mod.rs | 6 +-- src/values/vec_value.rs | 5 ++- 14 files changed, 208 insertions(+), 58 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6ff7d388ac3..ec0f3de8fe6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ llvm13-0 = ["llvm-sys-130"] llvm14-0 = ["llvm-sys-140"] llvm15-0 = ["llvm-sys-150"] llvm16-0 = ["llvm-sys-160"] +llvm17-0 = ["llvm-sys-170"] # Don't link against LLVM libraries. This is useful if another dependency is # installing LLVM. See llvm-sys for more details. We can't enable a single # `no-llvm-linking` feature across the board of llvm versions, as it'll cause @@ -45,6 +46,7 @@ llvm13-0-no-llvm-linking = ["llvm13-0", "llvm-sys-130/no-llvm-linking"] llvm14-0-no-llvm-linking = ["llvm14-0", "llvm-sys-140/no-llvm-linking"] llvm15-0-no-llvm-linking = ["llvm15-0", "llvm-sys-150/no-llvm-linking"] llvm16-0-no-llvm-linking = ["llvm16-0", "llvm-sys-160/no-llvm-linking"] +llvm17-0-no-llvm-linking = ["llvm17-0", "llvm-sys-170/no-llvm-linking"] # Linking preference. # If none of these are enabled, it defaults to force static linking. @@ -55,6 +57,7 @@ llvm13-0-force-dynamic = ["llvm13-0", "llvm-sys-130/force-dynamic"] llvm14-0-force-dynamic = ["llvm14-0", "llvm-sys-140/force-dynamic"] llvm15-0-force-dynamic = ["llvm15-0", "llvm-sys-150/force-dynamic"] llvm16-0-force-dynamic = ["llvm16-0", "llvm-sys-160/force-dynamic"] +llvm17-0-force-dynamic = ["llvm17-0", "llvm-sys-170/force-dynamic"] # Prefer dynamic linking against LLVM libraries. See llvm-sys for more details llvm12-0-prefer-dynamic = ["llvm12-0", "llvm-sys-120/prefer-dynamic"] @@ -62,6 +65,7 @@ llvm13-0-prefer-dynamic = ["llvm13-0", "llvm-sys-130/prefer-dynamic"] llvm14-0-prefer-dynamic = ["llvm14-0", "llvm-sys-140/prefer-dynamic"] llvm15-0-prefer-dynamic = ["llvm15-0", "llvm-sys-150/prefer-dynamic"] llvm16-0-prefer-dynamic = ["llvm16-0", "llvm-sys-160/prefer-dynamic"] +llvm17-0-prefer-dynamic = ["llvm17-0", "llvm-sys-170/prefer-dynamic"] # Force static linking against LLVM libraries. See llvm-sys for more details llvm12-0-force-static = ["llvm12-0", "llvm-sys-120/force-static"] @@ -69,6 +73,7 @@ llvm13-0-force-static = ["llvm13-0", "llvm-sys-130/force-static"] llvm14-0-force-static = ["llvm14-0", "llvm-sys-140/force-static"] llvm15-0-force-static = ["llvm15-0", "llvm-sys-150/force-static"] llvm16-0-force-static = ["llvm16-0", "llvm-sys-160/force-static"] +llvm17-0-force-static = ["llvm17-0", "llvm-sys-170/force-static"] # Prefer static linking against LLVM libraries. See llvm-sys for more details llvm12-0-prefer-static = ["llvm12-0", "llvm-sys-120/prefer-static"] @@ -76,6 +81,7 @@ llvm13-0-prefer-static = ["llvm13-0", "llvm-sys-130/prefer-static"] llvm14-0-prefer-static = ["llvm14-0", "llvm-sys-140/prefer-static"] llvm15-0-prefer-static = ["llvm15-0", "llvm-sys-150/prefer-static"] llvm16-0-prefer-static = ["llvm16-0", "llvm-sys-160/prefer-static"] +llvm17-0-prefer-static = ["llvm17-0", "llvm-sys-170/prefer-static"] # Don't force linking to libffi on non-windows platforms. Without this feature # inkwell always links to libffi on non-windows platforms. @@ -137,6 +143,7 @@ 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.0", optional = true } once_cell = "1.16" static-alloc = { version = "0.2", optional = true } thiserror = "1.0.48" diff --git a/internal_macros/src/lib.rs b/internal_macros/src/lib.rs index a6aa9054b1c..ce15f0c073c 100644 --- a/internal_macros/src/lib.rs +++ b/internal_macros/src/lib.rs @@ -12,9 +12,9 @@ use syn::{parse_macro_input, parse_quote}; use syn::{Attribute, Field, Ident, Item, LitFloat, Token, Variant}; // This array should match the LLVM features in the top level Cargo manifest -const FEATURE_VERSIONS: [&str; 13] = [ +const FEATURE_VERSIONS: [&str; 14] = [ "llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", - "llvm14-0", "llvm15-0", "llvm16-0", + "llvm14-0", "llvm15-0", "llvm16-0", "llvm17-0", ]; /// Gets the index of the feature version that represents `latest` diff --git a/src/builder.rs b/src/builder.rs index 60301cfeadf..d6a6f766ab6 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -1461,7 +1461,7 @@ impl<'ctx> Builder<'ctx> { /// both a power of 2 and under 2^64. /// /// The final argument should be a pointer-sized integer. - /// + /// /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. @@ -1509,7 +1509,7 @@ impl<'ctx> Builder<'ctx> { /// both a power of 2 and under 2^64. /// /// The final argument should be a pointer-sized integer. - /// + /// /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2 under 2^64. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. @@ -1557,7 +1557,7 @@ impl<'ctx> Builder<'ctx> { /// both a power of 2 and under 2^64. /// /// The final argument should be a pointer-sized integer. - /// + /// /// Returns an `Err(BuilderError::AlignmentError)` if the source alignment is not a power of 2 under 2^64. /// /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those. @@ -2669,7 +2669,7 @@ impl<'ctx> Builder<'ctx> { // REVIEW: What if instruction and basic_block are completely unrelated? // It'd be great if we could get the BB from the instruction behind the scenes /// Set the position of the builder to after an instruction. - /// + /// /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`. pub fn position_at(&self, basic_block: BasicBlock<'ctx>, instruction: &InstructionValue<'ctx>) { self.positioned.set(PositionState::Set); @@ -2678,7 +2678,7 @@ impl<'ctx> Builder<'ctx> { } /// Set the position of the builder to before an instruction. - /// + /// /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`. pub fn position_before(&self, instruction: &InstructionValue<'ctx>) { self.positioned.set(PositionState::Set); @@ -2687,7 +2687,7 @@ impl<'ctx> Builder<'ctx> { } /// Set the position of the builder to the end of a basic block. - /// + /// /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`. pub fn position_at_end(&self, basic_block: BasicBlock<'ctx>) { self.positioned.set(PositionState::Set); @@ -2699,7 +2699,7 @@ impl<'ctx> Builder<'ctx> { /// Builds an extract value instruction which extracts a `BasicValueEnum` /// from a struct or array. - /// + /// /// Returns `Err(BuilderError::ExtractOutOfRange)` if the provided index is out of bounds of the aggregate value length. /// /// # Example @@ -2782,7 +2782,7 @@ impl<'ctx> Builder<'ctx> { /// Builds an insert value instruction which inserts a `BasicValue` into a struct /// or array and returns the resulting aggregate value. - /// + /// /// Returns `Err(BuilderError::ExtractOutOfRange)` if the provided index is out of bounds of the aggregate value length. /// /// # Example @@ -3215,7 +3215,7 @@ impl<'ctx> Builder<'ctx> { /// May return of the following errors: /// - `Err(BuilderError::BitwidthError)` if the bitwidth of the value is not a power of 2 and less than 8 /// - `Err(BuilderError:PointeeTypeMismatch)` if the pointee type does not match the value's type - /// + /// /// # Example /// /// ``` @@ -3256,7 +3256,7 @@ impl<'ctx> Builder<'ctx> { )); } - #[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0")))] + #[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0")))] if ptr.get_type().get_element_type() != value.get_type().into() { return Err(BuilderError::PointeeTypeMismatch( "Pointer's pointee type must match the value's type.", @@ -3278,7 +3278,7 @@ impl<'ctx> Builder<'ctx> { } /// Builds a cmpxchg instruction. It allows you to atomically compare and replace memory. - /// + /// /// May return one of the following errors: /// - `Err(BuilderError::PointeeTypeMismatch)` if the pointer does not point to an element of the value type /// - `Err(BuilderError::ValueTypeMismatch)` if the value to compare and the new values are not of the same type, or if @@ -3334,7 +3334,7 @@ impl<'ctx> Builder<'ctx> { )); } - #[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0")))] + #[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0")))] if ptr.get_type().get_element_type().to_basic_type_enum() != cmp.get_type() { return Err(BuilderError::PointeeTypeMismatch( "The pointer does not point to an element of the value type.", diff --git a/src/context.rs b/src/context.rs index b4525473f49..486119eb3bf 100644 --- a/src/context.rs +++ b/src/context.rs @@ -19,10 +19,13 @@ use llvm_sys::core::{ LLVMCreateStringAttribute, LLVMDoubleTypeInContext, LLVMFP128TypeInContext, LLVMFloatTypeInContext, LLVMGetGlobalContext, LLVMGetMDKindIDInContext, LLVMHalfTypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, - LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMMDNodeInContext, LLVMMDStringInContext, - LLVMModuleCreateWithNameInContext, LLVMPPCFP128TypeInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, - LLVMVoidTypeInContext, LLVMX86FP80TypeInContext, + LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMPPCFP128TypeInContext, + LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMX86FP80TypeInContext, }; +#[llvm_versions(4.0..=16.0)] +use llvm_sys::core::{LLVMMDNodeInContext, LLVMMDStringInContext}; +#[llvm_versions(16.0..=latest)] +use llvm_sys::core::{LLVMMDNodeInContext2, LLVMMDStringInContext2}; use llvm_sys::ir_reader::LLVMParseIRInContext; use llvm_sys::prelude::{LLVMContextRef, LLVMDiagnosticInfoRef, LLVMTypeRef, LLVMValueRef}; use llvm_sys::target::{LLVMIntPtrTypeForASInContext, LLVMIntPtrTypeInContext}; @@ -321,6 +324,7 @@ impl ContextImpl { } } + #[llvm_versions(4.0..=16.0)] fn metadata_node<'ctx>(&self, values: &[BasicMetadataValueEnum<'ctx>]) -> MetadataValue<'ctx> { let mut tuple_values: Vec = values.iter().map(|val| val.as_value_ref()).collect(); unsafe { @@ -332,12 +336,43 @@ impl ContextImpl { } } + #[llvm_versions(17.0..=latest)] + fn metadata_node<'ctx>(&self, values: &[BasicMetadataValueEnum<'ctx>]) -> MetadataValue<'ctx> { + use llvm_sys::{core::LLVMMetadataAsValue, prelude::LLVMMetadataRef}; + + let mut tuple_values: Vec = values + .iter() + .map(|val| val.into_metadata_value().as_metadata_ref()) + .collect(); + unsafe { + MetadataValue::new(LLVMMetadataAsValue( + self.0, + LLVMMDNodeInContext2(self.0, tuple_values.as_mut_ptr(), tuple_values.len()), + )) + } + } + + #[llvm_versions(4.0..=16.0)] fn metadata_string<'ctx>(&self, string: &str) -> MetadataValue<'ctx> { let c_string = to_c_str(string); unsafe { MetadataValue::new(LLVMMDStringInContext(self.0, c_string.as_ptr(), string.len() as u32)) } } + #[llvm_versions(17.0..=latest)] + fn metadata_string<'ctx>(&self, string: &str) -> MetadataValue<'ctx> { + use llvm_sys::core::LLVMMetadataAsValue; + + let c_string = to_c_str(string); + + unsafe { + MetadataValue::new(LLVMMetadataAsValue( + self.0, + LLVMMDStringInContext2(self.0, c_string.as_ptr(), string.len()), + )) + } + } + fn get_kind_id(&self, key: &str) -> u32 { unsafe { LLVMGetMDKindIDInContext(self.0, key.as_ptr() as *const ::libc::c_char, key.len() as u32) } } diff --git a/src/debug_info.rs b/src/debug_info.rs index d2612bce452..044a8622cff 100644 --- a/src/debug_info.rs +++ b/src/debug_info.rs @@ -192,7 +192,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sysroot: &str, #[cfg(any( @@ -201,7 +202,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sdk: &str, ) -> (Self, DICompileUnit<'ctx>) { @@ -238,7 +240,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sysroot, #[cfg(any( @@ -247,7 +250,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sdk, ); @@ -292,7 +296,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sysroot: &str, #[cfg(any( @@ -301,7 +306,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sdk: &str, ) -> DICompileUnit<'ctx> { @@ -341,7 +347,8 @@ impl<'ctx> DebugInfoBuilder<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] { LLVMDIBuilderCreateCompileUnit( @@ -1585,5 +1592,8 @@ mod flags { #[llvm_versions(16.0..=latest)] #[llvm_variant(LLVMDWARFSourceLanguageAda2012)] Ada2012, + #[llvm_versions(17.0..=latest)] + #[llvm_variant(LLVMDWARFSourceLanguageMojo)] + Mojo, } } diff --git a/src/lib.rs b/src/lib.rs index aafc82bd71b..1f5d2321173 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,8 @@ extern crate llvm_sys_140 as llvm_sys; extern crate llvm_sys_150 as llvm_sys; #[cfg(feature = "llvm16-0")] extern crate llvm_sys_160 as llvm_sys; +#[cfg(feature = "llvm17-0")] +extern crate llvm_sys_170 as llvm_sys; #[cfg(feature = "llvm4-0")] extern crate llvm_sys_40 as llvm_sys; #[cfg(feature = "llvm5-0")] @@ -107,7 +109,22 @@ macro_rules! assert_unique_used_features { } } -assert_unique_used_features! {"llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", "llvm14-0", "llvm15-0", "llvm16-0"} +assert_unique_used_features! { + "llvm4-0", + "llvm5-0", + "llvm6-0", + "llvm7-0", + "llvm8-0", + "llvm9-0", + "llvm10-0", + "llvm11-0", + "llvm12-0", + "llvm13-0", + "llvm14-0", + "llvm15-0", + "llvm16-0", + "llvm17-0" +} /// Defines the address space in which a global will be inserted. /// diff --git a/src/module.rs b/src/module.rs index 6bf8d5680b1..08a3bf91a7b 100644 --- a/src/module.rs +++ b/src/module.rs @@ -1425,7 +1425,8 @@ impl<'ctx> Module<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sysroot: &str, #[cfg(any( @@ -1434,7 +1435,8 @@ impl<'ctx> Module<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sdk: &str, ) -> (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>) { @@ -1459,7 +1461,8 @@ impl<'ctx> Module<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sysroot, #[cfg(any( @@ -1468,7 +1471,8 @@ impl<'ctx> Module<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] sdk, ) diff --git a/src/passes.rs b/src/passes.rs index e2f9526cbcd..47c8624366b 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -1,8 +1,10 @@ +#[llvm_versions(4.0..=16.0)] +use llvm_sys::core::LLVMGetGlobalPassRegistry; use llvm_sys::core::{ LLVMCreateFunctionPassManagerForModule, LLVMCreatePassManager, LLVMDisposePassManager, - LLVMFinalizeFunctionPassManager, LLVMGetGlobalPassRegistry, LLVMInitializeFunctionPassManager, - LLVMRunFunctionPassManager, LLVMRunPassManager, + LLVMFinalizeFunctionPassManager, LLVMInitializeFunctionPassManager, LLVMRunFunctionPassManager, LLVMRunPassManager, }; +#[llvm_versions(4.0..=16.0)] use llvm_sys::initialization::{ LLVMInitializeAnalysis, LLVMInitializeCodeGen, LLVMInitializeCore, LLVMInitializeIPA, LLVMInitializeIPO, LLVMInitializeInstCombine, LLVMInitializeScalarOpts, LLVMInitializeTarget, LLVMInitializeTransformUtils, @@ -10,16 +12,20 @@ use llvm_sys::initialization::{ }; #[llvm_versions(4.0..=15.0)] use llvm_sys::initialization::{LLVMInitializeInstrumentation, LLVMInitializeObjCARCOpts}; -use llvm_sys::prelude::{LLVMPassManagerRef, LLVMPassRegistryRef}; -#[llvm_versions(10.0..=latest)] +use llvm_sys::prelude::LLVMPassManagerRef; +#[llvm_versions(4.0..=16.0)] +use llvm_sys::prelude::LLVMPassRegistry; +#[llvm_versions(10.0..=16.0)] use llvm_sys::transforms::ipo::LLVMAddMergeFunctionsPass; #[llvm_versions(4.0..=15.0)] use llvm_sys::transforms::ipo::LLVMAddPruneEHPass; +#[llvm_versions(4.0..=16.0)] use llvm_sys::transforms::ipo::{ LLVMAddAlwaysInlinerPass, LLVMAddConstantMergePass, LLVMAddDeadArgEliminationPass, LLVMAddFunctionAttrsPass, LLVMAddFunctionInliningPass, LLVMAddGlobalDCEPass, LLVMAddGlobalOptimizerPass, LLVMAddIPSCCPPass, LLVMAddInternalizePass, LLVMAddStripDeadPrototypesPass, LLVMAddStripSymbolsPass, }; +#[llvm_versions(4.0..=16.0)] use llvm_sys::transforms::pass_manager_builder::{ LLVMPassManagerBuilderCreate, LLVMPassManagerBuilderDispose, LLVMPassManagerBuilderPopulateFunctionPassManager, LLVMPassManagerBuilderPopulateModulePassManager, LLVMPassManagerBuilderRef, @@ -27,6 +33,7 @@ use llvm_sys::transforms::pass_manager_builder::{ LLVMPassManagerBuilderSetDisableUnrollLoops, LLVMPassManagerBuilderSetOptLevel, LLVMPassManagerBuilderSetSizeLevel, LLVMPassManagerBuilderUseInlinerWithThreshold, }; +#[llvm_versions(4.0..=16.0)] use llvm_sys::transforms::scalar::{ LLVMAddAggressiveDCEPass, LLVMAddAlignmentFromAssumptionsPass, LLVMAddBasicAliasAnalysisPass, LLVMAddBitTrackingDCEPass, LLVMAddCFGSimplificationPass, LLVMAddCorrelatedValuePropagationPass, @@ -39,6 +46,7 @@ use llvm_sys::transforms::scalar::{ LLVMAddScopedNoAliasAAPass, LLVMAddSimplifyLibCallsPass, LLVMAddTailCallEliminationPass, LLVMAddTypeBasedAliasAnalysisPass, LLVMAddVerifierPass, }; +#[llvm_versions(4.0..=16.0)] use llvm_sys::transforms::vectorize::{LLVMAddLoopVectorizePass, LLVMAddSLPVectorizePass}; // LLVM12 removes the ConstantPropagation pass @@ -58,22 +66,25 @@ use llvm_sys::transforms::pass_builder::{ LLVMPassBuilderOptionsSetMergeFunctions, LLVMPassBuilderOptionsSetSLPVectorization, LLVMPassBuilderOptionsSetVerifyEach, }; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12.0..=16.0)] use llvm_sys::transforms::scalar::LLVMAddInstructionSimplifyPass; use crate::module::Module; use crate::values::{AsValueRef, FunctionValue}; +#[llvm_versions(4.0..=16.0)] use crate::OptimizationLevel; use std::borrow::Borrow; use std::marker::PhantomData; // REVIEW: Opt Level might be identical to targets::Option +#[llvm_versions(4.0..=16.0)] #[derive(Debug)] pub struct PassManagerBuilder { pass_manager_builder: LLVMPassManagerBuilderRef, } +#[llvm_versions(4.0..=16.0)] impl PassManagerBuilder { pub unsafe fn new(pass_manager_builder: LLVMPassManagerBuilderRef) -> Self { assert!(!pass_manager_builder.is_null()); @@ -202,6 +213,7 @@ impl PassManagerBuilder { } } +#[llvm_versions(4.0..=16.0)] impl Drop for PassManagerBuilder { fn drop(&mut self) { unsafe { LLVMPassManagerBuilderDispose(self.pass_manager_builder) } @@ -323,12 +335,13 @@ impl PassManager { /// shared. This is useful because some passes (i.e., TraceValues) insert a lot /// of string constants into the program, regardless of whether or not an existing /// string is available. + #[llvm_versions(4.0..=16.0)] pub fn add_constant_merge_pass(&self) { unsafe { LLVMAddConstantMergePass(self.pass_manager) } } /// Discovers identical functions and collapses them. - #[llvm_versions(10.0..=latest)] + #[llvm_versions(10.0..=16.0)] pub fn add_merge_functions_pass(&self) { unsafe { LLVMAddMergeFunctionsPass(self.pass_manager) } } @@ -340,6 +353,7 @@ impl PassManager { /// /// This pass is often useful as a cleanup pass to run after aggressive /// interprocedural passes, which add possibly-dead arguments. + #[llvm_versions(4.0..=16.0)] pub fn add_dead_arg_elimination_pass(&self) { unsafe { LLVMAddDeadArgEliminationPass(self.pass_manager) } } @@ -352,16 +366,19 @@ impl PassManager { /// less means that the pointer is only dereferenced, and not returned /// from the function or stored in a global. This pass is implemented /// as a bottom-up traversal of the call-graph. + #[llvm_versions(4.0..=16.0)] pub fn add_function_attrs_pass(&self) { unsafe { LLVMAddFunctionAttrsPass(self.pass_manager) } } /// Bottom-up inlining of functions into callees. + #[llvm_versions(4.0..=16.0)] pub fn add_function_inlining_pass(&self) { unsafe { LLVMAddFunctionInliningPass(self.pass_manager) } } /// A custom inliner that handles only functions that are marked as “always inline”. + #[llvm_versions(4.0..=16.0)] pub fn add_always_inliner_pass(&self) { unsafe { LLVMAddAlwaysInlinerPass(self.pass_manager) } } @@ -372,6 +389,7 @@ impl PassManager { /// finds all of the globals which are needed, it deletes /// whatever is left over. This allows it to delete recursive /// chunks of the program which are unreachable. + #[llvm_versions(4.0..=16.0)] pub fn add_global_dce_pass(&self) { unsafe { LLVMAddGlobalDCEPass(self.pass_manager) } } @@ -379,6 +397,7 @@ impl PassManager { /// This pass transforms simple global variables that never have /// their address taken. If obviously true, it marks read/write /// globals as constant, deletes variables only stored to, etc. + #[llvm_versions(4.0..=16.0)] pub fn add_global_optimizer_pass(&self) { unsafe { LLVMAddGlobalOptimizerPass(self.pass_manager) } } @@ -409,6 +428,7 @@ impl PassManager { /// An interprocedural variant of [Sparse Conditional Constant /// Propagation](https://llvm.org/docs/Passes.html#passes-sccp). + #[llvm_versions(4.0..=16.0)] pub fn add_ipsccp_pass(&self) { unsafe { LLVMAddIPSCCPPass(self.pass_manager) } } @@ -417,6 +437,7 @@ impl PassManager { /// looking for a main function. If a main function is found, all /// other functions and all global variables with initializers are /// marked as internal. + #[llvm_versions(4.0..=16.0)] pub fn add_internalize_pass(&self, all_but_main: bool) { unsafe { LLVMAddInternalizePass(self.pass_manager, all_but_main as u32) } } @@ -425,6 +446,7 @@ impl PassManager { /// looking for dead declarations and removes them. Dead declarations /// are declarations of functions for which no implementation is available /// (i.e., declarations for unused library functions). + #[llvm_versions(4.0..=16.0)] pub fn add_strip_dead_prototypes_pass(&self) { unsafe { LLVMAddStripDeadPrototypesPass(self.pass_manager) } } @@ -439,6 +461,7 @@ impl PassManager { /// so it should only be used in situations where the strip utility /// would be used, such as reducing code size or making it harder /// to reverse engineer code. + #[llvm_versions(4.0..=16.0)] pub fn add_strip_symbol_pass(&self) { unsafe { LLVMAddStripSymbolsPass(self.pass_manager) } } @@ -464,11 +487,13 @@ impl PassManager { } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_vectorize_pass(&self) { unsafe { LLVMAddLoopVectorizePass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_slp_vectorize_pass(&self) { unsafe { LLVMAddSLPVectorizePass(self.pass_manager) } } @@ -478,16 +503,19 @@ impl PassManager { /// assumes that values are dead until proven otherwise. This is /// similar to [SCCP](https://llvm.org/docs/Passes.html#passes-sccp), /// except applied to the liveness of values. + #[llvm_versions(4.0..=16.0)] pub fn add_aggressive_dce_pass(&self) { unsafe { LLVMAddAggressiveDCEPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_bit_tracking_dce_pass(&self) { unsafe { LLVMAddBitTrackingDCEPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_alignment_from_assumptions_pass(&self) { unsafe { LLVMAddAlignmentFromAssumptionsPass(self.pass_manager) } } @@ -498,21 +526,25 @@ impl PassManager { /// * Merges a basic block into its predecessor if there is only one and the predecessor only has one successor. /// * Eliminates PHI nodes for basic blocks with a single predecessor. /// * Eliminates a basic block that only contains an unconditional branch. + #[llvm_versions(4.0..=16.0)] pub fn add_cfg_simplification_pass(&self) { unsafe { LLVMAddCFGSimplificationPass(self.pass_manager) } } /// A trivial dead store elimination that only considers basic-block local redundant stores. + #[llvm_versions(4.0..=16.0)] pub fn add_dead_store_elimination_pass(&self) { unsafe { LLVMAddDeadStoreEliminationPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_scalarizer_pass(&self) { unsafe { LLVMAddScalarizerPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_merged_load_store_motion_pass(&self) { unsafe { LLVMAddMergedLoadStoreMotionPass(self.pass_manager) } } @@ -520,6 +552,7 @@ impl PassManager { /// This pass performs global value numbering to eliminate /// fully and partially redundant instructions. It also /// performs redundant load elimination. + #[llvm_versions(4.0..=16.0)] pub fn add_gvn_pass(&self) { unsafe { LLVMAddGVNPass(self.pass_manager) } } @@ -529,7 +562,7 @@ impl PassManager { /// performs redundant load elimination. // REVIEW: Is `LLVMAddGVNPass` deprecated? Should we just seamlessly replace // the old one with this one in 4.0+? - #[llvm_versions(4.0..=latest)] + #[llvm_versions(4.0..=16.0)] pub fn add_new_gvn_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddNewGVNPass; @@ -575,6 +608,7 @@ impl PassManager { /// the desired loop transformations have been performed. Additionally, on /// targets where it is profitable, the loop could be transformed to count /// down to zero (the "do loop" optimization). + #[llvm_versions(4.0..=16.0)] pub fn add_ind_var_simplify_pass(&self) { unsafe { LLVMAddIndVarSimplifyPass(self.pass_manager) } } @@ -619,6 +653,7 @@ impl PassManager { /// the main() function can be transformed into simply return 3. Whether or not library /// calls are simplified is controlled by the [-functionattrs](https://llvm.org/docs/Passes.html#passes-functionattrs) /// pass and LLVM’s knowledge of library calls on different targets. + #[llvm_versions(4.0..=16.0)] pub fn add_instruction_combining_pass(&self) { unsafe { LLVMAddInstructionCombiningPass(self.pass_manager) } } @@ -642,6 +677,7 @@ impl PassManager { /// /// In this case, the unconditional branch at the end of the first /// if can be revectored to the false side of the second if. + #[llvm_versions(4.0..=16.0)] pub fn add_jump_threading_pass(&self) { unsafe { LLVMAddJumpThreadingPass(self.pass_manager) } } @@ -678,6 +714,7 @@ impl PassManager { /// and stores in the loop of the pointer to use a temporary /// alloca'd variable. We then use the mem2reg functionality /// to construct the appropriate SSA form for the variable. + #[llvm_versions(4.0..=16.0)] pub fn add_licm_pass(&self) { unsafe { LLVMAddLICMPass(self.pass_manager) } } @@ -687,21 +724,25 @@ impl PassManager { /// non-infinite computable trip counts that have no side /// effects or volatile instructions, and do not contribute /// to the computation of the function’s return value. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_deletion_pass(&self) { unsafe { LLVMAddLoopDeletionPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_idiom_pass(&self) { unsafe { LLVMAddLoopIdiomPass(self.pass_manager) } } /// A simple loop rotation transformation. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_rotate_pass(&self) { unsafe { LLVMAddLoopRotatePass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_reroll_pass(&self) { unsafe { LLVMAddLoopRerollPass(self.pass_manager) } } @@ -711,6 +752,7 @@ impl PassManager { /// by the [indvars](https://llvm.org/docs/Passes.html#passes-indvars) /// pass, allowing it to determine the trip counts /// of loops easily. + #[llvm_versions(4.0..=16.0)] pub fn add_loop_unroll_pass(&self) { unsafe { LLVMAddLoopUnrollPass(self.pass_manager) } } @@ -747,12 +789,14 @@ impl PassManager { /// This pass performs various transformations related /// to eliminating memcpy calls, or transforming sets /// of stores into memsets. + #[llvm_versions(4.0..=16.0)] pub fn add_memcpy_optimize_pass(&self) { unsafe { LLVMAddMemCpyOptPass(self.pass_manager) } } /// This pass performs partial inlining, typically by inlining /// an if statement that surrounds the body of the function. + #[llvm_versions(4.0..=16.0)] pub fn add_partially_inline_lib_calls_pass(&self) { unsafe { LLVMAddPartiallyInlineLibCallsPass(self.pass_manager) } } @@ -760,10 +804,11 @@ impl PassManager { /// Rewrites switch instructions with a sequence of branches, /// which allows targets to get away with not implementing the /// switch instruction until it is convenient. + #[llvm_versions(4.0..=16.0)] pub fn add_lower_switch_pass(&self) { #[llvm_versions(4.0..=6.0)] use llvm_sys::transforms::scalar::LLVMAddLowerSwitchPass; - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7.0..=16.0)] use llvm_sys::transforms::util::LLVMAddLowerSwitchPass; unsafe { LLVMAddLowerSwitchPass(self.pass_manager) } @@ -775,10 +820,11 @@ impl PassManager { /// to place phi nodes, then traversing the function in depth-first /// order to rewrite loads and stores as appropriate. This is just /// the standard SSA construction algorithm to construct "pruned" SSA form. + #[llvm_versions(4.0..=16.0)] pub fn add_promote_memory_to_register_pass(&self) { #[llvm_versions(4.0..=6.0)] use llvm_sys::transforms::scalar::LLVMAddPromoteMemoryToRegisterPass; - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7.0..=16.0)] use llvm_sys::transforms::util::LLVMAddPromoteMemoryToRegisterPass; unsafe { LLVMAddPromoteMemoryToRegisterPass(self.pass_manager) } @@ -794,6 +840,7 @@ impl PassManager { /// corresponding to the reverse post order traversal of current function /// (starting at 2), which effectively gives values in deep loops higher /// rank than values not in loops. + #[llvm_versions(4.0..=16.0)] pub fn add_reassociate_pass(&self) { unsafe { LLVMAddReassociatePass(self.pass_manager) } } @@ -808,11 +855,13 @@ impl PassManager { /// /// Note that this pass has a habit of making definitions be dead. /// It is a good idea to run a DCE pass sometime after running this pass. + #[llvm_versions(4.0..=16.0)] pub fn add_sccp_pass(&self) { unsafe { LLVMAddSCCPPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_scalar_repl_aggregates_pass(&self) { unsafe { LLVMAddScalarReplAggregatesPass(self.pass_manager) } } @@ -822,16 +871,19 @@ impl PassManager { /// (structure or array) into individual alloca instructions for each /// member if possible. Then, if possible, it transforms the individual /// alloca instructions into nice clean scalar SSA form. + #[llvm_versions(4.0..=16.0)] pub fn add_scalar_repl_aggregates_pass_ssa(&self) { unsafe { LLVMAddScalarReplAggregatesPassSSA(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_scalar_repl_aggregates_pass_with_threshold(&self, threshold: i32) { unsafe { LLVMAddScalarReplAggregatesPassWithThreshold(self.pass_manager, threshold) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_simplify_lib_calls_pass(&self) { unsafe { LLVMAddSimplifyLibCallsPass(self.pass_manager) } } @@ -856,6 +908,7 @@ impl PassManager { /// /// 4. If it can prove that callees do not access theier caller stack frame, /// they are marked as eligible for tail call elimination (by the code generator). + #[llvm_versions(4.0..=16.0)] pub fn add_tail_call_elimination_pass(&self) { unsafe { LLVMAddTailCallEliminationPass(self.pass_manager) } } @@ -900,7 +953,7 @@ impl PassManager { /// /// NOTE: this pass has a habit of making definitions be dead. It is a good idea to /// run a Dead Instruction Elimination pass sometime after running this pass. - #[llvm_versions(12.0..=latest)] + #[llvm_versions(12.0..=16.0)] pub fn add_instruction_simplify_pass(&self) { unsafe { LLVMAddInstructionSimplifyPass(self.pass_manager) } } @@ -911,6 +964,7 @@ impl PassManager { /// place phi nodes, then traversing the function in depth-first order to /// rewrite loads and stores as appropriate. This is just the standard SSA /// construction algorithm to construct “pruned” SSA form. + #[llvm_versions(4.0..=16.0)] pub fn add_demote_memory_to_register_pass(&self) { unsafe { LLVMAddDemoteMemoryToRegisterPass(self.pass_manager) } } @@ -966,21 +1020,24 @@ impl PassManager { /// 20. All other things that are tested by asserts spread about the code. /// /// Note that this does not provide full security verification (like Java), but instead just tries to ensure that code is well-formed. + #[llvm_versions(4.0..=16.0)] pub fn add_verifier_pass(&self) { unsafe { LLVMAddVerifierPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_correlated_value_propagation_pass(&self) { unsafe { LLVMAddCorrelatedValuePropagationPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_early_cse_pass(&self) { unsafe { LLVMAddEarlyCSEPass(self.pass_manager) } } - #[llvm_versions(4.0..=latest)] + #[llvm_versions(4.0..=16.0)] /// No LLVM documentation is available at this time. pub fn add_early_cse_mem_ssa_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddEarlyCSEMemSSAPass; @@ -989,16 +1046,19 @@ impl PassManager { } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_lower_expect_intrinsic_pass(&self) { unsafe { LLVMAddLowerExpectIntrinsicPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_type_based_alias_analysis_pass(&self) { unsafe { LLVMAddTypeBasedAliasAnalysisPass(self.pass_manager) } } /// No LLVM documentation is available at this time. + #[llvm_versions(4.0..=16.0)] pub fn add_scoped_no_alias_aa_pass(&self) { unsafe { LLVMAddScopedNoAliasAAPass(self.pass_manager) } } @@ -1006,6 +1066,7 @@ impl PassManager { /// A basic alias analysis pass that implements identities /// (two different globals cannot alias, etc), but does no /// stateful analysis. + #[llvm_versions(4.0..=16.0)] pub fn add_basic_alias_analysis_pass(&self) { unsafe { LLVMAddBasicAliasAnalysisPass(self.pass_manager) } } @@ -1020,7 +1081,7 @@ impl PassManager { unsafe { LLVMAddAggressiveInstCombinerPass(self.pass_manager) } } - #[llvm_versions(7.0..=latest)] + #[llvm_versions(7.0..=16.0)] pub fn add_loop_unroll_and_jam_pass(&self) { use llvm_sys::transforms::scalar::LLVMAddLoopUnrollAndJamPass; @@ -1062,11 +1123,13 @@ impl Drop for PassManager { } } +#[llvm_versions(4.0..=16.0)] #[derive(Debug)] pub struct PassRegistry { pass_registry: LLVMPassRegistryRef, } +#[llvm_versions(4.0..=16.0)] impl PassRegistry { pub unsafe fn new(pass_registry: LLVMPassRegistryRef) -> PassRegistry { assert!(!pass_registry.is_null()); diff --git a/src/support/mod.rs b/src/support/mod.rs index bd3422d5bc0..465e54c4a03 100644 --- a/src/support/mod.rs +++ b/src/support/mod.rs @@ -2,7 +2,7 @@ pub mod error_handling; use libc::c_char; -#[llvm_versions(16.0)] +#[llvm_versions(16.0..=latest)] use llvm_sys::core::LLVMGetVersion; use llvm_sys::core::{LLVMCreateMessage, LLVMDisposeMessage}; use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; diff --git a/src/types/enums.rs b/src/types/enums.rs index c897c08043a..efd404fda94 100644 --- a/src/types/enums.rs +++ b/src/types/enums.rs @@ -222,7 +222,8 @@ impl<'ctx> AnyTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMBFloatTypeKind => AnyTypeEnum::FloatType(FloatType::new(type_)), LLVMTypeKind::LLVMLabelTypeKind => panic!("FIXME: Unsupported type: Label"), @@ -238,7 +239,8 @@ impl<'ctx> AnyTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMScalableVectorTypeKind => AnyTypeEnum::VectorType(VectorType::new(type_)), // FIXME: should inkwell support metadata as AnyType? @@ -249,11 +251,12 @@ impl<'ctx> AnyTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMX86_AMXTypeKind => panic!("FIXME: Unsupported type: AMX"), LLVMTypeKind::LLVMTokenTypeKind => panic!("FIXME: Unsupported type: Token"), - #[cfg(feature = "llvm16-0")] + #[cfg(any(feature = "llvm16-0", feature = "llvm17-0"))] LLVMTypeKind::LLVMTargetExtTypeKind => panic!("FIXME: Unsupported type: TargetExt"), } } @@ -406,7 +409,8 @@ impl<'ctx> BasicTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMBFloatTypeKind => BasicTypeEnum::FloatType(FloatType::new(type_)), LLVMTypeKind::LLVMIntegerTypeKind => BasicTypeEnum::IntType(IntType::new(type_)), @@ -420,7 +424,8 @@ impl<'ctx> BasicTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMScalableVectorTypeKind => BasicTypeEnum::VectorType(VectorType::new(type_)), LLVMTypeKind::LLVMMetadataTypeKind => panic!("Unsupported basic type: Metadata"), @@ -432,14 +437,15 @@ impl<'ctx> BasicTypeEnum<'ctx> { feature = "llvm13-0", feature = "llvm14-0", feature = "llvm15-0", - feature = "llvm16-0" + feature = "llvm16-0", + feature = "llvm17-0" ))] LLVMTypeKind::LLVMX86_AMXTypeKind => unreachable!("Unsupported basic type: AMX"), LLVMTypeKind::LLVMLabelTypeKind => unreachable!("Unsupported basic type: Label"), LLVMTypeKind::LLVMVoidTypeKind => unreachable!("Unsupported basic type: VoidType"), LLVMTypeKind::LLVMFunctionTypeKind => unreachable!("Unsupported basic type: FunctionType"), LLVMTypeKind::LLVMTokenTypeKind => unreachable!("Unsupported basic type: Token"), - #[cfg(feature = "llvm16-0")] + #[cfg(any(feature = "llvm16-0", feature = "llvm17-0"))] LLVMTypeKind::LLVMTargetExtTypeKind => unreachable!("Unsupported basic type: TargetExt"), } } diff --git a/src/values/int_value.rs b/src/values/int_value.rs index 8ae04718136..0e68594efbb 100644 --- a/src/values/int_value.rs +++ b/src/values/int_value.rs @@ -1,10 +1,12 @@ +#[llvm_versions(4.0..=16.0)] +use llvm_sys::core::LLVMConstSelect; use llvm_sys::core::{ LLVMConstAShr, LLVMConstAdd, LLVMConstAnd, LLVMConstBitCast, LLVMConstICmp, LLVMConstIntCast, LLVMConstIntGetSExtValue, LLVMConstIntGetZExtValue, LLVMConstIntToPtr, LLVMConstLShr, LLVMConstMul, LLVMConstNSWAdd, LLVMConstNSWMul, LLVMConstNSWNeg, LLVMConstNSWSub, LLVMConstNUWAdd, LLVMConstNUWMul, LLVMConstNUWNeg, LLVMConstNUWSub, LLVMConstNeg, LLVMConstNot, LLVMConstOr, LLVMConstSExt, LLVMConstSExtOrBitCast, - LLVMConstSIToFP, LLVMConstSelect, LLVMConstShl, LLVMConstSub, LLVMConstTrunc, LLVMConstTruncOrBitCast, - LLVMConstUIToFP, LLVMConstXor, LLVMConstZExt, LLVMConstZExtOrBitCast, LLVMIsAConstantInt, + LLVMConstSIToFP, LLVMConstShl, LLVMConstSub, LLVMConstTrunc, LLVMConstTruncOrBitCast, LLVMConstUIToFP, + LLVMConstXor, LLVMConstZExt, LLVMConstZExtOrBitCast, LLVMIsAConstantInt, }; use llvm_sys::prelude::LLVMValueRef; @@ -14,7 +16,9 @@ use std::fmt::{self, Display}; use crate::types::{AsTypeRef, FloatType, IntType, PointerType}; use crate::values::traits::AsValueRef; -use crate::values::{BasicValue, BasicValueEnum, FloatValue, InstructionValue, PointerValue, Value}; +#[llvm_versions(4.0..=16.0)] +use crate::values::BasicValueEnum; +use crate::values::{BasicValue, FloatValue, InstructionValue, PointerValue, Value}; use crate::IntPredicate; use super::AnyValue; @@ -247,6 +251,7 @@ impl<'ctx> IntValue<'ctx> { } // SubTypes: self can only be IntValue + #[llvm_versions(4.0..=16.0)] pub fn const_select>(self, then: BV, else_: BV) -> BasicValueEnum<'ctx> { unsafe { BasicValueEnum::new(LLVMConstSelect( diff --git a/src/values/metadata_value.rs b/src/values/metadata_value.rs index 227a761470a..ba7a3563992 100644 --- a/src/values/metadata_value.rs +++ b/src/values/metadata_value.rs @@ -36,7 +36,7 @@ pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 30; pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 31; #[cfg(any(feature = "llvm15-0"))] pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 36; -#[cfg(any(feature = "llvm16-0"))] +#[cfg(any(feature = "llvm16-0", feature = "llvm17-0"))] pub const FIRST_CUSTOM_METADATA_KIND_ID: u32 = 39; #[derive(PartialEq, Eq, Clone, Copy, Hash)] diff --git a/src/values/mod.rs b/src/values/mod.rs index d133d31325d..0635a8925b0 100644 --- a/src/values/mod.rs +++ b/src/values/mod.rs @@ -20,10 +20,10 @@ mod struct_value; mod traits; mod vec_value; -#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0")))] +#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0")))] mod callable_value; -#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0")))] +#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0")))] pub use crate::values::callable_value::CallableValue; use crate::support::{to_c_str, LLVMString}; @@ -47,7 +47,7 @@ pub use crate::values::traits::AsValueRef; pub use crate::values::traits::{AggregateValue, AnyValue, BasicValue, FloatMathValue, IntMathValue, PointerMathValue}; pub use crate::values::vec_value::VectorValue; -#[llvm_versions(12.0..=latest)] +#[llvm_versions(12.0..=16.0)] use llvm_sys::core::LLVMIsPoison; use llvm_sys::core::{ diff --git a/src/values/vec_value.rs b/src/values/vec_value.rs index 79667e00f25..8ee8912c1c1 100644 --- a/src/values/vec_value.rs +++ b/src/values/vec_value.rs @@ -1,5 +1,7 @@ +#[llvm_versions(4.0..=16.0)] +use llvm_sys::core::LLVMConstSelect; use llvm_sys::core::{ - LLVMConstExtractElement, LLVMConstInsertElement, LLVMConstSelect, LLVMConstShuffleVector, LLVMGetElementAsConstant, + LLVMConstExtractElement, LLVMConstInsertElement, LLVMConstShuffleVector, LLVMGetElementAsConstant, LLVMIsAConstantDataVector, LLVMIsAConstantVector, }; use llvm_sys::prelude::LLVMValueRef; @@ -110,6 +112,7 @@ impl<'ctx> VectorValue<'ctx> { } // SubTypes: self can only be VectoValue> + #[llvm_versions(4.0..=16.0)] pub fn const_select>(self, then: BV, else_: BV) -> BasicValueEnum<'ctx> { unsafe { BasicValueEnum::new(LLVMConstSelect(