Skip to content

Commit 2527355

Browse files
committed
Get/set of volatile on atomicrmw and cmpxchg was added in LLVM 10.
1 parent fcf7742 commit 2527355

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/values/instruction_value.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use either::{Either, Either::{Left, Right}};
2-
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate, LLVMIsAAllocaInst, LLVMIsALoadInst, LLVMIsAStoreInst, LLVMGetMetadata, LLVMHasMetadata, LLVMSetMetadata};
2+
use llvm_sys::core::{LLVMGetAlignment, LLVMSetAlignment, LLVMGetInstructionOpcode, LLVMIsTailCall, LLVMGetPreviousInstruction, LLVMGetNextInstruction, LLVMGetInstructionParent, LLVMInstructionEraseFromParent, LLVMInstructionClone, LLVMSetVolatile, LLVMGetVolatile, LLVMGetNumOperands, LLVMGetOperand, LLVMGetOperandUse, LLVMSetOperand, LLVMValueAsBasicBlock, LLVMIsABasicBlock, LLVMGetICmpPredicate, LLVMGetFCmpPredicate, LLVMIsAAllocaInst, LLVMIsALoadInst, LLVMIsAStoreInst, LLVMGetMetadata, LLVMHasMetadata, LLVMSetMetadata, LLVMIsAAtomicRMWInst, LLVMIsAAtomicCmpXchgInst};
33
#[llvm_versions(3.8..=latest)]
44
use llvm_sys::core::{LLVMGetOrdering, LLVMSetOrdering};
55
#[llvm_versions(3.9..=latest)]
@@ -113,6 +113,12 @@ impl<'ctx> InstructionValue<'ctx> {
113113
fn is_a_alloca_inst(self) -> bool {
114114
!unsafe { LLVMIsAAllocaInst(self.as_value_ref()) }.is_null()
115115
}
116+
fn is_a_atomicrmw_inst(self) -> bool {
117+
!unsafe { LLVMIsAAtomicRMWInst(self.as_value_ref()) }.is_null()
118+
}
119+
fn is_a_cmpxchg_inst(self) -> bool {
120+
!unsafe { LLVMIsAAtomicCmpXchgInst(self.as_value_ref()) }.is_null()
121+
}
116122

117123
pub(crate) fn new(instruction_value: LLVMValueRef) -> Self {
118124
debug_assert!(!instruction_value.is_null());
@@ -203,25 +209,49 @@ impl<'ctx> InstructionValue<'ctx> {
203209

204210
// SubTypes: Only apply to memory access instructions
205211
/// Returns whether or not a memory access instruction is volatile.
212+
#[llvm_versions(3.6..=9.0)]
206213
pub fn get_volatile(self) -> Result<bool, &'static str> {
207214
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
208-
// does not export that functionality.
215+
// does not export that functionality until 10.0.
209216
if !self.is_a_load_inst() && !self.is_a_store_inst() {
210217
return Err("Value is not a load or store.");
211218
}
212219
Ok(unsafe { LLVMGetVolatile(self.as_value_ref()) } == 1)
213220
}
214221

222+
// SubTypes: Only apply to memory access instructions
223+
/// Returns whether or not a memory access instruction is volatile.
224+
#[llvm_versions(10.0..=latest)]
225+
pub fn get_volatile(self) -> Result<bool, &'static str> {
226+
if !self.is_a_load_inst() && !self.is_a_store_inst() &&
227+
!self.is_a_atomicrmw_inst() && !self.is_a_cmpxchg_inst() {
228+
return Err("Value is not a load, store, atomicrmw or cmpxchg.");
229+
}
230+
Ok(unsafe { LLVMGetVolatile(self.as_value_ref()) } == 1)
231+
}
232+
215233
// SubTypes: Only apply to memory access instructions
216234
/// Sets whether or not a memory access instruction is volatile.
235+
#[llvm_versions(3.6..=9.0)]
217236
pub fn set_volatile(self, volatile: bool) -> Result<(), &'static str> {
218237
// Although cmpxchg and atomicrmw can have volatile, LLVM's C API
219-
// does not export that functionality.
238+
// does not export that functionality until 10.0.
220239
if !self.is_a_load_inst() && !self.is_a_store_inst() {
221240
return Err("Value is not a load or store.");
222241
}
223242
Ok(unsafe { LLVMSetVolatile(self.as_value_ref(), volatile as i32) })
224243
}
244+
245+
// SubTypes: Only apply to memory access instructions
246+
/// Sets whether or not a memory access instruction is volatile.
247+
#[llvm_versions(10.0..=latest)]
248+
pub fn set_volatile(self, volatile: bool) -> Result<(), &'static str> {
249+
if !self.is_a_load_inst() && !self.is_a_store_inst() &&
250+
!self.is_a_atomicrmw_inst() && !self.is_a_cmpxchg_inst() {
251+
return Err("Value is not a load, store, atomicrmw or cmpxchg.");
252+
}
253+
Ok(unsafe { LLVMSetVolatile(self.as_value_ref(), volatile as i32) })
254+
}
225255

226256
// SubTypes: Only apply to memory access and alloca instructions
227257
/// Returns alignment on a memory access instruction or alloca.

0 commit comments

Comments
 (0)