Auto merge of #118705 - WaffleLapkin:codegen-atomic-exhange-untuple, r=cjgillot
Change `rustc_codegen_ssa`'s `atomic_cmpxchg` interface to return a pair of values Doesn't change much, but a little nicer that way.
This commit is contained in:
commit
ddca5343f2
@ -1296,7 +1296,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Atomic Operations
|
// Atomic Operations
|
||||||
fn atomic_cmpxchg(&mut self, dst: RValue<'gcc>, cmp: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering, failure_order: AtomicOrdering, weak: bool) -> RValue<'gcc> {
|
fn atomic_cmpxchg(&mut self, dst: RValue<'gcc>, cmp: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering, failure_order: AtomicOrdering, weak: bool) -> (RValue<'gcc>, RValue<'gcc>) {
|
||||||
let expected = self.current_func().new_local(None, cmp.get_type(), "expected");
|
let expected = self.current_func().new_local(None, cmp.get_type(), "expected");
|
||||||
self.llbb().add_assignment(None, expected, cmp);
|
self.llbb().add_assignment(None, expected, cmp);
|
||||||
// NOTE: gcc doesn't support a failure memory model that is stronger than the success
|
// NOTE: gcc doesn't support a failure memory model that is stronger than the success
|
||||||
@ -1310,20 +1310,12 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
};
|
};
|
||||||
let success = self.compare_exchange(dst, expected, src, order, failure_order, weak);
|
let success = self.compare_exchange(dst, expected, src, order, failure_order, weak);
|
||||||
|
|
||||||
let pair_type = self.cx.type_struct(&[src.get_type(), self.bool_type], false);
|
// NOTE: since success contains the call to the intrinsic, it must be added to the basic block before
|
||||||
let result = self.current_func().new_local(None, pair_type, "atomic_cmpxchg_result");
|
|
||||||
let align = Align::from_bits(64).expect("align"); // TODO(antoyo): use good align.
|
|
||||||
|
|
||||||
let value_type = result.to_rvalue().get_type();
|
|
||||||
if let Some(struct_type) = value_type.is_struct() {
|
|
||||||
self.store(success, result.access_field(None, struct_type.get_field(1)).get_address(None), align);
|
|
||||||
// NOTE: since success contains the call to the intrinsic, it must be stored before
|
|
||||||
// expected so that we store expected after the call.
|
// expected so that we store expected after the call.
|
||||||
self.store(expected.to_rvalue(), result.access_field(None, struct_type.get_field(0)).get_address(None), align);
|
let success_var = self.current_func().new_local(None, self.bool_type, "success");
|
||||||
}
|
self.llbb().add_assignment(None, success_var, success);
|
||||||
// TODO(antoyo): handle when value is not a struct.
|
|
||||||
|
|
||||||
result.to_rvalue()
|
(expected.to_rvalue(), success_var.to_rvalue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn atomic_rmw(&mut self, op: AtomicRmwBinOp, dst: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering) -> RValue<'gcc> {
|
fn atomic_rmw(&mut self, op: AtomicRmwBinOp, dst: RValue<'gcc>, src: RValue<'gcc>, order: AtomicOrdering) -> RValue<'gcc> {
|
||||||
|
@ -1072,7 +1072,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
order: rustc_codegen_ssa::common::AtomicOrdering,
|
order: rustc_codegen_ssa::common::AtomicOrdering,
|
||||||
failure_order: rustc_codegen_ssa::common::AtomicOrdering,
|
failure_order: rustc_codegen_ssa::common::AtomicOrdering,
|
||||||
weak: bool,
|
weak: bool,
|
||||||
) -> &'ll Value {
|
) -> (&'ll Value, &'ll Value) {
|
||||||
let weak = if weak { llvm::True } else { llvm::False };
|
let weak = if weak { llvm::True } else { llvm::False };
|
||||||
unsafe {
|
unsafe {
|
||||||
let value = llvm::LLVMBuildAtomicCmpXchg(
|
let value = llvm::LLVMBuildAtomicCmpXchg(
|
||||||
@ -1085,7 +1085,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||||||
llvm::False, // SingleThreaded
|
llvm::False, // SingleThreaded
|
||||||
);
|
);
|
||||||
llvm::LLVMSetWeak(value, weak);
|
llvm::LLVMSetWeak(value, weak);
|
||||||
value
|
let val = self.extract_value(value, 0);
|
||||||
|
let success = self.extract_value(value, 1);
|
||||||
|
(val, success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn atomic_rmw(
|
fn atomic_rmw(
|
||||||
|
@ -335,7 +335,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
cmp = bx.ptrtoint(cmp, bx.type_isize());
|
cmp = bx.ptrtoint(cmp, bx.type_isize());
|
||||||
src = bx.ptrtoint(src, bx.type_isize());
|
src = bx.ptrtoint(src, bx.type_isize());
|
||||||
}
|
}
|
||||||
let pair = bx.atomic_cmpxchg(
|
let (val, success) = bx.atomic_cmpxchg(
|
||||||
dst,
|
dst,
|
||||||
cmp,
|
cmp,
|
||||||
src,
|
src,
|
||||||
@ -343,8 +343,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
parse_ordering(bx, failure),
|
parse_ordering(bx, failure),
|
||||||
weak,
|
weak,
|
||||||
);
|
);
|
||||||
let val = bx.extract_value(pair, 0);
|
|
||||||
let success = bx.extract_value(pair, 1);
|
|
||||||
let val = bx.from_immediate(val);
|
let val = bx.from_immediate(val);
|
||||||
let success = bx.from_immediate(success);
|
let success = bx.from_immediate(success);
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||||||
order: AtomicOrdering,
|
order: AtomicOrdering,
|
||||||
failure_order: AtomicOrdering,
|
failure_order: AtomicOrdering,
|
||||||
weak: bool,
|
weak: bool,
|
||||||
) -> Self::Value;
|
) -> (Self::Value, Self::Value);
|
||||||
fn atomic_rmw(
|
fn atomic_rmw(
|
||||||
&mut self,
|
&mut self,
|
||||||
op: AtomicRmwBinOp,
|
op: AtomicRmwBinOp,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user