Skip to content

Commit 05ba1a5

Browse files
authored
Merge pull request rust-lang#169 from wasmerio/feature/use-list-bb
Add BasicBlock::get_first_use().
2 parents 42f3bb8 + d81f713 commit 05ba1a5

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

src/basic_block.rs

+38-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
//! A `BasicBlock` is a container of instructions.
22
3-
use llvm_sys::core::{LLVMGetBasicBlockParent, LLVMGetBasicBlockTerminator, LLVMGetNextBasicBlock, LLVMIsABasicBlock, LLVMIsConstant, LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString, LLVMTypeOf, LLVMDeleteBasicBlock, LLVMGetPreviousBasicBlock, LLVMRemoveBasicBlockFromParent, LLVMGetFirstInstruction, LLVMGetLastInstruction, LLVMGetTypeContext, LLVMBasicBlockAsValue, LLVMReplaceAllUsesWith};
3+
use llvm_sys::core::{LLVMGetBasicBlockParent, LLVMGetBasicBlockTerminator, LLVMGetNextBasicBlock, LLVMIsABasicBlock, LLVMIsConstant, LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString, LLVMTypeOf, LLVMDeleteBasicBlock, LLVMGetPreviousBasicBlock, LLVMRemoveBasicBlockFromParent, LLVMGetFirstInstruction, LLVMGetLastInstruction, LLVMGetTypeContext, LLVMBasicBlockAsValue, LLVMReplaceAllUsesWith, LLVMGetFirstUse};
44
#[llvm_versions(3.9..=latest)]
55
use llvm_sys::core::LLVMGetBasicBlockName;
66
use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef};
77

88
use crate::context::ContextRef;
9-
use crate::values::{FunctionValue, InstructionValue};
9+
use crate::values::{BasicValueUse, FunctionValue, InstructionValue};
1010

1111
use std::fmt;
1212
use std::ffi::CStr;
@@ -485,6 +485,42 @@ impl<'ctx> BasicBlock<'ctx> {
485485
}
486486
}
487487
}
488+
489+
/// Gets the first use of this `BasicBlock` if any.
490+
///
491+
/// The following example,
492+
///
493+
/// ```no_run
494+
/// use inkwell::AddressSpace;
495+
/// use inkwell::context::Context;
496+
/// use inkwell::values::BasicValue;
497+
///
498+
/// let context = Context::create();
499+
/// let module = context.create_module("ivs");
500+
/// let builder = context.create_builder();
501+
/// let void_type = context.void_type();
502+
/// let fn_type = void_type.fn_type(&[], false);
503+
/// let fn_val = module.add_function("my_fn", fn_type, None);
504+
/// let entry = context.append_basic_block(fn_val, "entry");
505+
/// let bb1 = context.append_basic_block(fn_val, "bb1");
506+
/// let bb2 = context.append_basic_block(fn_val, "bb2");
507+
/// builder.position_at_end(entry);
508+
/// let branch_inst = builder.build_unconditional_branch(bb1);
509+
///
510+
/// assert!(bb2.get_first_use().is_none());
511+
/// assert!(bb1.get_first_use().is_some());
512+
/// ```
513+
pub fn get_first_use(&self) -> Option<BasicValueUse> {
514+
let use_ = unsafe {
515+
LLVMGetFirstUse(LLVMBasicBlockAsValue(self.basic_block))
516+
};
517+
518+
if use_.is_null() {
519+
return None;
520+
}
521+
522+
Some(BasicValueUse::new(use_))
523+
}
488524
}
489525

490526
impl fmt::Debug for BasicBlock<'_> {

src/values/basic_value_use.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<'ctx> BasicValueUse<'ctx> {
1818
BasicValueUse(use_, PhantomData)
1919
}
2020

21-
/// Gets the next use of an `InstructionValue` or `BasicValue` if any.
21+
/// Gets the next use of a `BasicBlock`, `InstructionValue` or `BasicValue` if any.
2222
///
2323
/// The following example,
2424
///

tests/all/test_basic_block.rs

+20
Original file line numberDiff line numberDiff line change
@@ -183,3 +183,23 @@ fn test_rauw() {
183183

184184
assert_eq!(branch_inst.get_operand(0).unwrap().right().unwrap(), bb2);
185185
}
186+
187+
#[test]
188+
fn test_get_first_use() {
189+
let context = Context::create();
190+
let module = context.create_module("ivs");
191+
let builder = context.create_builder();
192+
let void_type = context.void_type();
193+
let fn_type = void_type.fn_type(&[], false);
194+
let fn_val = module.add_function("my_fn", fn_type, None);
195+
let entry = context.append_basic_block(fn_val, "entry");
196+
let bb1 = context.append_basic_block(fn_val, "bb1");
197+
let bb2 = context.append_basic_block(fn_val, "bb2");
198+
builder.position_at_end(entry);
199+
let branch_inst = builder.build_unconditional_branch(bb1);
200+
201+
assert!(bb2.get_first_use().is_none());
202+
assert!(bb1.get_first_use().is_some());
203+
assert_eq!(bb1.get_first_use().unwrap().get_user(), branch_inst);
204+
assert!(bb1.get_first_use().unwrap().get_next_use().is_none());
205+
}

0 commit comments

Comments
 (0)