Skip to content

Commit 2d4ae52

Browse files
committed
Auto merge of #28358 - dotdash:nounwind, r=alexcrichton
This allows to skip the codegen for all the unneeded landing pads, reducing code size across the board by about 2-5%, depending on the crate. Compile times seem to be pretty unaffected though :-/
2 parents 664a459 + 3ef75d5 commit 2d4ae52

File tree

12 files changed

+45
-11
lines changed

12 files changed

+45
-11
lines changed

src/libcore/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#![feature(optin_builtin_traits)]
8080
#![feature(reflect)]
8181
#![feature(rustc_attrs)]
82+
#![feature(unwind_attributes)]
8283
#![cfg_attr(stage0, feature(simd))]
8384
#![cfg_attr(not(stage0), feature(repr_simd, platform_intrinsics))]
8485
#![feature(staged_api)]

src/libcore/panicking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
6262
#[allow(improper_ctypes)]
6363
extern {
6464
#[lang = "panic_fmt"]
65+
#[unwind]
6566
fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: u32) -> !;
6667
}
6768
let (file, line) = *file_line;

src/librustc_trans/trans/attributes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ pub fn emit_uwtable(val: ValueRef, emit: bool) {
5959

6060
/// Tell LLVM whether the function can or cannot unwind.
6161
#[inline]
62-
#[allow(dead_code)] // possibly useful function
6362
pub fn unwind(val: ValueRef, can_unwind: bool) {
6463
if can_unwind {
6564
unsafe {
@@ -118,6 +117,8 @@ pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[hir::Attribute], llfn: ValueRe
118117
}
119118
} else if attr.check_name("allocator") {
120119
llvm::Attribute::NoAlias.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
120+
} else if attr.check_name("unwind") {
121+
unwind(llfn, true);
121122
}
122123
}
123124
}

src/librustc_trans/trans/base.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -677,11 +677,8 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
677677
ccx.sess().bug("unexpected intrinsic in trans_external_path")
678678
}
679679
_ => {
680-
let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi,
681-
t, &name);
682680
let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
683-
attributes::from_fn_attrs(ccx, &attrs, llfn);
684-
llfn
681+
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name, &attrs)
685682
}
686683
}
687684
}
@@ -2418,9 +2415,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
24182415
let abi = ccx.tcx().map.get_foreign_abi(id);
24192416
let ty = ccx.tcx().node_id_to_type(ni.id);
24202417
let name = foreign::link_name(&*ni);
2421-
let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
2422-
attributes::from_fn_attrs(ccx, &ni.attrs, llfn);
2423-
llfn
2418+
foreign::register_foreign_item_fn(ccx, abi, ty, &name, &ni.attrs)
24242419
}
24252420
hir::ForeignItemStatic(..) => {
24262421
foreign::register_static(ccx, &*ni)

src/librustc_trans/trans/foreign.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,8 @@ pub fn get_extern_fn(ccx: &CrateContext,
187187
/// Registers a foreign function found in a library. Just adds a LLVM global.
188188
pub fn register_foreign_item_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
189189
abi: Abi, fty: Ty<'tcx>,
190-
name: &str) -> ValueRef {
190+
name: &str,
191+
attrs: &[hir::Attribute])-> ValueRef {
191192
debug!("register_foreign_item_fn(abi={:?}, \
192193
ty={:?}, \
193194
name={})",
@@ -210,7 +211,9 @@ pub fn register_foreign_item_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
210211
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
211212

212213
let llfn = get_extern_fn(ccx, &mut *ccx.externs().borrow_mut(), name, cc, llfn_ty, fty);
214+
attributes::unwind(llfn, false);
213215
add_argument_attributes(&tys, llfn);
216+
attributes::from_fn_attrs(ccx, attrs, llfn);
214217
llfn
215218
}
216219

@@ -489,8 +492,7 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &hir::ForeignMod) {
489492
"foreign fn's sty isn't a bare_fn_ty?")
490493
}
491494

492-
let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
493-
attributes::from_fn_attrs(ccx, &foreign_item.attrs, llfn);
495+
register_foreign_item_fn(ccx, abi, ty, &lname, &foreign_item.attrs);
494496
// Unlike for other items, we shouldn't call
495497
// `base::update_linkage` here. Foreign items have
496498
// special linkage requirements, which are handled

src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@
242242
#![feature(unique)]
243243
#![feature(unsafe_no_drop_flag, filling_drop)]
244244
#![feature(decode_utf16)]
245+
#![feature(unwind_attributes)]
245246
#![feature(vec_push_all)]
246247
#![feature(vec_resize)]
247248
#![feature(wrapping)]

src/libstd/sys/common/libunwind.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,12 @@ extern "C" {
124124
// iOS on armv7 uses SjLj exceptions and requires to link
125125
// against corresponding routine (..._SjLj_...)
126126
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
127+
#[unwind]
127128
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
128129
-> _Unwind_Reason_Code;
129130

130131
#[cfg(all(target_os = "ios", target_arch = "arm"))]
132+
#[unwind]
131133
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
132134
-> _Unwind_Reason_Code;
133135

src/libstd/sys/common/unwind/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
192192
#[cfg(not(test))]
193193
/// Entry point of panic from the libcore crate.
194194
#[lang = "panic_fmt"]
195+
#[unwind]
195196
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
196197
file: &'static str, line: u32) -> ! {
197198
begin_unwind_fmt(msg, &(file, line))

src/libstd/sys/common/unwind/seh.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ static PANIC_DATA: StaticKey = StaticKey::new(None);
6262

6363
// This function is provided by kernel32.dll
6464
extern "system" {
65+
#[unwind]
6566
fn RaiseException(dwExceptionCode: DWORD,
6667
dwExceptionFlags: DWORD,
6768
nNumberOfArguments: DWORD,

src/libstd/sys/common/unwind/seh64_gnu.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ pub enum EXCEPTION_DISPOSITION {
9393

9494
// From kernel32.dll
9595
extern "system" {
96+
#[unwind]
9697
fn RaiseException(dwExceptionCode: DWORD,
9798
dwExceptionFlags: DWORD,
9899
nNumberOfArguments: DWORD,
@@ -198,6 +199,7 @@ unsafe extern fn rust_eh_personality(
198199

199200
#[lang = "eh_unwind_resume"]
200201
#[cfg(not(test))]
202+
#[unwind]
201203
unsafe extern fn rust_eh_unwind_resume(panic_ctx: LPVOID) {
202204
let params = [panic_ctx as ULONG_PTR];
203205
RaiseException(RUST_PANIC,

src/libsyntax/feature_gate.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
188188

189189
// allow `extern "platform-intrinsic" { ... }`
190190
("platform_intrinsics", "1.4.0", Some(27731), Active),
191+
192+
// allow `#[unwind]`
193+
("unwind_attributes", "1.4.0", None, Active),
191194
];
192195
// (changing above list without updating src/doc/reference.md makes @cmr sad)
193196

@@ -316,6 +319,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
316319
("unsafe_no_drop_flag", Whitelisted, Gated("unsafe_no_drop_flag",
317320
"unsafe_no_drop_flag has unstable semantics \
318321
and may be removed in the future")),
322+
("unwind", Whitelisted, Gated("unwind_attributes", "#[unwind] is experimental")),
319323

320324
// used in resolve
321325
("prelude_import", Whitelisted, Gated("prelude_import",

src/test/codegen/extern-functions.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// compile-flags: -C no-prepopulate-passes
12+
13+
#![feature(unwind_attributes)]
14+
15+
extern {
16+
// CHECK: Function Attrs: nounwind
17+
// CHECK-NEXT: declare void @extern_fn
18+
fn extern_fn();
19+
// CHECK-NOT: Function Attrs: nounwind
20+
// CHECK: declare void @unwinding_extern_fn
21+
#[unwind]
22+
fn unwinding_extern_fn();
23+
}

0 commit comments

Comments
 (0)