Skip to content

Commit 5f710f7

Browse files
committed
---
yaml --- r: 153311 b: refs/heads/try2 c: 345886c h: refs/heads/master i: 153309: e16124f 153307: ae47ada 153303: 636262f 153295: e5b3542 153279: 97da34d v: v3
1 parent 3ee5679 commit 5f710f7

File tree

11 files changed

+567
-604
lines changed

11 files changed

+567
-604
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: f8bc571df70a0832890bbed82ff80d4c9921b6ac
8+
refs/heads/try2: 345886cfddd881644fbf8c0e0c1487102b460cf6
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/mk/dist.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ distcheck-tar-bins: dist-tar-bins
259259
$(Q)cd tmp/distcheck && tar -xzf ../../dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz
260260
$(Q)mkdir -p tmp/distcheck/tarbininstall
261261
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall
262-
$(Q)tmp/distcheck/tarbininstall/bin/rustc --version
263262
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall --uninstall
264263
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)
265264
$(Q)rm -Rf tmp/distcheck/tarbininstall

branches/try2/src/libcore/intrinsics.rs

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -326,19 +326,73 @@ extern "rust-intrinsic" {
326326
/// integer, since the conversion would throw away aliasing information.
327327
pub fn offset<T>(dst: *const T, offset: int) -> *const T;
328328

329-
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
330-
/// a size of `count` * `size_of::<T>()` and an alignment of
331-
/// `min_align_of::<T>()`
329+
/// Copies data from one location to another.
330+
///
331+
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
332+
/// and destination may *not* overlap.
333+
///
334+
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
335+
///
336+
/// # Example
337+
///
338+
/// A safe swap function:
339+
///
340+
/// ```
341+
/// use std::mem;
342+
/// use std::ptr;
343+
///
344+
/// fn swap<T>(x: &mut T, y: &mut T) {
345+
/// unsafe {
346+
/// // Give ourselves some scratch space to work with
347+
/// let mut t: T = mem::uninitialized();
348+
///
349+
/// // Perform the swap, `&mut` pointers never alias
350+
/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
351+
/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
352+
/// ptr::copy_nonoverlapping_memory(y, &t, 1);
353+
///
354+
/// // y and t now point to the same thing, but we need to completely forget `tmp`
355+
/// // because it's no longer relevant.
356+
/// mem::forget(t);
357+
/// }
358+
/// }
359+
/// ```
360+
///
361+
/// # Safety Note
362+
///
363+
/// If the source and destination overlap then the behavior of this
364+
/// function is undefined.
365+
#[unstable]
332366
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint);
333367

334-
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
335-
/// a size of `count` * `size_of::<T>()` and an alignment of
336-
/// `min_align_of::<T>()`
368+
/// Copies data from one location to another.
369+
///
370+
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
371+
/// and destination may overlap.
372+
///
373+
/// `copy_memory` is semantically equivalent to C's `memmove`.
374+
///
375+
/// # Example
376+
///
377+
/// Efficiently create a Rust vector from an unsafe buffer:
378+
///
379+
/// ```
380+
/// use std::ptr;
381+
///
382+
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
383+
/// let mut dst = Vec::with_capacity(elts);
384+
/// dst.set_len(elts);
385+
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
386+
/// dst
387+
/// }
388+
/// ```
389+
///
390+
#[unstable]
337391
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: uint);
338392

339-
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
340-
/// size of `count` * `size_of::<T>()` and an alignment of
341-
/// `min_align_of::<T>()`
393+
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
394+
/// bytes of memory starting at `dst` to `c`.
395+
#[experimental = "uncertain about naming and semantics"]
342396
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
343397

344398
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with

branches/try2/src/libcore/ptr.rs

Lines changed: 4 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ use option::{Some, None, Option};
9595

9696
use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
9797

98+
pub use intrinsics::copy_memory;
99+
pub use intrinsics::copy_nonoverlapping_memory;
100+
pub use intrinsics::set_memory;
101+
98102
/// Create a null pointer.
99103
///
100104
/// # Example
@@ -123,86 +127,6 @@ pub fn null<T>() -> *const T { 0 as *const T }
123127
#[unstable = "may need a different name after pending changes to pointer types"]
124128
pub fn mut_null<T>() -> *mut T { 0 as *mut T }
125129

126-
/// Copies data from one location to another.
127-
///
128-
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
129-
/// and destination may overlap.
130-
///
131-
/// `copy_memory` is semantically equivalent to C's `memmove`.
132-
///
133-
/// # Example
134-
///
135-
/// Efficiently create a Rust vector from an unsafe buffer:
136-
///
137-
/// ```
138-
/// use std::ptr;
139-
///
140-
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
141-
/// let mut dst = Vec::with_capacity(elts);
142-
/// dst.set_len(elts);
143-
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
144-
/// dst
145-
/// }
146-
/// ```
147-
///
148-
#[inline]
149-
#[unstable]
150-
pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) {
151-
intrinsics::copy_memory(dst, src, count)
152-
}
153-
154-
/// Copies data from one location to another.
155-
///
156-
/// Copies `count` elements (not bytes) from `src` to `dst`. The source
157-
/// and destination may *not* overlap.
158-
///
159-
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
160-
///
161-
/// # Example
162-
///
163-
/// A safe swap function:
164-
///
165-
/// ```
166-
/// use std::mem;
167-
/// use std::ptr;
168-
///
169-
/// fn swap<T>(x: &mut T, y: &mut T) {
170-
/// unsafe {
171-
/// // Give ourselves some scratch space to work with
172-
/// let mut t: T = mem::uninitialized();
173-
///
174-
/// // Perform the swap, `&mut` pointers never alias
175-
/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
176-
/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
177-
/// ptr::copy_nonoverlapping_memory(y, &t, 1);
178-
///
179-
/// // y and t now point to the same thing, but we need to completely forget `tmp`
180-
/// // because it's no longer relevant.
181-
/// mem::forget(t);
182-
/// }
183-
/// }
184-
/// ```
185-
///
186-
/// # Safety Note
187-
///
188-
/// If the source and destination overlap then the behavior of this
189-
/// function is undefined.
190-
#[inline]
191-
#[unstable]
192-
pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
193-
src: *const T,
194-
count: uint) {
195-
intrinsics::copy_nonoverlapping_memory(dst, src, count)
196-
}
197-
198-
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
199-
/// bytes of memory starting at `dst` to `c`.
200-
#[inline]
201-
#[experimental = "uncertain about naming and semantics"]
202-
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
203-
intrinsics::set_memory(dst, c, count)
204-
}
205-
206130
/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
207131
#[inline]
208132
#[experimental = "uncertain about naming and semantics"]

branches/try2/src/librustc/middle/trans/base.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,12 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
862862
ty::ty_bare_fn(ref fn_ty) => {
863863
match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
864864
ccx.sess().targ_cfg.arch) {
865-
Some(Rust) | Some(RustIntrinsic) => {
865+
Some(Rust) => {
866866
get_extern_rust_fn(ccx, t, name.as_slice(), did)
867867
}
868+
Some(RustIntrinsic) => {
869+
ccx.sess().bug("unexpected intrinsic in trans_external_path")
870+
}
868871
Some(..) | None => {
869872
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
870873
name.as_slice(), None)
@@ -1781,9 +1784,9 @@ fn register_fn(ccx: &CrateContext,
17811784
-> ValueRef {
17821785
match ty::get(node_type).sty {
17831786
ty::ty_bare_fn(ref f) => {
1784-
assert!(f.abi == Rust || f.abi == RustIntrinsic);
1787+
assert!(f.abi == Rust);
17851788
}
1786-
_ => fail!("expected bare rust fn or an intrinsic")
1789+
_ => fail!("expected bare rust fn")
17871790
};
17881791

17891792
let llfn = decl_rust_fn(ccx, node_type, sym.as_slice());

branches/try2/src/librustc/middle/trans/callee.rs

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
use arena::TypedArena;
2020
use back::abi;
2121
use back::link;
22-
use driver::session;
2322
use lib::llvm::ValueRef;
2423
use lib::llvm::llvm;
2524
use metadata::csearch;
@@ -40,6 +39,7 @@ use middle::trans::expr;
4039
use middle::trans::glue;
4140
use middle::trans::inline;
4241
use middle::trans::foreign;
42+
use middle::trans::intrinsic;
4343
use middle::trans::meth;
4444
use middle::trans::monomorphize;
4545
use middle::trans::type_::Type;
@@ -53,7 +53,6 @@ use util::ppaux::Repr;
5353
use std::gc::Gc;
5454
use syntax::ast;
5555
use synabi = syntax::abi;
56-
use syntax::ast_map;
5756

5857
pub struct MethodData {
5958
pub llfn: ValueRef,
@@ -68,6 +67,8 @@ pub enum CalleeData {
6867
// value (which is a pair).
6968
Fn(/* llfn */ ValueRef),
7069

70+
Intrinsic(ast::NodeId, subst::Substs),
71+
7172
TraitMethod(MethodData)
7273
}
7374

@@ -119,7 +120,21 @@ fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> {
119120

120121
fn trans_def<'a>(bcx: &'a Block<'a>, def: def::Def, ref_expr: &ast::Expr)
121122
-> Callee<'a> {
123+
debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
124+
let expr_ty = node_id_type(bcx, ref_expr.id);
122125
match def {
126+
def::DefFn(did, _) if match ty::get(expr_ty).sty {
127+
ty::ty_bare_fn(ref f) => f.abi == synabi::RustIntrinsic,
128+
_ => false
129+
} => {
130+
let substs = node_id_substs(bcx, ExprId(ref_expr.id));
131+
let def_id = if did.krate != ast::LOCAL_CRATE {
132+
inline::maybe_instantiate_inline(bcx.ccx(), did)
133+
} else {
134+
did
135+
};
136+
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
137+
}
123138
def::DefFn(did, _) |
124139
def::DefStaticMethod(did, def::FromImpl(_), _) => {
125140
fn_callee(bcx, trans_fn_ref(bcx, did, ExprId(ref_expr.id)))
@@ -460,27 +475,8 @@ pub fn trans_fn_ref_with_vtables(
460475
}
461476
};
462477

463-
// We must monomorphise if the fn has type parameters, is a rust
464-
// intrinsic, or is a default method. In particular, if we see an
465-
// intrinsic that is inlined from a different crate, we want to reemit the
466-
// intrinsic instead of trying to call it in the other crate.
467-
let must_monomorphise = if !substs.types.is_empty() || is_default {
468-
true
469-
} else if def_id.krate == ast::LOCAL_CRATE {
470-
let map_node = session::expect(
471-
ccx.sess(),
472-
tcx.map.find(def_id.node),
473-
|| "local item should be in ast map".to_string());
474-
475-
match map_node {
476-
ast_map::NodeForeignItem(_) => {
477-
tcx.map.get_foreign_abi(def_id.node) == synabi::RustIntrinsic
478-
}
479-
_ => false
480-
}
481-
} else {
482-
false
483-
};
478+
// We must monomorphise if the fn has type parameters or is a default method.
479+
let must_monomorphise = !substs.types.is_empty() || is_default;
484480

485481
// Create a monomorphic version of generic functions
486482
if must_monomorphise {
@@ -662,6 +658,12 @@ pub fn trans_call_inner<'a>(
662658
let callee = get_callee(bcx, cleanup::CustomScope(arg_cleanup_scope));
663659
let mut bcx = callee.bcx;
664660

661+
let (abi, ret_ty) = match ty::get(callee_ty).sty {
662+
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
663+
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
664+
_ => fail!("expected bare rust fn or closure in trans_call_inner")
665+
};
666+
665667
let (llfn, llenv, llself) = match callee.data {
666668
Fn(llfn) => {
667669
(llfn, None, None)
@@ -679,14 +681,19 @@ pub fn trans_call_inner<'a>(
679681
let llenv = Load(bcx, llenv);
680682
(llfn, Some(llenv), None)
681683
}
682-
};
684+
Intrinsic(node, substs) => {
685+
assert!(abi == synabi::RustIntrinsic);
686+
assert!(dest.is_some());
683687

684-
let (abi, ret_ty) = match ty::get(callee_ty).sty {
685-
ty::ty_bare_fn(ref f) => (f.abi, f.sig.output),
686-
ty::ty_closure(ref f) => (synabi::Rust, f.sig.output),
687-
_ => fail!("expected bare rust fn or closure in trans_call_inner")
688+
return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
689+
arg_cleanup_scope, args,
690+
dest.unwrap(), substs);
691+
}
688692
};
689-
let is_rust_fn = abi == synabi::Rust || abi == synabi::RustIntrinsic;
693+
694+
// Intrinsics should not become actual functions.
695+
// We trans them in place in `trans_intrinsic_call`
696+
assert!(abi != synabi::RustIntrinsic);
690697

691698
// Generate a location to store the result. If the user does
692699
// not care about the result, just make a stack slot.
@@ -716,7 +723,7 @@ pub fn trans_call_inner<'a>(
716723
// and done, either the return value of the function will have been
717724
// written in opt_llretslot (if it is Some) or `llresult` will be
718725
// set appropriately (otherwise).
719-
if is_rust_fn {
726+
if abi == synabi::Rust {
720727
let mut llargs = Vec::new();
721728

722729
// Push the out-pointer if we use an out-pointer for this
@@ -816,13 +823,13 @@ pub enum CallArgs<'a> {
816823
ArgOverloadedOp(Datum<Expr>, Option<(Datum<Expr>, ast::NodeId)>),
817824
}
818825

819-
fn trans_args<'a>(cx: &'a Block<'a>,
820-
args: CallArgs,
821-
fn_ty: ty::t,
822-
llargs: &mut Vec<ValueRef> ,
823-
arg_cleanup_scope: cleanup::ScopeId,
824-
ignore_self: bool)
825-
-> &'a Block<'a> {
826+
pub fn trans_args<'a>(cx: &'a Block<'a>,
827+
args: CallArgs,
828+
fn_ty: ty::t,
829+
llargs: &mut Vec<ValueRef> ,
830+
arg_cleanup_scope: cleanup::ScopeId,
831+
ignore_self: bool)
832+
-> &'a Block<'a> {
826833
let _icx = push_ctxt("trans_args");
827834
let arg_tys = ty::ty_fn_args(fn_ty);
828835
let variadic = ty::fn_is_variadic(fn_ty);

branches/try2/src/librustc/middle/trans/foreign.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub fn llvm_calling_convention(ccx: &CrateContext,
7676
abi.for_target(os, arch).map(|abi| {
7777
match abi {
7878
RustIntrinsic => {
79-
// Intrinsics are emitted by monomorphic fn
79+
// Intrinsics are emitted at the call site
8080
ccx.sess().bug("asked to register intrinsic fn");
8181
}
8282

0 commit comments

Comments
 (0)