Skip to content

Commit 8e2027a

Browse files
committed
Add noalias and noreturn attributes in more cases.
1 parent 77eedda commit 8e2027a

File tree

4 files changed

+59
-57
lines changed

4 files changed

+59
-57
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -177,32 +177,57 @@ impl<'a> Drop for StatRecorder<'a> {
177177
}
178178

179179
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
180-
pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
180+
fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv,
181+
ty: Type, output: ty::t) -> ValueRef {
181182
let llfn: ValueRef = name.with_c_str(|buf| {
182183
unsafe {
183184
llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
184185
}
185186
});
186187

188+
match ty::get(output).sty {
189+
// functions returning bottom may unwind, but can never return normally
190+
ty::ty_bot => {
191+
unsafe {
192+
llvm::LLVMAddFunctionAttr(llfn, lib::llvm::NoReturnAttribute as c_uint)
193+
}
194+
}
195+
// `~` pointer return values never alias because ownership is transferred
196+
// FIXME #6750 ~Trait cannot be directly marked as
197+
// noalias because the actual object pointer is nested.
198+
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
199+
ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) => {
200+
unsafe {
201+
llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
202+
}
203+
}
204+
_ => {}
205+
}
206+
187207
lib::llvm::SetFunctionCallConv(llfn, cc);
188208
// Function addresses in Rust are never significant, allowing functions to be merged.
189209
lib::llvm::SetUnnamedAddr(llfn, true);
190-
return llfn;
210+
211+
llfn
191212
}
192213

193214
// only use this for foreign function ABIs and glue, use `decl_rust_fn` for Rust functions
194-
pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef {
195-
return decl_fn(llmod, name, lib::llvm::CCallConv, ty);
215+
pub fn decl_cdecl_fn(llmod: ModuleRef,
216+
name: &str,
217+
ty: Type,
218+
output: ty::t) -> ValueRef {
219+
decl_fn(llmod, name, lib::llvm::CCallConv, ty, output)
196220
}
197221

198222
// only use this for foreign function ABIs and glue, use `get_extern_rust_fn` for Rust functions
199-
pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
200-
cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
223+
pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef,
224+
name: &str, cc: lib::llvm::CallConv,
225+
ty: Type, output: ty::t) -> ValueRef {
201226
match externs.find_equiv(&name) {
202227
Some(n) => return *n,
203-
None => ()
228+
None => {}
204229
}
205-
let f = decl_fn(llmod, name, cc, ty);
230+
let f = decl_fn(llmod, name, cc, ty, output);
206231
externs.insert(name.to_owned(), f);
207232
f
208233
}
@@ -233,24 +258,7 @@ fn decl_rust_fn(ccx: &CrateContext,
233258
output: ty::t,
234259
name: &str) -> ValueRef {
235260
let llfty = type_of_rust_fn(ccx, self_ty, inputs, output);
236-
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty);
237-
238-
match ty::get(output).sty {
239-
// functions returning bottom may unwind, but can never return normally
240-
ty::ty_bot => {
241-
unsafe {
242-
llvm::LLVMAddFunctionAttr(llfn, lib::llvm::NoReturnAttribute as c_uint)
243-
}
244-
}
245-
// `~` pointer return values never alias because ownership is transferred
246-
ty::ty_uniq(..) |
247-
ty::ty_vec(_, ty::vstore_uniq) => {
248-
unsafe {
249-
llvm::LLVMAddReturnAttribute(llfn, lib::llvm::NoAliasAttribute as c_uint);
250-
}
251-
}
252-
_ => ()
253-
}
261+
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty, output);
254262

255263
let uses_outptr = type_of::return_uses_outptr(ccx, output);
256264
let offset = if uses_outptr { 2 } else { 1 };
@@ -259,8 +267,10 @@ fn decl_rust_fn(ccx: &CrateContext,
259267
let llarg = unsafe { llvm::LLVMGetParam(llfn, (offset + i) as c_uint) };
260268
match ty::get(arg_ty).sty {
261269
// `~` pointer parameters never alias because ownership is transferred
262-
ty::ty_uniq(..) |
263-
ty::ty_vec(_, ty::vstore_uniq) |
270+
// FIXME #6750 ~Trait cannot be directly marked as
271+
// noalias because the actual object pointer is nested.
272+
ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
273+
ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) |
264274
ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
265275
unsafe {
266276
llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
@@ -584,11 +594,8 @@ pub fn get_res_dtor(ccx: @CrateContext,
584594

585595
{
586596
let mut externs = ccx.externs.borrow_mut();
587-
get_extern_fn(externs.get(),
588-
ccx.llmod,
589-
name,
590-
lib::llvm::CCallConv,
591-
llty)
597+
get_extern_fn(externs.get(), ccx.llmod, name,
598+
lib::llvm::CCallConv, llty, ty::mk_nil())
592599
}
593600
}
594601
}
@@ -919,7 +926,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
919926
let cconv = c.unwrap_or(lib::llvm::CCallConv);
920927
let llty = type_of_fn_from_ty(ccx, None, t);
921928
let mut externs = ccx.externs.borrow_mut();
922-
get_extern_fn(externs.get(), ccx.llmod, name, cconv, llty)
929+
get_extern_fn(externs.get(), ccx.llmod, name,
930+
cconv, llty, fn_ty.sig.output)
923931
}
924932
}
925933
}
@@ -2535,13 +2543,13 @@ pub fn register_fn_llvmty(ccx: @CrateContext,
25352543
sym: ~str,
25362544
node_id: ast::NodeId,
25372545
cc: lib::llvm::CallConv,
2538-
fn_ty: Type)
2539-
-> ValueRef {
2546+
fn_ty: Type,
2547+
output: ty::t) -> ValueRef {
25402548
debug!("register_fn_fuller creating fn for item {} with path {}",
25412549
node_id,
25422550
ast_map::path_to_str(item_path(ccx, &node_id), token::get_ident_interner()));
25432551

2544-
let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty);
2552+
let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty, output);
25452553
finish_register_fn(ccx, sp, sym, node_id, llfn);
25462554
llfn
25472555
}
@@ -2573,7 +2581,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
25732581
let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()],
25742582
&ccx.int_type);
25752583

2576-
let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty);
2584+
let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty, ty::mk_nil());
25772585
let llbb = "top".with_c_str(|buf| {
25782586
unsafe {
25792587
llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
@@ -2977,7 +2985,8 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef {
29772985
macro_rules! ifn (
29782986
($intrinsics:ident, $name:expr, $args:expr, $ret:expr) => ({
29792987
let name = $name;
2980-
let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret));
2988+
// HACK(eddyb) dummy output type, shouln't affect anything.
2989+
let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret), ty::mk_nil());
29812990
$intrinsics.insert(name, f);
29822991
})
29832992
)

src/librustc/middle/trans/foreign.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,8 @@ pub fn register_foreign_item_fn(ccx: @CrateContext,
150150
let llfn;
151151
{
152152
let mut externs = ccx.externs.borrow_mut();
153-
llfn = base::get_extern_fn(externs.get(),
154-
ccx.llmod,
155-
lname,
156-
cc,
157-
llfn_ty);
153+
llfn = base::get_extern_fn(externs.get(), ccx.llmod, lname,
154+
cc, llfn_ty, tys.fn_sig.output);
158155
};
159156
add_argument_attributes(&tys, llfn);
160157

@@ -417,19 +414,14 @@ pub fn register_rust_fn_with_foreign_abi(ccx: @CrateContext,
417414
let tys = foreign_types_for_id(ccx, node_id);
418415
let llfn_ty = lltype_for_fn_from_foreign_types(&tys);
419416
let t = ty::node_id_to_type(ccx.tcx, node_id);
420-
let cconv = match ty::get(t).sty {
417+
let (cconv, output) = match ty::get(t).sty {
421418
ty::ty_bare_fn(ref fn_ty) => {
422419
let c = llvm_calling_convention(ccx, fn_ty.abis);
423-
c.unwrap_or(lib::llvm::CCallConv)
420+
(c.unwrap_or(lib::llvm::CCallConv), fn_ty.sig.output)
424421
}
425-
_ => lib::llvm::CCallConv
422+
_ => fail!("expected bare fn in register_rust_fn_with_foreign_abi")
426423
};
427-
let llfn = base::register_fn_llvmty(ccx,
428-
sp,
429-
sym,
430-
node_id,
431-
cconv,
432-
llfn_ty);
424+
let llfn = base::register_fn_llvmty(ccx, sp, sym, node_id, cconv, llfn_ty, output);
433425
add_argument_attributes(&tys, llfn);
434426
debug!("register_rust_fn_with_foreign_abi(node_id={:?}, llfn_ty={}, llfn={})",
435427
node_id, ccx.tn.type_to_str(llfn_ty), ccx.tn.val_to_str(llfn));

src/librustc/middle/trans/glue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
592592
let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed();
593593
debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx, t));
594594
note_unique_llvm_symbol(ccx, fn_nm);
595-
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
595+
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty, ty::mk_nil());
596596
return llfn;
597597
}
598598

src/librustc/middle/trans/intrinsic.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,10 @@ pub fn trans_intrinsic(ccx: @CrateContext,
431431
// native function. There should be a general in-language
432432
// way to do this
433433
let llfty = type_of_rust_fn(bcx.ccx(), None, [], ty::mk_nil());
434-
let morestack_addr = decl_cdecl_fn(
435-
bcx.ccx().llmod, "__morestack", llfty);
436-
let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to());
434+
let morestack_addr = decl_cdecl_fn(bcx.ccx().llmod, "__morestack",
435+
llfty, ty::mk_nil());
436+
let morestack_addr = PointerCast(bcx, morestack_addr,
437+
Type::nil().ptr_to());
437438
Ret(bcx, morestack_addr);
438439
}
439440
"offset" => {

0 commit comments

Comments
 (0)