From 72ba66c4f7fa557a2802c59d897c02bae4ca1f6a Mon Sep 17 00:00:00 2001 From: fw Date: Thu, 11 Aug 2022 15:01:47 -0400 Subject: [PATCH] update atomic intrinsic usage for newer rustc --- c2rust-transpile/src/translator/atomics.rs | 107 +++++++------------- c2rust-transpile/src/translator/builtins.rs | 15 +-- 2 files changed, 43 insertions(+), 79 deletions(-) diff --git a/c2rust-transpile/src/translator/atomics.rs b/c2rust-transpile/src/translator/atomics.rs index 2327aab0e9..c5f3c11fbd 100644 --- a/c2rust-transpile/src/translator/atomics.rs +++ b/c2rust-transpile/src/translator/atomics.rs @@ -68,35 +68,31 @@ impl<'c> Translation<'c> { .transpose()?; let weak = weak_id.and_then(|x| self.convert_constant_bool(x)); - fn static_order(order: Option) -> T { + fn static_order(order: Option) -> Ordering { order.unwrap_or_else(|| { // We have to select which intrinsic to use at runtime unimplemented!("Dynamic memory consistency arguments are not yet supported"); }) } + fn order_name(order: Ordering) -> &'static str { + match order { + SeqCst => "seqcst", + AcqRel => "acqrel", + Acquire => "acquire", + Release => "release", + Relaxed => "relaxed", + _ => unreachable!("Did we not handle a case above??"), + } + } + match name { "__atomic_load" | "__atomic_load_n" => ptr.and_then(|ptr| { - use Ordering::*; - let intrinsic_name = match static_order(order) { - SeqCst => Some("atomic_load"), - AcqRel => None, - Acquire => Some("atomic_load_acq"), - Release => None, - Relaxed => Some("atomic_load_relaxed"), - _ => unreachable!("Did we not handle a case above??"), - } - .ok_or_else(|| { - format_translation_err!( - self.ast_context - .display_loc(&self.ast_context[order_id].loc), - "Invalid memory ordering for __atomic_load", - ) - })?; + let intrinsic_name = "atomic_load_".to_owned() + order_name(static_order(order)); self.use_feature("core_intrinsics"); - let atomic_load = mk().abs_path_expr(vec!["core", "intrinsics", intrinsic_name]); + let atomic_load = mk().abs_path_expr(vec!["core", "intrinsics", &intrinsic_name]); let call = mk().call_expr(atomic_load, vec![ptr]); if name == "__atomic_load" { let ret = val1.expect("__atomic_load should have a ret argument"); @@ -124,27 +120,13 @@ impl<'c> Translation<'c> { let val = val1.expect("__atomic_store must have a val argument"); ptr.and_then(|ptr| { val.and_then(|val| { - use Ordering::*; - let intrinsic_name = match static_order(order) { - SeqCst => Some("atomic_store"), - AcqRel => None, - Acquire => None, - Release => Some("atomic_store_rel"), - Relaxed => Some("atomic_store_relaxed"), - _ => unreachable!("Did we not handle a case above??"), - } - .ok_or_else(|| { - format_translation_err!( - self.ast_context - .display_loc(&self.ast_context[order_id].loc), - "Invalid memory ordering for __atomic_store", - ) - })?; + let intrinsic_name = + "atomic_store_".to_owned() + order_name(static_order(order)); self.use_feature("core_intrinsics"); let atomic_store = - mk().abs_path_expr(vec!["core", "intrinsics", intrinsic_name]); + mk().abs_path_expr(vec!["core", "intrinsics", &intrinsic_name]); let val = if name == "__atomic_store" { mk().unary_expr(UnOp::Deref(Default::default()), val) } else { @@ -164,27 +146,13 @@ impl<'c> Translation<'c> { let val = val1.expect("__atomic_store must have a val argument"); ptr.and_then(|ptr| { val.and_then(|val| { - use Ordering::*; - let intrinsic_name = match static_order(order) { - SeqCst => Some("atomic_xchg"), - AcqRel => Some("atomic_xchg_acqrel"), - Acquire => Some("atomic_xchg_acq"), - Release => Some("atomic_xchg_rel"), - Relaxed => Some("atomic_xchg_relaxed"), - _ => unreachable!("Did we not handle a case above??"), - } - .ok_or_else(|| { - format_translation_err!( - self.ast_context - .display_loc(&self.ast_context[order_id].loc), - "Invalid memory ordering for __atomic_exchange", - ) - })?; + let intrinsic_name = + "atomic_xchg_".to_owned() + order_name(static_order(order)); self.use_feature("core_intrinsics"); let fn_path = - mk().abs_path_expr(vec!["core", "intrinsics", intrinsic_name]); + mk().abs_path_expr(vec!["core", "intrinsics", &intrinsic_name]); let val = if name == "__atomic_exchange" { mk().unary_expr(UnOp::Deref(Default::default()), val) } else { @@ -226,22 +194,25 @@ impl<'c> Translation<'c> { ptr.and_then(|ptr| { expected.and_then(|expected| { desired.and_then(|desired| { - let weak = static_order(weak); + // If this expect fails, we have to select which intrinsic to use at runtime + let weak = weak.expect( + "Dynamic memory consistency arguments are not yet supported", + ); let order = static_order(order); let order_fail = static_order(order_fail); use Ordering::*; let intrinsic_name = (|| { Some(match (order, order_fail) { (_, Release | AcqRel) => return None, - (SeqCst, SeqCst) => "", - (SeqCst, Acquire) => "_failacq", - (SeqCst, Relaxed) => "_failrelaxed", - (AcqRel, Acquire) => "_acqrel", - (AcqRel, Relaxed) => "_acqrel_failrelaxed", - (Release, Relaxed) => "_rel", - (Acquire, Acquire) => "_acq", - (Acquire, Relaxed) => "_acq_failrelaxed", - (Relaxed, Relaxed) => "_relaxed", + (SeqCst, SeqCst) => "_seqcst_seqcst", + (SeqCst, Acquire) => "_seqcst_acquire", + (SeqCst, Relaxed) => "_seqcst_relaxed", + (AcqRel, Acquire) => "_acqrel_acquire", + (AcqRel, Relaxed) => "_acqrel_relaxed", + (Release, Relaxed) => "_release_relaxed", + (Acquire, Acquire) => "_acquire_acquire", + (Acquire, Relaxed) => "_acquire_relaxed", + (Relaxed, Relaxed) => "_relaxed_relaxed", (SeqCst | AcqRel | Release | Acquire | Relaxed, _) => { return None } @@ -320,16 +291,8 @@ impl<'c> Translation<'c> { "atomic_and" }; - use Ordering::*; - let intrinsic_suffix = match static_order(order) { - SeqCst => "", - AcqRel => "_acqrel", - Acquire => "_acq", - Release => "_rel", - Relaxed => "_relaxed", - _ => unreachable!("Unknown memory ordering"), - }; - let intrinsic_name = format!("{intrinsic_name}{intrinsic_suffix}"); + let intrinsic_suffix = order_name(static_order(order)); + let intrinsic_name = format!("{intrinsic_name}_{intrinsic_suffix}"); let fetch_first = name.starts_with("__atomic_fetch"); let val = val1.expect("__atomic arithmetic operations must have a val argument"); diff --git a/c2rust-transpile/src/translator/builtins.rs b/c2rust-transpile/src/translator/builtins.rs index 5262c5830f..938a2f64b5 100644 --- a/c2rust-transpile/src/translator/builtins.rs +++ b/c2rust-transpile/src/translator/builtins.rs @@ -493,18 +493,18 @@ impl<'c> Translation<'c> { | "__sync_nand_and_fetch_8" | "__sync_nand_and_fetch_16" => { let func_name = if builtin_name.contains("_add_") { - "atomic_xadd" + "atomic_xadd_seqcst" } else if builtin_name.contains("_sub_") { - "atomic_xsub" + "atomic_xsub_seqcst" } else if builtin_name.contains("_or_") { - "atomic_or" + "atomic_or_seqcst" } else if builtin_name.contains("_xor_") { - "atomic_xor" + "atomic_xor_seqcst" } else if builtin_name.contains("_nand_") { - "atomic_nand" + "atomic_nand_seqcst" } else { // We can't explicitly check for "_and_" since they all contain it - "atomic_and" + "atomic_and_seqcst" }; let arg0 = self.convert_expr(ctx.used(), args[0])?; @@ -520,7 +520,8 @@ impl<'c> Translation<'c> { "__sync_synchronize" => { self.use_feature("core_intrinsics"); - let atomic_func = mk().abs_path_expr(vec!["core", "intrinsics", "atomic_fence"]); + let atomic_func = + mk().abs_path_expr(vec!["core", "intrinsics", "atomic_fence_seqcst"]); let call_expr = mk().call_expr(atomic_func, vec![]); self.convert_side_effects_expr( ctx,