Skip to main content

inkwell/values/
scalable_vec_value.rs

1#[llvm_versions(..=16)]
2use llvm_sys::core::LLVMConstSelect;
3#[allow(deprecated)]
4use llvm_sys::core::LLVMGetElementAsConstant;
5use llvm_sys::core::{LLVMConstExtractElement, LLVMConstInsertElement, LLVMConstShuffleVector};
6use llvm_sys::prelude::LLVMValueRef;
7
8use std::ffi::CStr;
9use std::fmt::{self, Display};
10
11use crate::types::ScalableVectorType;
12use crate::values::traits::AsValueRef;
13use crate::values::{BasicValue, BasicValueEnum, InstructionValue, IntValue, Value};
14
15use super::AnyValue;
16
17#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
18pub struct ScalableVectorValue<'ctx> {
19    scalable_vec_value: Value<'ctx>,
20}
21
22impl<'ctx> ScalableVectorValue<'ctx> {
23    /// Get a value from an [LLVMValueRef].
24    ///
25    /// # Safety
26    ///
27    /// The ref must be valid and of type scalable vector.
28    pub unsafe fn new(scalable_vector_value: LLVMValueRef) -> Self {
29        assert!(!scalable_vector_value.is_null());
30
31        ScalableVectorValue {
32            scalable_vec_value: Value::new(scalable_vector_value),
33        }
34    }
35
36    /// Determines whether or not a `ScalableVectorValue` is a constant.
37    ///
38    /// # Example
39    ///
40    /// ```ignore
41    /// use inkwell::context::Context;
42    ///
43    /// let context = Context::create();
44    /// let i8_type = context.i8_type();
45    /// let i8_scalable_vec_type = i8_type.scalable_vec_type(3);
46    /// let i8_scalable_vec_zero = i8_scalable_vec_type.const_zero();
47    ///
48    /// assert!(i8_scalable_vec_zero.is_const());
49    /// ```
50    pub fn is_const(self) -> bool {
51        self.scalable_vec_value.is_const()
52    }
53
54    pub fn print_to_stderr(self) {
55        self.scalable_vec_value.print_to_stderr()
56    }
57
58    /// Gets the name of a `ScalableVectorValue`. If the value is a constant, this will
59    /// return an empty string.
60    pub fn get_name(&self) -> &CStr {
61        self.scalable_vec_value.get_name()
62    }
63
64    /// Set name of the `ScalableVectorValue`.
65    pub fn set_name(&self, name: &str) {
66        self.scalable_vec_value.set_name(name)
67    }
68
69    pub fn get_type(self) -> ScalableVectorType<'ctx> {
70        unsafe { ScalableVectorType::new(self.scalable_vec_value.get_type()) }
71    }
72
73    pub fn is_null(self) -> bool {
74        self.scalable_vec_value.is_null()
75    }
76
77    pub fn is_undef(self) -> bool {
78        self.scalable_vec_value.is_undef()
79    }
80
81    pub fn as_instruction(self) -> Option<InstructionValue<'ctx>> {
82        self.scalable_vec_value.as_instruction()
83    }
84
85    pub fn const_extract_element(self, index: IntValue<'ctx>) -> BasicValueEnum<'ctx> {
86        unsafe { BasicValueEnum::new(LLVMConstExtractElement(self.as_value_ref(), index.as_value_ref())) }
87    }
88
89    // SubTypes: value should really be T in self: ScalableVectorValue<T> I think
90    pub fn const_insert_element<BV: BasicValue<'ctx>>(self, index: IntValue<'ctx>, value: BV) -> BasicValueEnum<'ctx> {
91        unsafe {
92            BasicValueEnum::new(LLVMConstInsertElement(
93                self.as_value_ref(),
94                value.as_value_ref(),
95                index.as_value_ref(),
96            ))
97        }
98    }
99
100    pub fn replace_all_uses_with(self, other: ScalableVectorValue<'ctx>) {
101        self.scalable_vec_value.replace_all_uses_with(other.as_value_ref())
102    }
103
104    // TODOC: Value seems to be zero initialized if index out of bounds
105    // SubType: ScalableVectorValue<BV> -> BV
106    #[allow(deprecated)]
107    pub fn get_element_as_constant(self, index: u32) -> BasicValueEnum<'ctx> {
108        unsafe { BasicValueEnum::new(LLVMGetElementAsConstant(self.as_value_ref(), index)) }
109    }
110
111    // SubTypes: self can only be ScalableVectoValue<IntValue<bool>>
112    #[llvm_versions(..=16)]
113    pub fn const_select<BV: BasicValue<'ctx>>(self, then: BV, else_: BV) -> BasicValueEnum<'ctx> {
114        unsafe {
115            BasicValueEnum::new(LLVMConstSelect(
116                self.as_value_ref(),
117                then.as_value_ref(),
118                else_.as_value_ref(),
119            ))
120        }
121    }
122
123    // SubTypes: <V: ScalableVectorValue<T, Const>> self: V, right: V, mask: V -> V
124    pub fn const_shuffle_vector(
125        self,
126        right: ScalableVectorValue<'ctx>,
127        mask: ScalableVectorValue<'ctx>,
128    ) -> ScalableVectorValue<'ctx> {
129        unsafe {
130            ScalableVectorValue::new(LLVMConstShuffleVector(
131                self.as_value_ref(),
132                right.as_value_ref(),
133                mask.as_value_ref(),
134            ))
135        }
136    }
137}
138
139unsafe impl AsValueRef for ScalableVectorValue<'_> {
140    fn as_value_ref(&self) -> LLVMValueRef {
141        self.scalable_vec_value.value
142    }
143}
144
145impl Display for ScalableVectorValue<'_> {
146    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147        write!(f, "{}", self.print_to_string())
148    }
149}