Skip to content

Commit c911925

Browse files
committed
rustc_mir: implement visit_local instead/along visit_lvalue where possible.
1 parent 2f2b8b3 commit c911925

File tree

10 files changed

+217
-235
lines changed

10 files changed

+217
-235
lines changed

src/librustc/mir/visit.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ macro_rules! make_mir_visitor {
256256
}
257257

258258
fn visit_local(&mut self,
259-
_local: & $($mutability)* Local) {
259+
_local: & $($mutability)* Local,
260+
_context: LvalueContext<'tcx>,
261+
_location: Location) {
260262
}
261263

262264
fn visit_visibility_scope(&mut self,
@@ -610,7 +612,7 @@ macro_rules! make_mir_visitor {
610612
location: Location) {
611613
match *lvalue {
612614
Lvalue::Local(ref $($mutability)* local) => {
613-
self.visit_local(local);
615+
self.visit_local(local, context, location);
614616
}
615617
Lvalue::Static(ref $($mutability)* static_) => {
616618
self.visit_static(static_, context, location);

src/librustc_mir/transform/copy_prop.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,7 @@ impl<'tcx> Action<'tcx> {
236236
}
237237

238238
// Replace all uses of the destination local with the source local.
239-
let src_lvalue = Lvalue::Local(src_local);
240-
def_use_analysis.replace_all_defs_and_uses_with(dest_local, mir, src_lvalue);
239+
def_use_analysis.replace_all_defs_and_uses_with(dest_local, mir, src_local);
241240

242241
// Finally, zap the now-useless assignment instruction.
243242
debug!(" Deleting assignment");

src/librustc_mir/transform/generator.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ struct RenameLocalVisitor {
8888

8989
impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
9090
fn visit_local(&mut self,
91-
local: &mut Local) {
91+
local: &mut Local,
92+
_: LvalueContext<'tcx>,
93+
_: Location) {
9294
if *local == self.from {
9395
*local = self.to;
9496
}
@@ -98,6 +100,13 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
98100
struct DerefArgVisitor;
99101

100102
impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
103+
fn visit_local(&mut self,
104+
local: &mut Local,
105+
_: LvalueContext<'tcx>,
106+
_: Location) {
107+
assert_ne!(*local, self_arg());
108+
}
109+
101110
fn visit_lvalue(&mut self,
102111
lvalue: &mut Lvalue<'tcx>,
103112
context: LvalueContext<'tcx>,
@@ -177,6 +186,13 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
177186
}
178187

179188
impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
189+
fn visit_local(&mut self,
190+
local: &mut Local,
191+
_: LvalueContext<'tcx>,
192+
_: Location) {
193+
assert_eq!(self.remap.get(local), None);
194+
}
195+
180196
fn visit_lvalue(&mut self,
181197
lvalue: &mut Lvalue<'tcx>,
182198
context: LvalueContext<'tcx>,

src/librustc_mir/transform/inline.rs

+24-31
Original file line numberDiff line numberDiff line change
@@ -589,16 +589,6 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
589589
new
590590
}
591591

592-
fn update_local(&self, local: Local) -> Option<Local> {
593-
let idx = local.index();
594-
if idx < (self.args.len() + 1) {
595-
return None;
596-
}
597-
let idx = idx - (self.args.len() + 1);
598-
let local = Local::new(idx);
599-
self.local_map.get(local).cloned()
600-
}
601-
602592
fn arg_index(&self, arg: Local) -> Option<usize> {
603593
let idx = arg.index();
604594
if idx > 0 && idx <= self.args.len() {
@@ -610,32 +600,35 @@ impl<'a, 'tcx> Integrator<'a, 'tcx> {
610600
}
611601

612602
impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
603+
fn visit_local(&mut self,
604+
local: &mut Local,
605+
_ctxt: LvalueContext<'tcx>,
606+
_location: Location) {
607+
if *local == RETURN_POINTER {
608+
match self.destination {
609+
Lvalue::Local(l) => *local = l,
610+
ref lval => bug!("Return lvalue is {:?}, not local", lval)
611+
}
612+
}
613+
let idx = local.index() - 1;
614+
if idx < self.args.len() {
615+
match self.args[idx] {
616+
Operand::Consume(Lvalue::Local(l)) => *local = l,
617+
ref op => bug!("Arg operand `{:?}` is {:?}, not local", idx, op)
618+
}
619+
}
620+
*local = self.local_map[Local::new(idx - self.args.len())];
621+
}
622+
613623
fn visit_lvalue(&mut self,
614624
lvalue: &mut Lvalue<'tcx>,
615625
_ctxt: LvalueContext<'tcx>,
616626
_location: Location) {
617-
if let Lvalue::Local(ref mut local) = *lvalue {
618-
if let Some(l) = self.update_local(*local) {
619-
// Temp or Var; update the local reference
620-
*local = l;
621-
return;
622-
}
623-
}
624-
if let Lvalue::Local(local) = *lvalue {
625-
if local == RETURN_POINTER {
626-
// Return pointer; update the lvalue itself
627-
*lvalue = self.destination.clone();
628-
} else if local.index() < (self.args.len() + 1) {
629-
// Argument, once again update the the lvalue itself
630-
let idx = local.index() - 1;
631-
if let Operand::Consume(ref lval) = self.args[idx] {
632-
*lvalue = lval.clone();
633-
} else {
634-
bug!("Arg operand `{:?}` is not an Lvalue use.", idx)
635-
}
636-
}
627+
if let Lvalue::Local(RETURN_POINTER) = *lvalue {
628+
// Return pointer; update the lvalue itself
629+
*lvalue = self.destination.clone();
637630
} else {
638-
self.super_lvalue(lvalue, _ctxt, _location)
631+
self.super_lvalue(lvalue, _ctxt, _location);
639632
}
640633
}
641634

src/librustc_mir/transform/promote_consts.rs

+43-49
Original file line numberDiff line numberDiff line change
@@ -83,52 +83,49 @@ struct TempCollector<'tcx> {
8383
}
8484

8585
impl<'tcx> Visitor<'tcx> for TempCollector<'tcx> {
86-
fn visit_lvalue(&mut self,
87-
lvalue: &Lvalue<'tcx>,
88-
context: LvalueContext<'tcx>,
89-
location: Location) {
90-
self.super_lvalue(lvalue, context, location);
91-
if let Lvalue::Local(index) = *lvalue {
92-
// We're only interested in temporaries
93-
if self.mir.local_kind(index) != LocalKind::Temp {
94-
return;
95-
}
86+
fn visit_local(&mut self,
87+
&index: &Local,
88+
context: LvalueContext<'tcx>,
89+
location: Location) {
90+
// We're only interested in temporaries
91+
if self.mir.local_kind(index) != LocalKind::Temp {
92+
return;
93+
}
9694

97-
// Ignore drops, if the temp gets promoted,
98-
// then it's constant and thus drop is noop.
99-
// Storage live ranges are also irrelevant.
100-
if context.is_drop() || context.is_storage_marker() {
101-
return;
102-
}
95+
// Ignore drops, if the temp gets promoted,
96+
// then it's constant and thus drop is noop.
97+
// Storage live ranges are also irrelevant.
98+
if context.is_drop() || context.is_storage_marker() {
99+
return;
100+
}
103101

104-
let temp = &mut self.temps[index];
105-
if *temp == TempState::Undefined {
106-
match context {
107-
LvalueContext::Store |
108-
LvalueContext::Call => {
109-
*temp = TempState::Defined {
110-
location,
111-
uses: 0
112-
};
113-
return;
114-
}
115-
_ => { /* mark as unpromotable below */ }
116-
}
117-
} else if let TempState::Defined { ref mut uses, .. } = *temp {
118-
// We always allow borrows, even mutable ones, as we need
119-
// to promote mutable borrows of some ZSTs e.g. `&mut []`.
120-
let allowed_use = match context {
121-
LvalueContext::Borrow {..} => true,
122-
_ => context.is_nonmutating_use()
123-
};
124-
if allowed_use {
125-
*uses += 1;
102+
let temp = &mut self.temps[index];
103+
if *temp == TempState::Undefined {
104+
match context {
105+
LvalueContext::Store |
106+
LvalueContext::Call => {
107+
*temp = TempState::Defined {
108+
location,
109+
uses: 0
110+
};
126111
return;
127112
}
128-
/* mark as unpromotable below */
113+
_ => { /* mark as unpromotable below */ }
129114
}
130-
*temp = TempState::Unpromotable;
115+
} else if let TempState::Defined { ref mut uses, .. } = *temp {
116+
// We always allow borrows, even mutable ones, as we need
117+
// to promote mutable borrows of some ZSTs e.g. `&mut []`.
118+
let allowed_use = match context {
119+
LvalueContext::Borrow {..} => true,
120+
_ => context.is_nonmutating_use()
121+
};
122+
if allowed_use {
123+
*uses += 1;
124+
return;
125+
}
126+
/* mark as unpromotable below */
131127
}
128+
*temp = TempState::Unpromotable;
132129
}
133130

134131
fn visit_source_info(&mut self, source_info: &SourceInfo) {
@@ -326,16 +323,13 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
326323

327324
/// Replaces all temporaries with their promoted counterparts.
328325
impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
329-
fn visit_lvalue(&mut self,
330-
lvalue: &mut Lvalue<'tcx>,
331-
context: LvalueContext<'tcx>,
332-
location: Location) {
333-
if let Lvalue::Local(ref mut temp) = *lvalue {
334-
if self.source.local_kind(*temp) == LocalKind::Temp {
335-
*temp = self.promote_temp(*temp);
336-
}
326+
fn visit_local(&mut self,
327+
local: &mut Local,
328+
_: LvalueContext<'tcx>,
329+
_: Location) {
330+
if self.source.local_kind(*local) == LocalKind::Temp {
331+
*local = self.promote_temp(*local);
337332
}
338-
self.super_lvalue(lvalue, context, location);
339333
}
340334
}
341335

src/librustc_mir/transform/qualify_consts.rs

+29-22
Original file line numberDiff line numberDiff line change
@@ -499,33 +499,40 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
499499
/// For functions (constant or not), it also records
500500
/// candidates for promotion in promotion_candidates.
501501
impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
502+
fn visit_local(&mut self,
503+
&local: &Local,
504+
_: LvalueContext<'tcx>,
505+
_: Location) {
506+
match self.mir.local_kind(local) {
507+
LocalKind::ReturnPointer => {
508+
self.not_const();
509+
}
510+
LocalKind::Arg => {
511+
self.add(Qualif::FN_ARGUMENT);
512+
}
513+
LocalKind::Var => {
514+
self.add(Qualif::NOT_CONST);
515+
}
516+
LocalKind::Temp => {
517+
if !self.temp_promotion_state[local].is_promotable() {
518+
self.add(Qualif::NOT_PROMOTABLE);
519+
}
520+
521+
if let Some(qualif) = self.temp_qualif[local] {
522+
self.add(qualif);
523+
} else {
524+
self.not_const();
525+
}
526+
}
527+
}
528+
}
529+
502530
fn visit_lvalue(&mut self,
503531
lvalue: &Lvalue<'tcx>,
504532
context: LvalueContext<'tcx>,
505533
location: Location) {
506534
match *lvalue {
507-
Lvalue::Local(local) => match self.mir.local_kind(local) {
508-
LocalKind::ReturnPointer => {
509-
self.not_const();
510-
}
511-
LocalKind::Arg => {
512-
self.add(Qualif::FN_ARGUMENT);
513-
}
514-
LocalKind::Var => {
515-
self.add(Qualif::NOT_CONST);
516-
}
517-
LocalKind::Temp => {
518-
if !self.temp_promotion_state[local].is_promotable() {
519-
self.add(Qualif::NOT_PROMOTABLE);
520-
}
521-
522-
if let Some(qualif) = self.temp_qualif[local] {
523-
self.add(qualif);
524-
} else {
525-
self.not_const();
526-
}
527-
}
528-
},
535+
Lvalue::Local(ref local) => self.visit_local(local, context, location),
529536
Lvalue::Static(ref global) => {
530537
self.add(Qualif::STATIC);
531538

src/librustc_mir/transform/simplify.rs

+6-14
Original file line numberDiff line numberDiff line change
@@ -352,15 +352,11 @@ struct DeclMarker {
352352
}
353353

354354
impl<'tcx> Visitor<'tcx> for DeclMarker {
355-
fn visit_lvalue(&mut self, lval: &Lvalue<'tcx>, ctx: LvalueContext<'tcx>, loc: Location) {
356-
if ctx == LvalueContext::StorageLive || ctx == LvalueContext::StorageDead {
357-
// ignore these altogether, they get removed along with their otherwise unused decls.
358-
return;
355+
fn visit_local(&mut self, local: &Local, ctx: LvalueContext<'tcx>, _: Location) {
356+
// ignore these altogether, they get removed along with their otherwise unused decls.
357+
if ctx != LvalueContext::StorageLive && ctx != LvalueContext::StorageDead {
358+
self.locals.insert(local.index());
359359
}
360-
if let Lvalue::Local(ref v) = *lval {
361-
self.locals.insert(v.index());
362-
}
363-
self.super_lvalue(lval, ctx, loc);
364360
}
365361
}
366362

@@ -384,11 +380,7 @@ impl<'tcx> MutVisitor<'tcx> for LocalUpdater {
384380
});
385381
self.super_basic_block_data(block, data);
386382
}
387-
fn visit_lvalue(&mut self, lval: &mut Lvalue<'tcx>, ctx: LvalueContext<'tcx>, loc: Location) {
388-
match *lval {
389-
Lvalue::Local(ref mut l) => *l = Local::new(self.map[l.index()]),
390-
_ => (),
391-
};
392-
self.super_lvalue(lval, ctx, loc);
383+
fn visit_local(&mut self, l: &mut Local, _: LvalueContext<'tcx>, _: Location) {
384+
*l = Local::new(self.map[l.index()]);
393385
}
394386
}

0 commit comments

Comments
 (0)