rust/src/librustc/middle/trans
bors 7aa407958b auto merge of #15998 : luqmana/rust/nmnnbd, r=thestinger
LLVM recently added a new attribute, dereferenceable: http://reviews.llvm.org/D4449

>This patch adds a dereferencable attribute. In some sense, this is a companion to the nonnull attribute, but specifies that the pointer is known to be dereferencable in the same sense as a pointer generated by alloca is known to be dereferencable.

With rust, everywhere that we previously marked `nonnull` we can actually mark as `dereferenceable` (which implies nonnull) since we know the size. That is, except for one case: when generating calls for TyVisitor. It seems like we haven't substituted the self type (so we have `ty_param`) and just treat it as an opaque pointer so I just left that bit as nonnull.

With this, LLVM can for example hoist a load out of a loop where it previously couldn't:

```Rust
pub fn baz(c: &uint, n: uint) -> uint {
    let mut res = 0;
    for i in range(0, n) {
        if i > 0 {
            res += *c * i;
        }
    }
    res
}
```

Before:
```llvm
define i64 @baz(i64* noalias nocapture nonnull readonly, i64) unnamed_addr #0 {
entry-block:
  br label %for_loopback.outer

for_loopback.outer:                               ; preds = %then-block-33-, %entry-block
  %.ph = phi i64 [ %.lcssa, %then-block-33- ], [ 0, %entry-block ]
  %res.0.ph = phi i64 [ %8, %then-block-33- ], [ 0, %entry-block ]
  br label %for_loopback

for_exit:                                         ; preds = %for_loopback
  %res.0.ph.lcssa = phi i64 [ %res.0.ph, %for_loopback ]
  ret i64 %res.0.ph.lcssa

for_loopback:                                     ; preds = %for_loopback.outer, %for_body
  %2 = phi i64 [ %4, %for_body ], [ %.ph, %for_loopback.outer ]
  %3 = icmp ult i64 %2, %1
  br i1 %3, label %for_body, label %for_exit

for_body:                                         ; preds = %for_loopback
  %4 = add i64 %2, 1
  %5 = icmp eq i64 %2, 0
  br i1 %5, label %for_loopback, label %then-block-33-

then-block-33-:                                   ; preds = %for_body
  %.lcssa = phi i64 [ %4, %for_body ]
  %.lcssa15 = phi i64 [ %2, %for_body ]
  %6 = load i64* %0, align 8                     ; <------- this load
  %7 = mul i64 %6, %.lcssa15
  %8 = add i64 %7, %res.0.ph
  br label %for_loopback.outer
}
```

After:
```llvm
define i64 @baz(i64* noalias nocapture readonly dereferenceable(8), i64) unnamed_addr #0 {
entry-block:
  %2 = load i64* %0, align 8                    ; <------- load once instead
  br label %for_loopback.outer

for_loopback.outer:                               ; preds = %then-block-33-, %entry-block
  %.ph = phi i64 [ %.lcssa, %then-block-33- ], [ 0, %entry-block ]
  %res.0.ph = phi i64 [ %8, %then-block-33- ], [ 0, %entry-block ]
  br label %for_loopback

for_exit:                                         ; preds = %for_loopback
  %res.0.ph.lcssa = phi i64 [ %res.0.ph, %for_loopback ]
  ret i64 %res.0.ph.lcssa

for_loopback:                                     ; preds = %for_loopback.outer, %for_body
  %3 = phi i64 [ %5, %for_body ], [ %.ph, %for_loopback.outer ]
  %4 = icmp ult i64 %3, %1
  br i1 %4, label %for_body, label %for_exit

for_body:                                         ; preds = %for_loopback
  %5 = add i64 %3, 1
  %6 = icmp eq i64 %3, 0
  br i1 %6, label %for_loopback, label %then-block-33-

then-block-33-:                                   ; preds = %for_body
  %.lcssa = phi i64 [ %5, %for_body ]
  %.lcssa15 = phi i64 [ %3, %for_body ]
  %7 = mul i64 %2, %.lcssa15
  %8 = add i64 %7, %res.0.ph
  br label %for_loopback.outer
}
```
2014-07-26 15:46:18 +00:00
..
_match.rs librustc: Stop desugaring for expressions and translate them directly. 2014-07-24 18:58:12 -07:00
adt.rs Add Drop support for enums 2014-07-22 23:45:49 +02:00
asm.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
base.rs librustc: Use dereferenceable attribute instead of nonnull where we can. 2014-07-25 18:33:10 -07:00
basic_block.rs librustc: Implement lifetime elision. 2014-07-19 13:10:58 -07:00
build.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
builder.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
cabi_arm.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_mips.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_x86_64.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi_x86.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
cabi.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
callee.rs librustc: Only emit constructor functions as necessary. 2014-07-18 11:58:45 -07:00
cleanup.rs Emit lifetime end markers in unwinding codepaths 2014-07-25 14:31:05 +02:00
closure.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
common.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
consts.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
context.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
controlflow.rs librustc: Stop desugaring for expressions and translate them directly. 2014-07-24 18:58:12 -07:00
datum.rs Improve usage of lifetime intrinsics in match expressions 2014-07-23 17:39:13 +02:00
debuginfo.rs librustc: Stop desugaring for expressions and translate them directly. 2014-07-24 18:58:12 -07:00
doc.rs
expr.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
foreign.rs librustc: Use dereferenceable attribute instead of nonnull where we can. 2014-07-25 18:33:10 -07:00
glue.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
inline.rs change to new trait style for method field refs 2014-07-15 14:46:32 -07:00
intrinsic.rs librustc: Use builder for llvm attributes. 2014-07-25 16:06:44 -07:00
llrepr.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
machine.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00
macros.rs
meth.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
mod.rs
monomorphize.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
reflect.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
tvec.rs Emit LLVM lifetime intrinsics to improve stack usage and codegen in general 2014-07-22 09:17:41 +02:00
type_.rs Add string::raw::from_buf 2014-07-24 07:25:43 -07:00
type_of.rs librustc: Implement unboxed closures with mutable receivers 2014-07-18 09:01:37 -07:00
value.rs rustc_llvm: Remove the inner llvm module 2014-07-14 12:27:08 -07:00