From 0958c8f4cad247204ed7d9f9723f273ef81074f1 Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Mon, 14 Feb 2022 14:01:19 -0500 Subject: [PATCH] llvm: migrate to new parameter-bearing uwtable attr In https://reviews.llvm.org/D114543 the uwtable attribute gained a flag so that we can ask for sync uwtables instead of async, as the former are much cheaper. The default is async, so that's what I've done here, but I left a TODO that we might be able to do better. While in here I went ahead and dropped support for removing uwtable attributes in rustc: we never did it, so I didn't write the extra C++ bridge code to make it work. Maybe I should have done the same thing with the `sync|async` parameter but we'll see. --- compiler/rustc_codegen_llvm/src/allocator.rs | 4 ++-- compiler/rustc_codegen_llvm/src/attributes.rs | 9 ++++++--- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/mod.rs | 4 ++++ compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 11 +++++++++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 30d91b41a8e8b..7680d4fd233be 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -64,7 +64,7 @@ pub(crate) unsafe fn codegen( llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } if tcx.sess.must_emit_unwind_tables() { - attributes::emit_uwtable(llfn, true); + attributes::emit_uwtable(llfn); } let callee = kind.fn_name(method.name); @@ -111,7 +111,7 @@ pub(crate) unsafe fn codegen( llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); } if tcx.sess.must_emit_unwind_tables() { - attributes::emit_uwtable(llfn, true); + attributes::emit_uwtable(llfn); } let kind = if has_alloc_error_handler { AllocatorKind::Global } else { AllocatorKind::Default }; diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 2472789601e70..30a52d6bd67fc 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -59,8 +59,11 @@ pub fn sanitize<'ll>(cx: &CodegenCx<'ll, '_>, no_sanitize: SanitizerSet, llfn: & /// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function. #[inline] -pub fn emit_uwtable(val: &Value, emit: bool) { - Attribute::UWTable.toggle_llfn(Function, val, emit); +pub fn emit_uwtable(val: &Value) { + // NOTE: We should determine if we even need async unwind tables, as they + // take have more overhead and if we can use sync unwind tables we + // probably should. + llvm::EmitUWTableAttr(val, true); } /// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue. @@ -275,7 +278,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( // You can also find more info on why Windows always requires uwtables here: // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078 if cx.sess().must_emit_unwind_tables() { - attributes::emit_uwtable(llfn, true); + attributes::emit_uwtable(llfn); } if cx.sess().opts.debugging_opts.profile_sample_use.is_some() { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 4f62c68556841..90d4367a280a4 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1182,6 +1182,7 @@ extern "C" { pub fn LLVMRustAddByValAttr(Fn: &Value, index: c_uint, ty: &Type); pub fn LLVMRustAddStructRetAttr(Fn: &Value, index: c_uint, ty: &Type); pub fn LLVMRustAddFunctionAttribute(Fn: &Value, index: c_uint, attr: Attribute); + pub fn LLVMRustEmitUWTableAttr(Fn: &Value, async_: bool); pub fn LLVMRustAddFunctionAttrStringValue( Fn: &Value, index: c_uint, diff --git a/compiler/rustc_codegen_llvm/src/llvm/mod.rs b/compiler/rustc_codegen_llvm/src/llvm/mod.rs index a1117a11fc7ce..8586b0466c8d0 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/mod.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/mod.rs @@ -31,6 +31,10 @@ impl LLVMRustResult { } } +pub fn EmitUWTableAttr(llfn: &Value, async_: bool) { + unsafe { LLVMRustEmitUWTableAttr(llfn, async_) } +} + pub fn AddFunctionAttrStringValue(llfn: &Value, idx: AttributePlace, attr: &CStr, value: &CStr) { unsafe { LLVMRustAddFunctionAttrStringValue(llfn, idx.as_uint(), attr.as_ptr(), value.as_ptr()) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index fb9c5e6a527a7..2333319950651 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -334,6 +334,17 @@ extern "C" void LLVMRustAddStructRetAttr(LLVMValueRef Fn, unsigned Index, AddAttribute(F, Index, Attr); } +extern "C" void LLVMRustEmitUWTableAttr(LLVMValueRef Fn, bool Async) { + Function *F = unwrap(Fn); +#if LLVM_VERSION_LT(15, 0) + Attribute Attr = Attribute::get(F->getContext(), Attribute::UWTable); +#else + Attribute Attr = Attribute::getWithUWTableKind( + F->getContext(), Async ? UWTableKind::Async : UWTableKind::Sync); +#endif + AddAttribute(F, AttributeList::AttrIndex::FunctionIndex, Attr); +} + extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn, unsigned Index, const char *Name,