Skip to content

Commit 6a7b508

Browse files
committed
Added wrappers for LLVMIntPredicate & LLVMRealPredicate
1 parent 4984271 commit 6a7b508

File tree

5 files changed

+91
-13
lines changed

5 files changed

+91
-13
lines changed

src/basic_block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ impl BasicBlock {
110110
Some(InstructionValue::new(value))
111111
}
112112

113-
// REVIEW: Potentially unsafe if parent was deleted
114113
// SubTypes: Don't need to call get_parent for a BasicBlock<HasParent>
115114
pub fn remove_from_function(&self) {
116-
if let Some(_) = self.get_parent() {
115+
// This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
116+
if self.get_parent().is_some() {
117117
unsafe {
118118
LLVMRemoveBasicBlockFromParent(self.basic_block)
119119
}

src/builder.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use either::Either;
22
use llvm_sys::core::{LLVMBuildAdd, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildArrayMalloc, LLVMBuildBr, LLVMBuildCall, LLVMBuildCast, LLVMBuildCondBr, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFCmp, LLVMBuildFDiv, LLVMBuildFence, LLVMBuildFMul, LLVMBuildFNeg, LLVMBuildFree, LLVMBuildFSub, LLVMBuildGEP, LLVMBuildICmp, LLVMBuildInsertValue, LLVMBuildIsNotNull, LLVMBuildIsNull, LLVMBuildLoad, LLVMBuildMalloc, LLVMBuildMul, LLVMBuildNeg, LLVMBuildNot, LLVMBuildOr, LLVMBuildPhi, LLVMBuildPointerCast, LLVMBuildRet, LLVMBuildRetVoid, LLVMBuildStore, LLVMBuildSub, LLVMBuildUDiv, LLVMBuildUnreachable, LLVMBuildXor, LLVMDisposeBuilder, LLVMGetElementType, LLVMGetInsertBlock, LLVMGetReturnType, LLVMGetTypeKind, LLVMInsertIntoBuilder, LLVMPositionBuilderAtEnd, LLVMTypeOf, LLVMSetTailCall, LLVMBuildExtractElement, LLVMBuildInsertElement, LLVMBuildIntToPtr, LLVMBuildPtrToInt, LLVMInsertIntoBuilderWithName, LLVMClearInsertionPosition, LLVMCreateBuilder, LLVMPositionBuilder, LLVMPositionBuilderBefore, LLVMBuildAggregateRet, LLVMBuildStructGEP, LLVMBuildInBoundsGEP, LLVMBuildPtrDiff, LLVMBuildNSWAdd, LLVMBuildNUWAdd, LLVMBuildNSWSub, LLVMBuildNUWSub, LLVMBuildNSWMul, LLVMBuildNUWMul, LLVMBuildSDiv, LLVMBuildSRem, LLVMBuildURem, LLVMBuildFRem, LLVMBuildNSWNeg, LLVMBuildNUWNeg, LLVMBuildFPToUI, LLVMBuildFPToSI, LLVMBuildSIToFP, LLVMBuildUIToFP, LLVMBuildFPTrunc, LLVMBuildFPExt, LLVMBuildIntCast, LLVMBuildFPCast, LLVMBuildSExtOrBitCast, LLVMBuildZExtOrBitCast, LLVMBuildTruncOrBitCast, LLVMBuildSwitch, LLVMAddCase, LLVMBuildShl, LLVMBuildAShr, LLVMBuildLShr};
33
use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef};
4-
use llvm_sys::{LLVMOpcode, LLVMIntPredicate, LLVMTypeKind, LLVMRealPredicate, LLVMAtomicOrdering};
4+
use llvm_sys::{LLVMOpcode, LLVMTypeKind, LLVMAtomicOrdering};
55

6+
use {IntPredicate, FloatPredicate};
67
use basic_block::BasicBlock;
78
use values::{AggregateValue, AsValueRef, BasicValue, BasicValueEnum, PhiValue, FunctionValue, FloatValue, IntValue, PointerValue, VectorValue, InstructionValue};
89
use types::{AsTypeRef, BasicType, PointerType, IntType, FloatType};
@@ -740,23 +741,23 @@ impl Builder {
740741

741742
// SubType: <I>(&self, op, lhs: &IntValue<I>, rhs: &IntValue<I>, name) -> IntValue<bool> { ?
742743
// FIXME: Don't take llvm-sys op enum
743-
pub fn build_int_compare(&self, op: LLVMIntPredicate, lhs: &IntValue, rhs: &IntValue, name: &str) -> IntValue {
744+
pub fn build_int_compare(&self, op: &IntPredicate, lhs: &IntValue, rhs: &IntValue, name: &str) -> IntValue {
744745
let c_string = CString::new(name).expect("Conversion to CString failed unexpectedly");
745746

746747
let value = unsafe {
747-
LLVMBuildICmp(self.builder, op, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
748+
LLVMBuildICmp(self.builder, op.as_llvm_predicate(), lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
748749
};
749750

750751
IntValue::new(value)
751752
}
752753

753754
// SubType: <F>(&self, op, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name) -> IntValue<bool> { ?
754755
// FIXME: Don't take llvm-sys op enum
755-
pub fn build_float_compare(&self, op: LLVMRealPredicate, lhs: &FloatValue, rhs: &FloatValue, name: &str) -> IntValue {
756+
pub fn build_float_compare(&self, op: &FloatPredicate, lhs: &FloatValue, rhs: &FloatValue, name: &str) -> IntValue {
756757
let c_string = CString::new(name).expect("Conversion to CString failed unexpectedly");
757758

758759
let value = unsafe {
759-
LLVMBuildFCmp(self.builder, op, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
760+
LLVMBuildFCmp(self.builder, op.as_llvm_predicate(), lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
760761
};
761762

762763
IntValue::new(value)

src/lib.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ pub mod targets;
1717
pub mod types;
1818
pub mod values;
1919

20+
use llvm_sys::{LLVMIntPredicate, LLVMRealPredicate};
21+
2022
// TODO: Probably move into error handling module
2123
pub fn enable_llvm_pretty_stack_trace() {
2224
// use llvm_sys::error_handling::LLVMEnablePrettyStackTrace; // v3.8
@@ -47,6 +49,81 @@ pub fn shutdown_llvm() {
4749
}
4850
}
4951

52+
// REVIEW: Maybe this belongs in some sort of prelude?
53+
pub enum IntPredicate {
54+
EQ,
55+
NE,
56+
UGT,
57+
UGE,
58+
ULT,
59+
ULE,
60+
SGT,
61+
SGE,
62+
SLT,
63+
SLE,
64+
}
65+
66+
impl IntPredicate {
67+
pub(crate) fn as_llvm_predicate(&self) -> LLVMIntPredicate {
68+
match *self {
69+
IntPredicate::EQ => LLVMIntPredicate::LLVMIntEQ,
70+
IntPredicate::NE => LLVMIntPredicate::LLVMIntNE,
71+
IntPredicate::UGT => LLVMIntPredicate::LLVMIntUGT,
72+
IntPredicate::UGE => LLVMIntPredicate::LLVMIntUGE,
73+
IntPredicate::ULT => LLVMIntPredicate::LLVMIntULT,
74+
IntPredicate::ULE => LLVMIntPredicate::LLVMIntULE,
75+
IntPredicate::SGT => LLVMIntPredicate::LLVMIntSGT,
76+
IntPredicate::SGE => LLVMIntPredicate::LLVMIntSGE,
77+
IntPredicate::SLT => LLVMIntPredicate::LLVMIntSLT,
78+
IntPredicate::SLE => LLVMIntPredicate::LLVMIntSLE,
79+
}
80+
}
81+
}
82+
83+
// REVIEW: Maybe this belongs in some sort of prelude?
84+
pub enum FloatPredicate {
85+
PredicateFalse,
86+
OEQ,
87+
OGT,
88+
OGE,
89+
OLT,
90+
OLE,
91+
ONE,
92+
ORD,
93+
UNO,
94+
UEQ,
95+
UGT,
96+
UGE,
97+
ULT,
98+
ULE,
99+
UNE,
100+
PredicateTrue,
101+
}
102+
103+
impl FloatPredicate {
104+
pub(crate) fn as_llvm_predicate(&self) -> LLVMRealPredicate {
105+
match *self {
106+
FloatPredicate::PredicateFalse => LLVMRealPredicate::LLVMRealPredicateFalse,
107+
FloatPredicate::OEQ => LLVMRealPredicate::LLVMRealOEQ,
108+
FloatPredicate::OGT => LLVMRealPredicate::LLVMRealOGT,
109+
FloatPredicate::OGE => LLVMRealPredicate::LLVMRealOGE,
110+
FloatPredicate::OLT => LLVMRealPredicate::LLVMRealOLT,
111+
FloatPredicate::OLE => LLVMRealPredicate::LLVMRealOLE,
112+
FloatPredicate::ONE => LLVMRealPredicate::LLVMRealONE,
113+
FloatPredicate::ORD => LLVMRealPredicate::LLVMRealORD,
114+
FloatPredicate::UNO => LLVMRealPredicate::LLVMRealUNO,
115+
FloatPredicate::UEQ => LLVMRealPredicate::LLVMRealUEQ,
116+
FloatPredicate::UGT => LLVMRealPredicate::LLVMRealUGT,
117+
FloatPredicate::UGE => LLVMRealPredicate::LLVMRealUGE,
118+
FloatPredicate::ULT => LLVMRealPredicate::LLVMRealULT,
119+
FloatPredicate::ULE => LLVMRealPredicate::LLVMRealULE,
120+
FloatPredicate::UNE => LLVMRealPredicate::LLVMRealUNE,
121+
FloatPredicate::PredicateTrue => LLVMRealPredicate::LLVMRealPredicateTrue,
122+
}
123+
}
124+
}
125+
126+
50127
// Misc Notes
51128
// Always pass a c_string.as_ptr() call into the function call directly and never
52129
// before hand. Seems to make a huge difference (stuff stops working) otherwise

src/values/float_value.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use llvm_sys::core::{LLVMConstFNeg, LLVMConstFAdd, LLVMConstFSub, LLVMConstFMul, LLVMConstFDiv, LLVMConstFRem, LLVMConstFPCast, LLVMConstFPToUI, LLVMConstFPToSI, LLVMConstFPTrunc, LLVMConstFPExt, LLVMConstFCmp};
22
use llvm_sys::prelude::LLVMValueRef;
3-
use llvm_sys::LLVMRealPredicate;
43

54
use std::ffi::CStr;
65

6+
use FloatPredicate;
77
use types::{AsTypeRef, FloatType, IntType};
88
use values::traits::AsValueRef;
99
use values::{InstructionValue, IntValue, Value, MetadataValue};
@@ -159,9 +159,9 @@ impl FloatValue {
159159
}
160160

161161
// FIXME: Don't take llvm-sys op enum
162-
pub fn const_float_compare(&self, op: LLVMRealPredicate, rhs: &FloatValue) -> IntValue {
162+
pub fn const_float_compare(&self, op: &FloatPredicate, rhs: &FloatValue) -> IntValue {
163163
let value = unsafe {
164-
LLVMConstFCmp(op, self.as_value_ref(), rhs.as_value_ref())
164+
LLVMConstFCmp(op.as_llvm_predicate(), self.as_value_ref(), rhs.as_value_ref())
165165
};
166166

167167
IntValue::new(value)

src/values/int_value.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use llvm_sys::core::{LLVMConstNot, LLVMConstNeg, LLVMConstNSWNeg, LLVMConstNUWNeg, LLVMConstAdd, LLVMConstNSWAdd, LLVMConstNUWAdd, LLVMConstSub, LLVMConstNSWSub, LLVMConstNUWSub, LLVMConstMul, LLVMConstNSWMul, LLVMConstNUWMul, LLVMConstUDiv, LLVMConstSDiv, LLVMConstSRem, LLVMConstURem, LLVMConstIntCast, LLVMConstXor, LLVMConstOr, LLVMConstAnd, LLVMConstExactSDiv, LLVMConstShl, LLVMConstLShr, LLVMConstAShr, LLVMConstUIToFP, LLVMConstSIToFP, LLVMConstIntToPtr, LLVMConstTrunc, LLVMConstSExt, LLVMConstZExt, LLVMConstTruncOrBitCast, LLVMConstSExtOrBitCast, LLVMConstZExtOrBitCast, LLVMConstBitCast, LLVMConstICmp};
22
use llvm_sys::prelude::LLVMValueRef;
3-
use llvm_sys::LLVMIntPredicate;
43

54
use std::ffi::CStr;
65

6+
use IntPredicate;
77
use types::{AsTypeRef, FloatType, PointerType, IntType};
88
use values::traits::AsValueRef;
99
use values::{FloatValue, InstructionValue, PointerValue, Value, MetadataValue};
@@ -358,9 +358,9 @@ impl IntValue {
358358
}
359359

360360
// FIXME: Don't take llvm-sys op enum
361-
pub fn const_int_compare(&self, op: LLVMIntPredicate, rhs: &IntValue) -> IntValue {
361+
pub fn const_int_compare(&self, op: &IntPredicate, rhs: &IntValue) -> IntValue {
362362
let value = unsafe {
363-
LLVMConstICmp(op, self.as_value_ref(), rhs.as_value_ref())
363+
LLVMConstICmp(op.as_llvm_predicate(), self.as_value_ref(), rhs.as_value_ref())
364364
};
365365

366366
IntValue::new(value)

0 commit comments

Comments
 (0)