Skip to content

Commit faa0b5a

Browse files
committed
auto merge of #11538 : eddyb/rust/llvm-attributes, r=alexcrichton
2 parents 9075025 + 8e2027a commit faa0b5a

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);
@@ -582,11 +592,8 @@ pub fn get_res_dtor(ccx: @CrateContext,
582592

583593
{
584594
let mut externs = ccx.externs.borrow_mut();
585-
get_extern_fn(externs.get(),
586-
ccx.llmod,
587-
name,
588-
lib::llvm::CCallConv,
589-
llty)
595+
get_extern_fn(externs.get(), ccx.llmod, name,
596+
lib::llvm::CCallConv, llty, ty::mk_nil())
590597
}
591598
}
592599
}
@@ -917,7 +924,8 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
917924
let cconv = c.unwrap_or(lib::llvm::CCallConv);
918925
let llty = type_of_fn_from_ty(ccx, None, t);
919926
let mut externs = ccx.externs.borrow_mut();
920-
get_extern_fn(externs.get(), ccx.llmod, name, cconv, llty)
927+
get_extern_fn(externs.get(), ccx.llmod, name,
928+
cconv, llty, fn_ty.sig.output)
921929
}
922930
}
923931
}
@@ -2533,13 +2541,13 @@ pub fn register_fn_llvmty(ccx: @CrateContext,
25332541
sym: ~str,
25342542
node_id: ast::NodeId,
25352543
cc: lib::llvm::CallConv,
2536-
fn_ty: Type)
2537-
-> ValueRef {
2544+
fn_ty: Type,
2545+
output: ty::t) -> ValueRef {
25382546
debug!("register_fn_fuller creating fn for item {} with path {}",
25392547
node_id,
25402548
ast_map::path_to_str(item_path(ccx, &node_id), token::get_ident_interner()));
25412549

2542-
let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty);
2550+
let llfn = decl_fn(ccx.llmod, sym, cc, fn_ty, output);
25432551
finish_register_fn(ccx, sp, sym, node_id, llfn);
25442552
llfn
25452553
}
@@ -2571,7 +2579,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
25712579
let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()],
25722580
&ccx.int_type);
25732581

2574-
let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty);
2582+
let llfn = decl_cdecl_fn(ccx.llmod, "main", llfty, ty::mk_nil());
25752583
let llbb = "top".with_c_str(|buf| {
25762584
unsafe {
25772585
llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
@@ -2975,7 +2983,8 @@ pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef {
29752983
macro_rules! ifn (
29762984
($intrinsics:ident, $name:expr, $args:expr, $ret:expr) => ({
29772985
let name = $name;
2978-
let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret));
2986+
// HACK(eddyb) dummy output type, shouln't affect anything.
2987+
let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret), ty::mk_nil());
29792988
$intrinsics.insert(name, f);
29802989
})
29812990
)

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
@@ -596,7 +596,7 @@ fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type,
596596
let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed();
597597
debug!("{} is for type {}", fn_nm, ppaux::ty_to_str(ccx.tcx, t));
598598
note_unique_llvm_symbol(ccx, fn_nm);
599-
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
599+
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty, ty::mk_nil());
600600
return llfn;
601601
}
602602

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)