Skip to content

Commit f39ad7f

Browse files
committed
---
yaml --- r: 153072 b: refs/heads/try2 c: 5d5c206 h: refs/heads/master v: v3
1 parent e501a0b commit f39ad7f

File tree

5 files changed

+91
-139
lines changed

5 files changed

+91
-139
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: 9bd6479912990046947913f160f69bc550dd3817
8+
refs/heads/try2: 5d5c20647f45f2eb74f337e5434bbe63b0c43345
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/mk/platform.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ CFG_PATH_MUNGE_i686-pc-mingw32 :=
461461
CFG_LDPATH_i686-pc-mingw32 :=$(CFG_LDPATH_i686-pc-mingw32):$(PATH)
462462
CFG_RUN_i686-pc-mingw32=PATH="$(CFG_LDPATH_i686-pc-mingw32):$(1)" $(2)
463463
CFG_RUN_TARG_i686-pc-mingw32=$(call CFG_RUN_i686-pc-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
464+
RUSTC_FLAGS_i686-pc-mingw32=-C link-args="-Wl,--large-address-aware"
464465

465466
# i586-mingw32msvc configuration
466467
CC_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-gcc

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

Lines changed: 63 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@
6464
* We store information about the bound variables for each arm as part of the
6565
* per-arm `ArmData` struct. There is a mapping from identifiers to
6666
* `BindingInfo` structs. These structs contain the mode/id/type of the
67-
* binding, but they also contain up to two LLVM values, called `llmatch` and
68-
* `llbinding` respectively (the `llbinding`, as will be described shortly, is
69-
* optional and only present for by-value bindings---therefore it is bundled
70-
* up as part of the `TransBindingMode` type). Both point at allocas.
67+
* binding, but they also contain an LLVM value which points at an alloca
68+
* called `llmatch`. For by value bindings that are Copy, we also create
69+
* an extra alloca that we copy the matched value to so that any changes
70+
* we do to our copy is not reflected in the original and vice-versa.
71+
* We don't do this if it's a move since the original value can't be used
72+
* and thus allowing us to cheat in not creating an extra alloca.
7173
*
7274
* The `llmatch` binding always stores a pointer into the value being matched
7375
* which points at the data for the binding. If the value being matched has
@@ -83,32 +85,26 @@
8385
* up against an identifier, we store the current pointer into the
8486
* corresponding alloca.
8587
*
86-
* In addition, for each by-value binding (copy or move), we will create a
87-
* second alloca (`llbinding`) that will hold the final value. In this
88-
* example, that means that `d` would have this second alloca of type `D` (and
89-
* hence `llbinding` has type `D*`).
90-
*
9188
* Once a pattern is completely matched, and assuming that there is no guard
9289
* pattern, we will branch to a block that leads to the body itself. For any
9390
* by-value bindings, this block will first load the ptr from `llmatch` (the
94-
* one of type `D*`) and copy/move the value into `llbinding` (the one of type
95-
* `D`). The second alloca then becomes the value of the local variable. For
96-
* by ref bindings, the value of the local variable is simply the first
97-
* alloca.
91+
* one of type `D*`) and then load a second time to get the actual value (the
92+
* one of type `D`). For by ref bindings, the value of the local variable is
93+
* simply the first alloca.
9894
*
9995
* So, for the example above, we would generate a setup kind of like this:
10096
*
10197
* +-------+
10298
* | Entry |
10399
* +-------+
104100
* |
105-
* +-------------------------------------------+
106-
* | llmatch_c = (addr of first half of tuple) |
107-
* | llmatch_d = (addr of first half of tuple) |
108-
* +-------------------------------------------+
101+
* +--------------------------------------------+
102+
* | llmatch_c = (addr of first half of tuple) |
103+
* | llmatch_d = (addr of second half of tuple) |
104+
* +--------------------------------------------+
109105
* |
110106
* +--------------------------------------+
111-
* | *llbinding_d = **llmatch_dlbinding_d |
107+
* | *llbinding_d = **llmatch_d |
112108
* +--------------------------------------+
113109
*
114110
* If there is a guard, the situation is slightly different, because we must
@@ -127,22 +123,20 @@
127123
* +-------------------------------------------+
128124
* |
129125
* +-------------------------------------------------+
130-
* | *llbinding_d = **llmatch_dlbinding_d |
126+
* | *llbinding_d = **llmatch_d |
131127
* | check condition |
132-
* | if false { free *llbinding_d, goto next case } |
128+
* | if false { goto next case } |
133129
* | if true { goto body } |
134130
* +-------------------------------------------------+
135131
*
136132
* The handling for the cleanups is a bit... sensitive. Basically, the body
137133
* is the one that invokes `add_clean()` for each binding. During the guard
138134
* evaluation, we add temporary cleanups and revoke them after the guard is
139-
* evaluated (it could fail, after all). Presuming the guard fails, we drop
140-
* the various values we copied explicitly. Note that guards and moves are
135+
* evaluated (it could fail, after all). Note that guards and moves are
141136
* just plain incompatible.
142137
*
143138
* Some relevant helper functions that manage bindings:
144139
* - `create_bindings_map()`
145-
* - `store_non_ref_bindings()`
146140
* - `insert_lllocals()`
147141
*
148142
*
@@ -216,7 +210,6 @@ use middle::trans::datum;
216210
use middle::trans::datum::*;
217211
use middle::trans::expr::Dest;
218212
use middle::trans::expr;
219-
use middle::trans::glue;
220213
use middle::trans::tvec;
221214
use middle::trans::type_of;
222215
use middle::trans::debuginfo;
@@ -355,8 +348,9 @@ fn variant_opt(bcx: &Block, pat_id: ast::NodeId) -> Opt {
355348
}
356349

357350
#[deriving(Clone)]
358-
enum TransBindingMode {
359-
TrByValue(/*llbinding:*/ ValueRef),
351+
pub enum TransBindingMode {
352+
TrByCopy(/* llbinding */ ValueRef),
353+
TrByMove,
360354
TrByRef,
361355
}
362356

@@ -369,12 +363,12 @@ enum TransBindingMode {
369363
* - `id` is the node id of the binding
370364
* - `ty` is the Rust type of the binding */
371365
#[deriving(Clone)]
372-
struct BindingInfo {
373-
llmatch: ValueRef,
374-
trmode: TransBindingMode,
375-
id: ast::NodeId,
376-
span: Span,
377-
ty: ty::t,
366+
pub struct BindingInfo {
367+
pub llmatch: ValueRef,
368+
pub trmode: TransBindingMode,
369+
pub id: ast::NodeId,
370+
pub span: Span,
371+
pub ty: ty::t,
378372
}
379373

380374
type BindingsMap = HashMap<Ident, BindingInfo>;
@@ -968,64 +962,34 @@ fn compare_values<'a>(
968962
}
969963
}
970964

971-
fn store_non_ref_bindings<'a>(
972-
bcx: &'a Block<'a>,
973-
bindings_map: &BindingsMap,
974-
opt_cleanup_scope: Option<cleanup::ScopeId>)
975-
-> &'a Block<'a>
976-
{
977-
/*!
978-
* For each copy/move binding, copy the value from the value being
979-
* matched into its final home. This code executes once one of
980-
* the patterns for a given arm has completely matched. It adds
981-
* cleanups to the `opt_cleanup_scope`, if one is provided.
982-
*/
983-
984-
let fcx = bcx.fcx;
985-
let mut bcx = bcx;
986-
for (_, &binding_info) in bindings_map.iter() {
987-
match binding_info.trmode {
988-
TrByValue(lldest) => {
989-
let llval = Load(bcx, binding_info.llmatch); // get a T*
990-
let datum = Datum::new(llval, binding_info.ty, Lvalue);
991-
bcx = datum.store_to(bcx, lldest);
992-
993-
match opt_cleanup_scope {
994-
None => {}
995-
Some(s) => {
996-
fcx.schedule_drop_mem(s, lldest, binding_info.ty);
997-
}
998-
}
999-
}
1000-
TrByRef => {}
1001-
}
1002-
}
1003-
return bcx;
1004-
}
1005-
1006-
fn insert_lllocals<'a>(bcx: &'a Block<'a>,
1007-
bindings_map: &BindingsMap,
1008-
cleanup_scope: cleanup::ScopeId)
965+
fn insert_lllocals<'a>(mut bcx: &'a Block<'a>,
966+
bindings_map: &BindingsMap)
1009967
-> &'a Block<'a> {
1010968
/*!
1011969
* For each binding in `data.bindings_map`, adds an appropriate entry into
1012-
* the `fcx.lllocals` map, scheduling cleanup in `cleanup_scope`.
970+
* the `fcx.lllocals` map
1013971
*/
1014972

1015-
let fcx = bcx.fcx;
1016-
1017973
for (&ident, &binding_info) in bindings_map.iter() {
1018974
let llval = match binding_info.trmode {
1019-
// By value bindings: use the stack slot that we
1020-
// copied/moved the value into
1021-
TrByValue(lldest) => lldest,
975+
// By value mut binding for a copy type: load from the ptr
976+
// into the matched value and copy to our alloca
977+
TrByCopy(llbinding) => {
978+
let llval = Load(bcx, binding_info.llmatch);
979+
let datum = Datum::new(llval, binding_info.ty, Lvalue);
980+
bcx = datum.store_to(bcx, llbinding);
981+
982+
llbinding
983+
},
984+
985+
// By value move bindings: load from the ptr into the matched value
986+
TrByMove => Load(bcx, binding_info.llmatch),
1022987

1023988
// By ref binding: use the ptr into the matched value
1024989
TrByRef => binding_info.llmatch
1025990
};
1026991

1027992
let datum = Datum::new(llval, binding_info.ty, Lvalue);
1028-
fcx.schedule_drop_mem(cleanup_scope, llval, binding_info.ty);
1029993

1030994
debug!("binding {:?} to {}",
1031995
binding_info.id,
@@ -1035,9 +999,7 @@ fn insert_lllocals<'a>(bcx: &'a Block<'a>,
1035999
if bcx.sess().opts.debuginfo == FullDebugInfo {
10361000
debuginfo::create_match_binding_metadata(bcx,
10371001
ident,
1038-
binding_info.id,
1039-
binding_info.span,
1040-
datum);
1002+
binding_info);
10411003
}
10421004
}
10431005
bcx
@@ -1059,28 +1021,16 @@ fn compile_guard<'a, 'b>(
10591021
vec_map_to_str(vals, |v| bcx.val_to_str(*v)));
10601022
let _indenter = indenter();
10611023

1062-
// Lest the guard itself should fail, introduce a temporary cleanup
1063-
// scope for any non-ref bindings we create.
1064-
let temp_scope = bcx.fcx.push_custom_cleanup_scope();
1065-
1066-
let mut bcx = bcx;
1067-
bcx = store_non_ref_bindings(bcx, &data.bindings_map,
1068-
Some(cleanup::CustomScope(temp_scope)));
1069-
bcx = insert_lllocals(bcx, &data.bindings_map,
1070-
cleanup::CustomScope(temp_scope));
1024+
let mut bcx = insert_lllocals(bcx, &data.bindings_map);
10711025

10721026
let val = unpack_datum!(bcx, expr::trans(bcx, guard_expr));
10731027
let val = val.to_llbool(bcx);
10741028

1075-
// Cancel cleanups now that the guard successfully executed. If
1076-
// the guard was false, we will drop the values explicitly
1077-
// below. Otherwise, we'll add lvalue cleanups at the end.
1078-
bcx.fcx.pop_custom_cleanup_scope(temp_scope);
1079-
10801029
return with_cond(bcx, Not(bcx, val), |bcx| {
1081-
// Guard does not match: free the values we copied,
1082-
// and remove all bindings from the lllocals table
1083-
let bcx = drop_bindings(bcx, data);
1030+
// Guard does not match: remove all bindings from the lllocals table
1031+
for (_, &binding_info) in data.bindings_map.iter() {
1032+
bcx.fcx.lllocals.borrow_mut().remove(&binding_info.id);
1033+
}
10841034
match chk {
10851035
// If the default arm is the only one left, move on to the next
10861036
// condition explicitly rather than (possibly) falling back to
@@ -1094,21 +1044,6 @@ fn compile_guard<'a, 'b>(
10941044
};
10951045
bcx
10961046
});
1097-
1098-
fn drop_bindings<'a>(bcx: &'a Block<'a>, data: &ArmData)
1099-
-> &'a Block<'a> {
1100-
let mut bcx = bcx;
1101-
for (_, &binding_info) in data.bindings_map.iter() {
1102-
match binding_info.trmode {
1103-
TrByValue(llval) => {
1104-
bcx = glue::drop_ty(bcx, llval, binding_info.ty);
1105-
}
1106-
TrByRef => {}
1107-
}
1108-
bcx.fcx.lllocals.borrow_mut().remove(&binding_info.id);
1109-
}
1110-
return bcx;
1111-
}
11121047
}
11131048

11141049
fn compile_submatch<'a, 'b>(
@@ -1433,18 +1368,28 @@ fn create_bindings_map(bcx: &Block, pat: Gc<ast::Pat>) -> BindingsMap {
14331368
let ident = path1.node;
14341369
let variable_ty = node_id_type(bcx, p_id);
14351370
let llvariable_ty = type_of::type_of(ccx, variable_ty);
1371+
let tcx = bcx.tcx();
14361372

14371373
let llmatch;
14381374
let trmode;
14391375
match bm {
1376+
ast::BindByValue(_)
1377+
if !ty::type_moves_by_default(tcx, variable_ty) => {
1378+
llmatch = alloca(bcx,
1379+
llvariable_ty.ptr_to(),
1380+
"__llmatch");
1381+
trmode = TrByCopy(alloca(bcx,
1382+
llvariable_ty,
1383+
bcx.ident(ident).as_slice()));
1384+
}
14401385
ast::BindByValue(_) => {
14411386
// in this case, the final type of the variable will be T,
14421387
// but during matching we need to store a *T as explained
14431388
// above
1444-
llmatch = alloca(bcx, llvariable_ty.ptr_to(), "__llmatch");
1445-
trmode = TrByValue(alloca(bcx,
1446-
llvariable_ty,
1447-
bcx.ident(ident).as_slice()));
1389+
llmatch = alloca(bcx,
1390+
llvariable_ty.ptr_to(),
1391+
bcx.ident(ident).as_slice());
1392+
trmode = TrByMove;
14481393
}
14491394
ast::BindByRef(_) => {
14501395
llmatch = alloca(bcx,
@@ -1530,20 +1475,9 @@ fn trans_match_inner<'a>(scope_cx: &'a Block<'a>,
15301475
for arm_data in arm_datas.iter() {
15311476
let mut bcx = arm_data.bodycx;
15321477

1533-
// If this arm has a guard, then the various by-value bindings have
1534-
// already been copied into their homes. If not, we do it here. This
1535-
// is just to reduce code space. See extensive comment at the start
1536-
// of the file for more details.
1537-
if arm_data.arm.guard.is_none() {
1538-
bcx = store_non_ref_bindings(bcx, &arm_data.bindings_map, None);
1539-
}
1540-
1541-
// insert bindings into the lllocals map and add cleanups
1542-
let cleanup_scope = fcx.push_custom_cleanup_scope();
1543-
bcx = insert_lllocals(bcx, &arm_data.bindings_map,
1544-
cleanup::CustomScope(cleanup_scope));
1478+
// insert bindings into the lllocals map
1479+
bcx = insert_lllocals(bcx, &arm_data.bindings_map);
15451480
bcx = expr::trans_into(bcx, &*arm_data.arm.body, dest);
1546-
bcx = fcx.pop_and_trans_custom_cleanup_scope(bcx, cleanup_scope);
15471481
arm_cxs.push(bcx);
15481482
}
15491483

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ pub fn trans_unboxing_shim(bcx: &Block,
261261
let function_type =
262262
ty::mk_bare_fn(tcx, method.fty.clone()).subst(tcx, &substs);
263263

264-
let function_name = tcx.map.with_path(method_id.node, |path| {
264+
let function_name = ty::with_path(tcx, method_id, |path| {
265265
link::mangle_internal_name_by_path_and_seq(path, "unboxing_shim")
266266
});
267267
let llfn = decl_internal_rust_fn(ccx,

0 commit comments

Comments
 (0)