Skip to content

Commit cfe22fa

Browse files
committed
---
yaml --- r: 277416 b: refs/heads/try c: c2de80f h: refs/heads/master
1 parent 4d6086f commit cfe22fa

File tree

8 files changed

+164
-143
lines changed

8 files changed

+164
-143
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 6dbb0e86aec11050480beb76eade6fb805010ba7
33
refs/heads/snap-stage3: 235d77457d80b549dad3ac36d94f235208a1eafb
4-
refs/heads/try: f242fe3c04621dca3aaa3ab288a3812b45633ffd
4+
refs/heads/try: c2de80f05fe32bdb694c085b48a87727175e3691
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/librustc_mir/build/block.rs

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
// except according to those terms.
1010

1111
use build::{BlockAnd, BlockAndExtension, Builder};
12-
use build::scope::LoopScope;
1312
use hair::*;
14-
use rustc::middle::region::CodeExtent;
1513
use rustc::mir::repr::*;
1614
use rustc::hir;
17-
use syntax::codemap::Span;
1815

1916
impl<'a,'tcx> Builder<'a,'tcx> {
2017
pub fn ast_block(&mut self,
@@ -82,118 +79,4 @@ impl<'a,'tcx> Builder<'a,'tcx> {
8279
block.unit()
8380
})
8481
}
85-
86-
pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()> {
87-
let this = self;
88-
let expr_span = expr.span;
89-
let scope_id = this.innermost_scope_id();
90-
// Handle a number of expressions that don't need a destination at all. This
91-
// avoids needing a mountain of temporary `()` variables.
92-
match expr.kind {
93-
ExprKind::Scope { extent, value } => {
94-
let value = this.hir.mirror(value);
95-
this.in_scope(extent, block, |this, _| this.stmt_expr(block, value))
96-
}
97-
ExprKind::Assign { lhs, rhs } => {
98-
let lhs = this.hir.mirror(lhs);
99-
let scope_id = this.innermost_scope_id();
100-
let lhs_span = lhs.span;
101-
let lhs_ty = lhs.ty;
102-
103-
let lhs_needs_drop = this.hir.needs_drop(lhs_ty);
104-
105-
// Note: we evaluate assignments right-to-left. This
106-
// is better for borrowck interaction with overloaded
107-
// operators like x[j] = x[i].
108-
109-
// Generate better code for things that don't need to be
110-
// dropped. We need the temporary as_operand generates
111-
// so we can clean up the data if evaluating the LHS unwinds,
112-
// but if the LHS (and therefore the RHS) doesn't need
113-
// unwinding, we just translate directly to an rvalue instead.
114-
let rhs = if lhs_needs_drop {
115-
let op = unpack!(block = this.as_operand(block, rhs));
116-
Rvalue::Use(op)
117-
} else {
118-
unpack!(block = this.as_rvalue(block, rhs))
119-
};
120-
121-
let lhs = unpack!(block = this.as_lvalue(block, lhs));
122-
unpack!(block = this.build_drop(block, lhs_span, lhs.clone(), lhs_ty));
123-
this.cfg.push_assign(block, scope_id, expr_span, &lhs, rhs);
124-
block.unit()
125-
}
126-
ExprKind::AssignOp { op, lhs, rhs } => {
127-
// FIXME(#28160) there is an interesting semantics
128-
// question raised here -- should we "freeze" the
129-
// value of the lhs here? I'm inclined to think not,
130-
// since it seems closer to the semantics of the
131-
// overloaded version, which takes `&mut self`. This
132-
// only affects weird things like `x += {x += 1; x}`
133-
// -- is that equal to `x + (x + 1)` or `2*(x+1)`?
134-
135-
// As above, RTL.
136-
let rhs = unpack!(block = this.as_operand(block, rhs));
137-
let lhs = unpack!(block = this.as_lvalue(block, lhs));
138-
139-
// we don't have to drop prior contents or anything
140-
// because AssignOp is only legal for Copy types
141-
// (overloaded ops should be desugared into a call).
142-
this.cfg.push_assign(block, scope_id, expr_span, &lhs,
143-
Rvalue::BinaryOp(op,
144-
Operand::Consume(lhs.clone()),
145-
rhs));
146-
147-
block.unit()
148-
}
149-
ExprKind::Continue { label } => {
150-
this.break_or_continue(expr_span, label, block,
151-
|loop_scope| loop_scope.continue_block)
152-
}
153-
ExprKind::Break { label } => {
154-
this.break_or_continue(expr_span, label, block, |loop_scope| {
155-
loop_scope.might_break = true;
156-
loop_scope.break_block
157-
})
158-
}
159-
ExprKind::Return { value } => {
160-
block = match value {
161-
Some(value) => unpack!(this.into(&Lvalue::ReturnPointer, block, value)),
162-
None => {
163-
this.cfg.push_assign_unit(block, scope_id,
164-
expr_span, &Lvalue::ReturnPointer);
165-
block
166-
}
167-
};
168-
let extent = this.extent_of_return_scope();
169-
let return_block = this.return_block();
170-
this.exit_scope(expr_span, extent, block, return_block);
171-
this.cfg.start_new_block().unit()
172-
}
173-
_ => {
174-
let expr_span = expr.span;
175-
let expr_ty = expr.ty;
176-
let temp = this.temp(expr.ty.clone());
177-
unpack!(block = this.into(&temp, block, expr));
178-
unpack!(block = this.build_drop(block, expr_span, temp, expr_ty));
179-
block.unit()
180-
}
181-
}
182-
}
183-
184-
fn break_or_continue<F>(&mut self,
185-
span: Span,
186-
label: Option<CodeExtent>,
187-
block: BasicBlock,
188-
exit_selector: F)
189-
-> BlockAnd<()>
190-
where F: FnOnce(&mut LoopScope) -> BasicBlock
191-
{
192-
let (exit_block, extent) = {
193-
let loop_scope = self.find_loop_scope(span, label);
194-
(exit_selector(loop_scope), loop_scope.extent)
195-
};
196-
self.exit_scope(span, extent, block, exit_block);
197-
self.cfg.start_new_block().unit()
198-
}
19982
}

branches/try/src/librustc_mir/build/expr/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,6 @@ mod as_lvalue;
7575
mod as_rvalue;
7676
mod as_operand;
7777
mod as_temp;
78-
pub mod category;
78+
mod category;
7979
mod into;
80+
mod stmt;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use build::{BlockAnd, BlockAndExtension, Builder};
12+
use build::scope::LoopScope;
13+
use hair::*;
14+
use rustc::middle::region::CodeExtent;
15+
use rustc::mir::repr::*;
16+
use syntax::codemap::Span;
17+
18+
impl<'a,'tcx> Builder<'a,'tcx> {
19+
20+
pub fn stmt_expr(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<()> {
21+
let this = self;
22+
let expr_span = expr.span;
23+
let scope_id = this.innermost_scope_id();
24+
// Handle a number of expressions that don't need a destination at all. This
25+
// avoids needing a mountain of temporary `()` variables.
26+
match expr.kind {
27+
ExprKind::Scope { extent, value } => {
28+
let value = this.hir.mirror(value);
29+
this.in_scope(extent, block, |this, _| this.stmt_expr(block, value))
30+
}
31+
ExprKind::Assign { lhs, rhs } => {
32+
let lhs = this.hir.mirror(lhs);
33+
let rhs = this.hir.mirror(rhs);
34+
let scope_id = this.innermost_scope_id();
35+
let lhs_span = lhs.span;
36+
37+
let lhs_ty = lhs.ty;
38+
let rhs_ty = rhs.ty;
39+
40+
let lhs_needs_drop = this.hir.needs_drop(lhs_ty);
41+
let rhs_needs_drop = this.hir.needs_drop(rhs_ty);
42+
43+
// Note: we evaluate assignments right-to-left. This
44+
// is better for borrowck interaction with overloaded
45+
// operators like x[j] = x[i].
46+
47+
// Generate better code for things that don't need to be
48+
// dropped.
49+
let rhs = if lhs_needs_drop || rhs_needs_drop {
50+
let op = unpack!(block = this.as_operand(block, rhs));
51+
Rvalue::Use(op)
52+
} else {
53+
unpack!(block = this.as_rvalue(block, rhs))
54+
};
55+
56+
let lhs = unpack!(block = this.as_lvalue(block, lhs));
57+
unpack!(block = this.build_drop(block, lhs_span, lhs.clone(), lhs_ty));
58+
this.cfg.push_assign(block, scope_id, expr_span, &lhs, rhs);
59+
block.unit()
60+
}
61+
ExprKind::AssignOp { op, lhs, rhs } => {
62+
// FIXME(#28160) there is an interesting semantics
63+
// question raised here -- should we "freeze" the
64+
// value of the lhs here? I'm inclined to think not,
65+
// since it seems closer to the semantics of the
66+
// overloaded version, which takes `&mut self`. This
67+
// only affects weird things like `x += {x += 1; x}`
68+
// -- is that equal to `x + (x + 1)` or `2*(x+1)`?
69+
70+
// As above, RTL.
71+
let rhs = unpack!(block = this.as_operand(block, rhs));
72+
let lhs = unpack!(block = this.as_lvalue(block, lhs));
73+
74+
// we don't have to drop prior contents or anything
75+
// because AssignOp is only legal for Copy types
76+
// (overloaded ops should be desugared into a call).
77+
this.cfg.push_assign(block, scope_id, expr_span, &lhs,
78+
Rvalue::BinaryOp(op,
79+
Operand::Consume(lhs.clone()),
80+
rhs));
81+
82+
block.unit()
83+
}
84+
ExprKind::Continue { label } => {
85+
this.break_or_continue(expr_span, label, block,
86+
|loop_scope| loop_scope.continue_block)
87+
}
88+
ExprKind::Break { label } => {
89+
this.break_or_continue(expr_span, label, block, |loop_scope| {
90+
loop_scope.might_break = true;
91+
loop_scope.break_block
92+
})
93+
}
94+
ExprKind::Return { value } => {
95+
block = match value {
96+
Some(value) => unpack!(this.into(&Lvalue::ReturnPointer, block, value)),
97+
None => {
98+
this.cfg.push_assign_unit(block, scope_id,
99+
expr_span, &Lvalue::ReturnPointer);
100+
block
101+
}
102+
};
103+
let extent = this.extent_of_return_scope();
104+
let return_block = this.return_block();
105+
this.exit_scope(expr_span, extent, block, return_block);
106+
this.cfg.start_new_block().unit()
107+
}
108+
_ => {
109+
let expr_span = expr.span;
110+
let expr_ty = expr.ty;
111+
let temp = this.temp(expr.ty.clone());
112+
unpack!(block = this.into(&temp, block, expr));
113+
unpack!(block = this.build_drop(block, expr_span, temp, expr_ty));
114+
block.unit()
115+
}
116+
}
117+
}
118+
119+
fn break_or_continue<F>(&mut self,
120+
span: Span,
121+
label: Option<CodeExtent>,
122+
block: BasicBlock,
123+
exit_selector: F)
124+
-> BlockAnd<()>
125+
where F: FnOnce(&mut LoopScope) -> BasicBlock
126+
{
127+
let (exit_block, extent) = {
128+
let loop_scope = self.find_loop_scope(span, label);
129+
(exit_selector(loop_scope), loop_scope.extent)
130+
};
131+
self.exit_scope(span, extent, block, exit_block);
132+
self.cfg.start_new_block().unit()
133+
}
134+
135+
}

branches/try/src/librustc_trans/mir/analyze.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
use rustc_data_structures::bitvec::BitVector;
1515
use rustc::mir::repr as mir;
1616
use rustc::mir::visit::{Visitor, LvalueContext};
17-
use common::{self, Block};
17+
use common::{self, Block, BlockAndBuilder};
1818
use super::rvalue;
1919

2020
pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
21-
mir: &mir::Mir<'tcx>)
22-
-> BitVector {
23-
let mut analyzer = TempAnalyzer::new(mir, bcx, mir.temp_decls.len());
21+
mir: &mir::Mir<'tcx>) -> BitVector {
22+
let bcx = bcx.build();
23+
let mut analyzer = TempAnalyzer::new(mir, &bcx, mir.temp_decls.len());
2424

2525
analyzer.visit_mir(mir);
2626

@@ -51,16 +51,16 @@ pub fn lvalue_temps<'bcx,'tcx>(bcx: Block<'bcx,'tcx>,
5151
analyzer.lvalue_temps
5252
}
5353

54-
struct TempAnalyzer<'mir, 'bcx, 'tcx: 'mir + 'bcx> {
54+
struct TempAnalyzer<'mir, 'bcx: 'mir, 'tcx: 'bcx> {
5555
mir: &'mir mir::Mir<'tcx>,
56-
bcx: Block<'bcx, 'tcx>,
56+
bcx: &'mir BlockAndBuilder<'bcx, 'tcx>,
5757
lvalue_temps: BitVector,
5858
seen_assigned: BitVector
5959
}
6060

6161
impl<'mir, 'bcx, 'tcx> TempAnalyzer<'mir, 'bcx, 'tcx> {
6262
fn new(mir: &'mir mir::Mir<'tcx>,
63-
bcx: Block<'bcx, 'tcx>,
63+
bcx: &'mir BlockAndBuilder<'bcx, 'tcx>,
6464
temp_count: usize) -> TempAnalyzer<'mir, 'bcx, 'tcx> {
6565
TempAnalyzer {
6666
mir: mir,

branches/try/src/librustc_trans/mir/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ enum TempRef<'tcx> {
108108
Operand(Option<OperandRef<'tcx>>),
109109
}
110110

111+
impl<'tcx> TempRef<'tcx> {
112+
fn new_operand(val: OperandValue, ty: ty::Ty<'tcx>) -> TempRef<'tcx> {
113+
let op = OperandRef {
114+
val: val,
115+
ty: ty
116+
};
117+
TempRef::Operand(Some(op))
118+
}
119+
}
120+
111121
///////////////////////////////////////////////////////////////////////////
112122

113123
pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
@@ -154,11 +164,8 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
154164
// Zero-size temporaries aren't always initialized, which
155165
// doesn't matter because they don't contain data, but
156166
// we need something in the operand.
157-
let op = OperandRef {
158-
val: OperandValue::Immediate(common::C_nil(bcx.ccx())),
159-
ty: mty
160-
};
161-
TempRef::Operand(Some(op))
167+
let val = OperandValue::Immediate(common::C_nil(bcx.ccx()));
168+
TempRef::new_operand(val, mty)
162169
} else {
163170
// If this is an immediate temp, we do not create an
164171
// alloca in advance. Instead we wait until we see the

branches/try/src/librustc_trans/mir/rvalue.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc::mir::repr as mir;
1818
use asm;
1919
use base;
2020
use callee::Callee;
21-
use common::{self, C_uint, Block, BlockAndBuilder, Result};
21+
use common::{self, C_uint, BlockAndBuilder, Result};
2222
use datum::{Datum, Lvalue};
2323
use debuginfo::DebugLoc;
2424
use declare;
@@ -218,9 +218,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
218218
}
219219

220220
_ => {
221-
bcx.with_block(|bcx| {
222-
assert!(rvalue_creates_operand(&self.mir, bcx, rvalue));
223-
});
221+
assert!(rvalue_creates_operand(&self.mir, &bcx, rvalue));
224222
let (bcx, temp) = self.trans_rvalue_operand(bcx, rvalue, debug_loc);
225223
self.store_operand(&bcx, dest.llval, temp);
226224
bcx
@@ -234,10 +232,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
234232
debug_loc: DebugLoc)
235233
-> (BlockAndBuilder<'bcx, 'tcx>, OperandRef<'tcx>)
236234
{
237-
bcx.with_block(|bcx| {
238-
assert!(rvalue_creates_operand(&self.mir, bcx, rvalue),
239-
"cannot trans {:?} to operand", rvalue);
240-
});
235+
assert!(rvalue_creates_operand(&self.mir, &bcx, rvalue),
236+
"cannot trans {:?} to operand", rvalue);
241237

242238
match *rvalue {
243239
mir::Rvalue::Cast(ref kind, ref source, cast_ty) => {
@@ -608,7 +604,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
608604
}
609605
}
610606

611-
pub fn rvalue_creates_operand<'bcx, 'tcx>(mir: &mir::Mir<'tcx>, bcx: Block<'bcx, 'tcx>,
607+
pub fn rvalue_creates_operand<'bcx, 'tcx>(mir: &mir::Mir<'tcx>,
608+
bcx: &BlockAndBuilder<'bcx, 'tcx>,
612609
rvalue: &mir::Rvalue<'tcx>) -> bool {
613610
match *rvalue {
614611
mir::Rvalue::Ref(..) |

0 commit comments

Comments
 (0)