-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc: mark references w/anonymous lifetime nocapture #13001
Conversation
@cmr: Can you make sure they are marked |
@thestinger what would IR for that look like? For example with fn foo<'a>(x: &'a int) -> int { *x }
fn bar(x: &int) -> int { *x }
fn unwrap<T>(f: fn(&T) -> T, v: &T) -> T {
f(v)
}
fn main() {
let x = unwrap(foo, &42);
let y = unwrap(bar, &32);
assert!(x == 42);
assert!(y == 32);
} I find a line in the IR:
Which if I change to...
llc dies with
|
@cmr: I forget the syntax, but the code adding // A function pointer is called without the declaration
// available, so we have to apply any attributes with ABI
// implications directly to the call instruction. Right now,
// the only attribute we need to worry about is `sret`.
let mut attrs = Vec::new();
if type_of::return_uses_outptr(ccx, ret_ty) {
attrs.push((1, StructRetAttribute));
}
// The `noalias` attribute on the return value is useful to a
// function ptr caller.
match ty::get(ret_ty).sty {
// `~` pointer return values never alias because ownership
// is transferred
ty::ty_uniq(..) | ty::ty_vec(_, ty::vstore_uniq) => {
attrs.push((0, NoAliasAttribute));
}
_ => {}
} So you could add |
@thestinger after playing with it, LLVM errors on broken functions whenever I try to add attributes there. So I think it just doesn't allow it. |
The code that @thestinger referenced is about adding the attribute to the argument in the call itself. For example, there is an indirect call in %4 = call i64 %2(i64* %3) extending the code to handle %4 = call i64 %2(i64* nocapture %3) |
Made up example where this makes a difference: ; ModuleID = 'issue-13001.rs'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @other()
define i64 @without(i64 (i64*)*) unnamed_addr #4 {
entry-block:
%1 = alloca i64
%2 = call i64 %0(i64* %1)
store i64 8, i64* %1
call void @other()
ret i64 %2
}
define i64 @with(i64 (i64*)*) unnamed_addr #4 {
entry-block:
%1 = alloca i64
%2 = call i64 %0(i64* nocapture %1)
store i64 8, i64* %1
call void @other()
ret i64 %2
} Gets optimized to: ; ModuleID = '<stdin>'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare void @other()
define i64 @without(i64 (i64*)* nocapture) unnamed_addr {
entry-block:
%1 = alloca i64, align 8
%2 = call i64 %0(i64* %1)
store i64 8, i64* %1, align 8
call void @other()
ret i64 %2
}
define i64 @with(i64 (i64*)* nocapture) unnamed_addr {
entry-block:
%1 = alloca i64, align 8
%2 = call i64 %0(i64* nocapture %1)
tail call void @other()
ret i64 %2
} The |
@cmr: It's already adding |
What I tried in the "wip" commit. |
(Rebuilding to try and debug further) |
Current status with the wips:
I think the accounting for self/envptr might be wrong but I'll continue debugging tomorrow. |
Note that you don't have to account for |
@dotdash ah thanks. do you want me to add that to this pr? |
@cmr looks like travis doesn't like some of your long lines. I gave r+ but removed it due to travis failures. I think the reasoning for using I think I'd feel more comfortable if we had a pass that ran just before trans and which analysed and annotated (in a side table) the various parameters with the various kinds of attributes that they are best suited for. I envision a very simple visitor that walks the AST, examining the declared types of each function and closure. One argument against this approach would be that perhaps the results of monomorphization are relevant in some cases (though not in this one). There would also be the necessity of serializing and deserializing these results for cross-crate inlining, which is always a bit of a pain. @cmr what do you think about that? Am I just being overly nervous? |
@nikomatsakis: At some point we'll want to be outputting TBAA metadata nodes rather than just parameter attributes, so we will need some kind of smarter high-level infrastructure. I don't think it's too difficult to get it right with just parameters though. |
These failures are in some way legitimate, investigating. |
Accidentally let LLVM do some TCO where we didn't want it. |
We really do *not* want TCO to kick in. If it does, we'll never blow the stack, and never trigger the condition the test is checking for. To that end, do a meaningless alloc that serves only to get a destructor to run. The addition of nocapture/noalias seems to have let LLVM do more TCO, which hurt this testcase.
Replace crossbeam with std's scoped threads Probably best to wait a week or two so we don't immediately give linux packagers problems again
Closes #6751