Skip to content

Commit 57d3897

Browse files
committed
liveness: Use newtype_index for Variable and LiveNode
1 parent 49d1ce0 commit 57d3897

File tree

4 files changed

+47
-66
lines changed

4 files changed

+47
-66
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3891,6 +3891,7 @@ dependencies = [
38913891
"rustc_hir",
38923892
"rustc_index",
38933893
"rustc_middle",
3894+
"rustc_serialize",
38943895
"rustc_session",
38953896
"rustc_span",
38963897
"rustc_target",

compiler/rustc_passes/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ rustc_index = { path = "../rustc_index" }
1515
rustc_session = { path = "../rustc_session" }
1616
rustc_target = { path = "../rustc_target" }
1717
rustc_ast = { path = "../rustc_ast" }
18+
rustc_serialize = { path = "../rustc_serialize" }
1819
rustc_span = { path = "../rustc_span" }
1920
rustc_trait_selection = { path = "../rustc_trait_selection" }

compiler/rustc_passes/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
//! This API is completely unstable and subject to change.
66
77
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
8+
#![feature(const_fn)]
9+
#![feature(const_panic)]
810
#![feature(in_band_lifetimes)]
911
#![feature(nll)]
1012
#![feature(or_patterns)]

compiler/rustc_passes/src/liveness.rs

+43-66
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@
6262
//! - `reader`: the `LiveNode` ID of some node which will read the value
6363
//! that `V` holds on entry to `N`. Formally: a node `M` such
6464
//! that there exists a path `P` from `N` to `M` where `P` does not
65-
//! write `V`. If the `reader` is `invalid_node()`, then the current
65+
//! write `V`. If the `reader` is `INVALID_NODE`, then the current
6666
//! value will never be read (the variable is dead, essentially).
6767
//!
6868
//! - `writer`: the `LiveNode` ID of some node which will write the
6969
//! variable `V` and which is reachable from `N`. Formally: a node `M`
7070
//! such that there exists a path `P` from `N` to `M` and `M` writes
71-
//! `V`. If the `writer` is `invalid_node()`, then there is no writer
71+
//! `V`. If the `writer` is `INVALID_NODE`, then there is no writer
7272
//! of `V` that follows `N`.
7373
//!
7474
//! - `used`: a boolean value indicating whether `V` is *used*. We
@@ -92,6 +92,7 @@ use rustc_hir::def::*;
9292
use rustc_hir::def_id::LocalDefId;
9393
use rustc_hir::intravisit::{self, FnKind, NestedVisitorMap, Visitor};
9494
use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, Node};
95+
use rustc_index::vec::IndexVec;
9596
use rustc_middle::hir::map::Map;
9697
use rustc_middle::ty::query::Providers;
9798
use rustc_middle::ty::{self, TyCtxt};
@@ -100,26 +101,20 @@ use rustc_span::symbol::{kw, sym, Symbol};
100101
use rustc_span::Span;
101102

102103
use std::collections::VecDeque;
103-
use std::fmt;
104104
use std::io;
105105
use std::io::prelude::*;
106106
use std::rc::Rc;
107107

108-
#[derive(Copy, Clone, PartialEq)]
109-
struct Variable(u32);
110-
111-
#[derive(Copy, Clone, PartialEq)]
112-
struct LiveNode(u32);
113-
114-
impl Variable {
115-
fn get(&self) -> usize {
116-
self.0 as usize
108+
rustc_index::newtype_index! {
109+
pub struct Variable {
110+
DEBUG_FORMAT = "v({})",
117111
}
118112
}
119113

120-
impl LiveNode {
121-
fn get(&self) -> usize {
122-
self.0 as usize
114+
rustc_index::newtype_index! {
115+
pub struct LiveNode {
116+
DEBUG_FORMAT = "ln({})",
117+
const INVALID_NODE = LiveNode::MAX_AS_U32,
123118
}
124119
}
125120

@@ -183,18 +178,6 @@ pub fn provide(providers: &mut Providers) {
183178
*providers = Providers { check_mod_liveness, ..*providers };
184179
}
185180

186-
impl fmt::Debug for LiveNode {
187-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188-
write!(f, "ln({})", self.get())
189-
}
190-
}
191-
192-
impl fmt::Debug for Variable {
193-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194-
write!(f, "v({})", self.get())
195-
}
196-
}
197-
198181
// ______________________________________________________________________
199182
// Creating ir_maps
200183
//
@@ -218,15 +201,11 @@ impl fmt::Debug for Variable {
218201
// assignment. And so forth.
219202

220203
impl LiveNode {
221-
fn is_valid(&self) -> bool {
222-
self.0 != u32::MAX
204+
fn is_valid(self) -> bool {
205+
self != INVALID_NODE
223206
}
224207
}
225208

226-
fn invalid_node() -> LiveNode {
227-
LiveNode(u32::MAX)
228-
}
229-
230209
struct CaptureInfo {
231210
ln: LiveNode,
232211
var_hid: HirId,
@@ -252,8 +231,8 @@ struct IrMaps<'tcx> {
252231
live_node_map: HirIdMap<LiveNode>,
253232
variable_map: HirIdMap<Variable>,
254233
capture_info_map: HirIdMap<Rc<Vec<CaptureInfo>>>,
255-
var_kinds: Vec<VarKind>,
256-
lnks: Vec<LiveNodeKind>,
234+
var_kinds: IndexVec<Variable, VarKind>,
235+
lnks: IndexVec<LiveNode, LiveNodeKind>,
257236
}
258237

259238
impl IrMaps<'tcx> {
@@ -264,14 +243,13 @@ impl IrMaps<'tcx> {
264243
live_node_map: HirIdMap::default(),
265244
variable_map: HirIdMap::default(),
266245
capture_info_map: Default::default(),
267-
var_kinds: Vec::new(),
268-
lnks: Vec::new(),
246+
var_kinds: IndexVec::new(),
247+
lnks: IndexVec::new(),
269248
}
270249
}
271250

272251
fn add_live_node(&mut self, lnk: LiveNodeKind) -> LiveNode {
273-
let ln = LiveNode(self.lnks.len() as u32);
274-
self.lnks.push(lnk);
252+
let ln = self.lnks.push(lnk);
275253

276254
debug!("{:?} is of kind {}", ln, live_node_kind_to_string(lnk, self.tcx));
277255

@@ -286,8 +264,7 @@ impl IrMaps<'tcx> {
286264
}
287265

288266
fn add_variable(&mut self, vk: VarKind) -> Variable {
289-
let v = Variable(self.var_kinds.len() as u32);
290-
self.var_kinds.push(vk);
267+
let v = self.var_kinds.push(vk);
291268

292269
match vk {
293270
Local(LocalInfo { id: node_id, .. }) | Param(node_id, _) | Upvar(node_id, _) => {
@@ -310,13 +287,13 @@ impl IrMaps<'tcx> {
310287
}
311288

312289
fn variable_name(&self, var: Variable) -> Symbol {
313-
match self.var_kinds[var.get()] {
290+
match self.var_kinds[var] {
314291
Local(LocalInfo { name, .. }) | Param(_, name) | Upvar(_, name) => name,
315292
}
316293
}
317294

318295
fn variable_is_shorthand(&self, var: Variable) -> bool {
319-
match self.var_kinds[var.get()] {
296+
match self.var_kinds[var] {
320297
Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
321298
Param(..) | Upvar(..) => false,
322299
}
@@ -327,7 +304,7 @@ impl IrMaps<'tcx> {
327304
}
328305

329306
fn lnk(&self, ln: LiveNode) -> LiveNodeKind {
330-
self.lnks[ln.get()]
307+
self.lnks[ln]
331308
}
332309
}
333310

@@ -556,10 +533,10 @@ struct RWUTable {
556533
unpacked_rwus: Vec<RWU>,
557534
}
558535

559-
// A constant representing `RWU { reader: invalid_node(); writer: invalid_node(); used: false }`.
536+
// A constant representing `RWU { reader: INVALID_NODE; writer: INVALID_NODE; used: false }`.
560537
const INV_INV_FALSE: u32 = u32::MAX;
561538

562-
// A constant representing `RWU { reader: invalid_node(); writer: invalid_node(); used: true }`.
539+
// A constant representing `RWU { reader: INVALID_NODE; writer: INVALID_NODE; used: true }`.
563540
const INV_INV_TRUE: u32 = u32::MAX - 1;
564541

565542
impl RWUTable {
@@ -570,24 +547,24 @@ impl RWUTable {
570547
fn get(&self, idx: usize) -> RWU {
571548
let packed_rwu = self.packed_rwus[idx];
572549
match packed_rwu {
573-
INV_INV_FALSE => RWU { reader: invalid_node(), writer: invalid_node(), used: false },
574-
INV_INV_TRUE => RWU { reader: invalid_node(), writer: invalid_node(), used: true },
550+
INV_INV_FALSE => RWU { reader: INVALID_NODE, writer: INVALID_NODE, used: false },
551+
INV_INV_TRUE => RWU { reader: INVALID_NODE, writer: INVALID_NODE, used: true },
575552
_ => self.unpacked_rwus[packed_rwu as usize],
576553
}
577554
}
578555

579556
fn get_reader(&self, idx: usize) -> LiveNode {
580557
let packed_rwu = self.packed_rwus[idx];
581558
match packed_rwu {
582-
INV_INV_FALSE | INV_INV_TRUE => invalid_node(),
559+
INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE,
583560
_ => self.unpacked_rwus[packed_rwu as usize].reader,
584561
}
585562
}
586563

587564
fn get_writer(&self, idx: usize) -> LiveNode {
588565
let packed_rwu = self.packed_rwus[idx];
589566
match packed_rwu {
590-
INV_INV_FALSE | INV_INV_TRUE => invalid_node(),
567+
INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE,
591568
_ => self.unpacked_rwus[packed_rwu as usize].writer,
592569
}
593570
}
@@ -607,7 +584,7 @@ impl RWUTable {
607584
}
608585

609586
fn assign_unpacked(&mut self, idx: usize, rwu: RWU) {
610-
if rwu.reader == invalid_node() && rwu.writer == invalid_node() {
587+
if rwu.reader == INVALID_NODE && rwu.writer == INVALID_NODE {
611588
// When we overwrite an indexing entry in `self.packed_rwus` with
612589
// `INV_INV_{TRUE,FALSE}` we don't remove the corresponding entry
613590
// from `self.unpacked_rwus`; it's not worth the effort, and we
@@ -634,7 +611,7 @@ struct Liveness<'a, 'tcx> {
634611
ir: &'a mut IrMaps<'tcx>,
635612
typeck_results: &'a ty::TypeckResults<'tcx>,
636613
param_env: ty::ParamEnv<'tcx>,
637-
successors: Vec<LiveNode>,
614+
successors: IndexVec<LiveNode, LiveNode>,
638615
rwu_table: RWUTable,
639616

640617
/// A live node representing a point of execution before closure entry &
@@ -667,7 +644,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
667644
ir,
668645
typeck_results,
669646
param_env,
670-
successors: vec![invalid_node(); num_live_nodes],
647+
successors: IndexVec::from_elem_n(INVALID_NODE, num_live_nodes),
671648
rwu_table: RWUTable::new(num_live_nodes * num_vars),
672649
closure_ln,
673650
exit_ln,
@@ -708,7 +685,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
708685
}
709686

710687
fn idx(&self, ln: LiveNode, var: Variable) -> usize {
711-
ln.get() * self.ir.var_kinds.len() + var.get()
688+
ln.index() * self.ir.var_kinds.len() + var.index()
712689
}
713690

714691
fn live_on_entry(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
@@ -719,7 +696,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
719696

720697
// Is this variable live on entry to any of its successor nodes?
721698
fn live_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
722-
let successor = self.successors[ln.get()];
699+
let successor = self.successors[ln];
723700
self.live_on_entry(successor, var)
724701
}
725702

@@ -735,16 +712,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
735712
}
736713

737714
fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> Option<LiveNodeKind> {
738-
let successor = self.successors[ln.get()];
715+
let successor = self.successors[ln];
739716
self.assigned_on_entry(successor, var)
740717
}
741718

742719
fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F)
743720
where
744721
F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
745722
{
746-
let node_base_idx = self.idx(ln, Variable(0));
747-
let succ_base_idx = self.idx(succ_ln, Variable(0));
723+
let node_base_idx = self.idx(ln, Variable::from(0u32));
724+
let succ_base_idx = self.idx(succ_ln, Variable::from(0u32));
748725
for var_idx in 0..self.ir.var_kinds.len() {
749726
op(self, node_base_idx + var_idx, succ_base_idx + var_idx);
750727
}
@@ -754,11 +731,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
754731
where
755732
F: FnMut(usize) -> bool,
756733
{
757-
let node_base_idx = self.idx(ln, Variable(0));
734+
let node_base_idx = self.idx(ln, Variable::from(0u32));
758735
for var_idx in 0..self.ir.var_kinds.len() {
759736
let idx = node_base_idx + var_idx;
760737
if test(idx) {
761-
write!(wr, " {:?}", Variable(var_idx as u32))?;
738+
write!(wr, " {:?}", Variable::from(var_idx))?;
762739
}
763740
}
764741
Ok(())
@@ -769,14 +746,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
769746
let mut wr = Vec::new();
770747
{
771748
let wr = &mut wr as &mut dyn Write;
772-
write!(wr, "[ln({:?}) of kind {:?} reads", ln.get(), self.ir.lnk(ln));
749+
write!(wr, "[{:?} of kind {:?} reads", ln, self.ir.lnk(ln));
773750
self.write_vars(wr, ln, |idx| self.rwu_table.get_reader(idx).is_valid());
774751
write!(wr, " writes");
775752
self.write_vars(wr, ln, |idx| self.rwu_table.get_writer(idx).is_valid());
776753
write!(wr, " uses");
777754
self.write_vars(wr, ln, |idx| self.rwu_table.get_used(idx));
778755

779-
write!(wr, " precedes {:?}]", self.successors[ln.get()]);
756+
write!(wr, " precedes {:?}]", self.successors[ln]);
780757
}
781758
String::from_utf8(wr).unwrap()
782759
}
@@ -787,7 +764,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
787764
"^^ liveness computation results for body {} (entry={:?})",
788765
{
789766
for ln_idx in 0..self.ir.lnks.len() {
790-
debug!("{:?}", self.ln_str(LiveNode(ln_idx as u32)));
767+
debug!("{:?}", self.ln_str(LiveNode::from(ln_idx)));
791768
}
792769
hir_id
793770
},
@@ -796,7 +773,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
796773
}
797774

798775
fn init_empty(&mut self, ln: LiveNode, succ_ln: LiveNode) {
799-
self.successors[ln.get()] = succ_ln;
776+
self.successors[ln] = succ_ln;
800777

801778
// It is not necessary to initialize the RWUs here because they are all
802779
// set to INV_INV_FALSE when they are created, and the sets only grow
@@ -805,7 +782,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
805782

806783
fn init_from_succ(&mut self, ln: LiveNode, succ_ln: LiveNode) {
807784
// more efficient version of init_empty() / merge_from_succ()
808-
self.successors[ln.get()] = succ_ln;
785+
self.successors[ln] = succ_ln;
809786

810787
self.indices2(ln, succ_ln, |this, idx, succ_idx| {
811788
this.rwu_table.copy_packed(idx, succ_idx);
@@ -878,7 +855,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
878855
let mut rwu = self.rwu_table.get(idx);
879856

880857
if (acc & ACC_WRITE) != 0 {
881-
rwu.reader = invalid_node();
858+
rwu.reader = INVALID_NODE;
882859
rwu.writer = ln;
883860
}
884861

0 commit comments

Comments
 (0)