pub struct BasicValueUse<'ctx>(/* private fields */);
Expand description
A usage of a BasicValue
in another value.
Implementations§
source§impl<'ctx> BasicValueUse<'ctx>
impl<'ctx> BasicValueUse<'ctx>
sourcepub unsafe fn new(use_: LLVMUseRef) -> Self
pub unsafe fn new(use_: LLVMUseRef) -> Self
sourcepub fn get_next_use(self) -> Option<Self>
pub fn get_next_use(self) -> Option<Self>
Gets the next use of a BasicBlock
, InstructionValue
or BasicValue
if any.
The following example,
use inkwell::AddressSpace;
use inkwell::context::Context;
use inkwell::values::BasicValue;
let context = Context::create();
let module = context.create_module("ivs");
let builder = context.create_builder();
let void_type = context.void_type();
let f32_type = context.f32_type();
#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0")))]
let f32_ptr_type = f32_type.ptr_type(AddressSpace::default());
#[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0"))]
let f32_ptr_type = context.ptr_type(AddressSpace::default());
let fn_type = void_type.fn_type(&[f32_ptr_type.into()], false);
let function = module.add_function("take_f32_ptr", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
let arg1 = function.get_first_param().unwrap().into_pointer_value();
let f32_val = f32_type.const_float(std::f64::consts::PI);
let store_instruction = builder.build_store(arg1, f32_val).unwrap();
let free_instruction = builder.build_free(arg1).unwrap();
let return_instruction = builder.build_return(None).unwrap();
let arg1_first_use = arg1.get_first_use().unwrap();
assert!(arg1_first_use.get_next_use().is_some());
will generate LLVM IR roughly like (varying slightly across LLVM versions):
; ModuleID = 'ivs'
source_filename = "ivs"
define void @take_f32_ptr(float* %0) {
entry:
store float 0x400921FB60000000, float* %0
%1 = bitcast float* %0 to i8*
tail call void @free(i8* %1)
ret void
}
declare void @free(i8*)
which makes the arg1 (%0) uses clear:
- In the store instruction
- In the pointer bitcast
sourcepub fn get_user(self) -> AnyValueEnum<'ctx>
pub fn get_user(self) -> AnyValueEnum<'ctx>
Gets the user (an AnyValueEnum
) of this use.
use inkwell::AddressSpace;
use inkwell::context::Context;
use inkwell::values::BasicValue;
let context = Context::create();
let module = context.create_module("ivs");
let builder = context.create_builder();
let void_type = context.void_type();
let f32_type = context.f32_type();
#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0")))]
let f32_ptr_type = f32_type.ptr_type(AddressSpace::default());
#[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0"))]
let f32_ptr_type = context.ptr_type(AddressSpace::default());
let fn_type = void_type.fn_type(&[f32_ptr_type.into()], false);
let function = module.add_function("take_f32_ptr", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
let arg1 = function.get_first_param().unwrap().into_pointer_value();
let f32_val = f32_type.const_float(std::f64::consts::PI);
let store_instruction = builder.build_store(arg1, f32_val).unwrap();
let free_instruction = builder.build_free(arg1).unwrap();
let return_instruction = builder.build_return(None).unwrap();
let store_operand_use0 = store_instruction.get_operand_use(0).unwrap();
let store_operand_use1 = store_instruction.get_operand_use(1).unwrap();
assert_eq!(store_operand_use0.get_user(), store_instruction);
assert_eq!(store_operand_use1.get_user(), store_instruction);
sourcepub fn get_used_value(self) -> Either<BasicValueEnum<'ctx>, BasicBlock<'ctx>>
pub fn get_used_value(self) -> Either<BasicValueEnum<'ctx>, BasicBlock<'ctx>>
Gets the used value (a BasicValueEnum
or BasicBlock
) of this use.
use inkwell::AddressSpace;
use inkwell::context::Context;
use inkwell::values::BasicValue;
let context = Context::create();
let module = context.create_module("ivs");
let builder = context.create_builder();
let void_type = context.void_type();
let f32_type = context.f32_type();
#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0")))]
let f32_ptr_type = f32_type.ptr_type(AddressSpace::default());
#[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0"))]
let f32_ptr_type = context.ptr_type(AddressSpace::default());
let fn_type = void_type.fn_type(&[f32_ptr_type.into()], false);
let function = module.add_function("take_f32_ptr", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
let arg1 = function.get_first_param().unwrap().into_pointer_value();
let f32_val = f32_type.const_float(std::f64::consts::PI);
let store_instruction = builder.build_store(arg1, f32_val).unwrap();
let free_instruction = builder.build_free(arg1).unwrap();
let return_instruction = builder.build_return(None).unwrap();
let free_operand0 = free_instruction.get_operand(0).unwrap().left().unwrap();
let free_operand0_instruction = free_operand0.as_instruction_value().unwrap();
let bitcast_use_value = free_operand0_instruction
.get_first_use()
.unwrap()
.get_used_value()
.left()
.unwrap();
assert_eq!(bitcast_use_value, free_operand0);
Trait Implementations§
source§impl<'ctx> Clone for BasicValueUse<'ctx>
impl<'ctx> Clone for BasicValueUse<'ctx>
source§fn clone(&self) -> BasicValueUse<'ctx>
fn clone(&self) -> BasicValueUse<'ctx>
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl<'ctx> Debug for BasicValueUse<'ctx>
impl<'ctx> Debug for BasicValueUse<'ctx>
source§impl<'ctx> PartialEq for BasicValueUse<'ctx>
impl<'ctx> PartialEq for BasicValueUse<'ctx>
impl<'ctx> Copy for BasicValueUse<'ctx>
impl<'ctx> Eq for BasicValueUse<'ctx>
impl<'ctx> StructuralPartialEq for BasicValueUse<'ctx>
Auto Trait Implementations§
impl<'ctx> Freeze for BasicValueUse<'ctx>
impl<'ctx> RefUnwindSafe for BasicValueUse<'ctx>
impl<'ctx> !Send for BasicValueUse<'ctx>
impl<'ctx> !Sync for BasicValueUse<'ctx>
impl<'ctx> Unpin for BasicValueUse<'ctx>
impl<'ctx> UnwindSafe for BasicValueUse<'ctx>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
🔬This is a nightly-only experimental API. (
clone_to_uninit
)source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more