diff options
Diffstat (limited to 'library/stdarch/crates/assert-instr-macro/src/lib.rs')
| -rw-r--r-- | library/stdarch/crates/assert-instr-macro/src/lib.rs | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/library/stdarch/crates/assert-instr-macro/src/lib.rs b/library/stdarch/crates/assert-instr-macro/src/lib.rs index f40f81fc033..702cd59c57f 100644 --- a/library/stdarch/crates/assert-instr-macro/src/lib.rs +++ b/library/stdarch/crates/assert-instr-macro/src/lib.rs @@ -48,14 +48,15 @@ pub fn assert_instr( use quote::ToTokens; let instr_str = instr .clone() - .into_tokens() + .into_token_stream() .to_string() .replace('.', "_") .replace(|c: char| c.is_whitespace(), ""); - let assert_name = syn::Ident::from( - &format!("assert_{}_{}", name.as_ref(), instr_str)[..], + let assert_name = syn::Ident::new( + &format!("assert_{}_{}", name, instr_str), + name.span(), ); - let shim_name = syn::Ident::from(format!("{}_shim", name.as_ref())); + let shim_name = syn::Ident::new(&format!("{}_shim", name), name.span()); let mut inputs = Vec::new(); let mut input_vals = Vec::new(); let ret = &func.decl.output; @@ -64,7 +65,7 @@ pub fn assert_instr( syn::FnArg::Captured(ref c) => c, ref v => panic!( "arguments must not have patterns: `{:?}`", - v.clone().into_tokens() + v.clone().into_token_stream() ), }; let ident = match capture.pat { @@ -74,7 +75,7 @@ pub fn assert_instr( match invoc .args .iter() - .find(|a| a.0 == ident.as_ref()) + .find(|a| *ident == a.0) { Some(&(_, ref tts)) => { input_vals.push(quote! { #tts }); @@ -95,7 +96,7 @@ pub fn assert_instr( .expect("attr.path.segments.first() failed") .value() .ident - .as_ref() + .to_string() .starts_with("target") }) .collect::<Vec<_>>(); @@ -108,15 +109,27 @@ pub fn assert_instr( } else { syn::LitStr::new("C", proc_macro2::Span::call_site()) }; + let shim_name_str = format!("{}{}", shim_name, assert_name); let to_test = quote! { #attrs unsafe extern #abi fn #shim_name(#(#inputs),*) #ret { + // The compiler in optimized mode by default runs a pass called + // "mergefunc" where it'll merge functions that look identical. + // Turns out some intrinsics produce identical code and they're + // folded together, meaning that one just jumps to another. This + // messes up our inspection of the disassembly of this function and + // we're not a huge fan of that. + // + // To thwart this pass and prevent functions from being merged we + // generate some code that's hopefully very tight in terms of + // codegen but is otherwise unique to prevent code from being + // folded. + ::stdsimd_test::_DONT_DEDUP = #shim_name_str; #name(#(#input_vals),*) } }; - let tts: TokenStream = quote_spanned! { - proc_macro2::Span::call_site() => + let tts: TokenStream = quote! { #[test] #[allow(non_snake_case)] #maybe_ignore @@ -169,7 +182,7 @@ where T: Clone + IntoIterator, T::Item: quote::ToTokens, { - fn to_tokens(&self, tokens: &mut quote::Tokens) { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { for item in self.0.clone() { item.to_tokens(tokens); } |
