Skip to content
This repository was archived by the owner on Jan 7, 2022. It is now read-only.

Commit 29bf888

Browse files
committed
Build a_orig during conversion to TIR to avoid another loop.
1 parent 2638cc9 commit 29bf888

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

src/librustc_yk_sections/emit_tir.rs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
3434
use rustc_data_structures::graph::dominators::DominatorFrontiers;
3535
use ykpack;
3636
use ykpack::LocalIndex as TirLocal;
37+
use rustc_data_structures::fx::FxHashSet;
3738

3839
const SECTION_NAME: &'static str = ".yk_tir";
3940
const TMP_EXT: &'static str = ".yk_tir.tmp";
@@ -53,6 +54,8 @@ struct ConvCx<'a, 'tcx, 'gcx> {
5354
tcx: &'a TyCtxt<'a, 'tcx, 'gcx>,
5455
/// Maps TIR variables to their definition sites.
5556
def_sites: RefCell<Vec<BitSet<BasicBlock>>>,
57+
/// Maps each block to the variable it defines. This is what Appel calls `A_{orig}`.
58+
block_defines: RefCell<IndexVec<BasicBlock, FxHashSet<TirLocal>>>,
5659
/// Monotonically increasing number used to give TIR variables a unique ID.
5760
next_tir_var: Cell<TirLocal>,
5861
/// A mapping from MIR variables to TIR variables.
@@ -64,13 +67,15 @@ struct ConvCx<'a, 'tcx, 'gcx> {
6467
impl<'a, 'tcx, 'gcx> ConvCx<'a, 'tcx, 'gcx> {
6568
fn new(tcx: &'a TyCtxt<'a, 'tcx, 'gcx>, mir: &Mir<'tcx>) -> Self {
6669
let var_map = IndexVec::new();
70+
let num_blks = mir.basic_blocks().len();
6771

6872
Self {
6973
tcx,
7074
def_sites: RefCell::new(Vec::new()),
75+
block_defines: RefCell::new(IndexVec::from_elem_n(FxHashSet::default(), num_blks)),
7176
next_tir_var: Cell::new(0),
7277
var_map: RefCell::new(var_map),
73-
num_blks: mir.basic_blocks().len(),
78+
num_blks: num_blks,
7479
}
7580
}
7681

@@ -101,8 +106,9 @@ impl<'a, 'tcx, 'gcx> ConvCx<'a, 'tcx, 'gcx> {
101106
})
102107
}
103108

104-
fn def_sites(self) -> Vec<BitSet<BasicBlock>> {
105-
self.def_sites.into_inner()
109+
/// Finalise the conversion context, returning the definition sites and block defines mappings.
110+
fn done(self) -> (Vec<BitSet<BasicBlock>>, IndexVec<BasicBlock, FxHashSet<TirLocal>>) {
111+
(self.def_sites.into_inner(), self.block_defines.into_inner())
106112
}
107113

108114
/// Add `bb` as a definition site of the TIR variable `var`.
@@ -118,6 +124,9 @@ impl<'a, 'tcx, 'gcx> ConvCx<'a, 'tcx, 'gcx> {
118124
BitSet::new_empty(self.num_blks));
119125
}
120126
sites[var_usize].insert(bb);
127+
128+
// Also push into the inverse mapping (blocks to defined vars).
129+
self.block_defines.borrow_mut()[bb].insert(var);
121130
}
122131
}
123132

@@ -186,7 +195,8 @@ fn do_generate_tir<'a, 'tcx, 'gcx>(
186195
let mut pack = (&ccx, def_id, tcx.optimized_mir(*def_id)).to_pack();
187196
{
188197
let ykpack::Pack::Mir(ykpack::Mir{ref mut blocks, ..}) = pack;
189-
insert_phis(blocks, mir, ccx.def_sites());
198+
let (def_sites, block_defines) = ccx.done();
199+
insert_phis(blocks, mir, def_sites, block_defines);
190200
}
191201

192202
// FIXME - rename variables with fresh SSA names.
@@ -213,27 +223,12 @@ fn do_generate_tir<'a, 'tcx, 'gcx>(
213223
/// Algorithm reference:
214224
/// Bottom of p406 of 'Modern Compiler Implementation in Java (2nd ed.)' by Andrew Appel.
215225
fn insert_phis(blocks: &mut Vec<ykpack::BasicBlock>, mir: &Mir,
216-
mut def_sites: Vec<BitSet<BasicBlock>>)
217-
{
226+
mut def_sites: Vec<BitSet<BasicBlock>>,
227+
a_orig: IndexVec<BasicBlock, FxHashSet<TirLocal>>) {
218228
let doms = mir.dominators();
219229
let df = DominatorFrontiers::new(mir, &doms);
220230
let num_tir_vars = def_sites.len();
221-
222-
// We first need a mapping from block to the variables it defines. Appel calls this
223-
// `A_{orig}`. We can derive this from our definition sites.
224-
let (a_orig, num_tir_blks) = {
225-
let num_tir_blks = blocks.len();
226-
227-
let mut a_orig: IndexVec<BasicBlock, BitSet<TirLocal>> =
228-
IndexVec::from_elem_n(BitSet::new_empty(num_tir_vars), num_tir_blks);
229-
for (a, def_blks) in def_sites.iter().enumerate() {
230-
for bb in def_blks.iter() {
231-
// `def_sites` is guaranteed to have at most `u32::max_value()` items.
232-
a_orig[bb].insert(a as u32);
233-
}
234-
}
235-
(a_orig, num_tir_blks)
236-
};
231+
let num_tir_blks = a_orig.len();
237232

238233
let mut a_phi: Vec<BitSet<TirLocal>> = Vec::with_capacity(num_tir_blks);
239234
a_phi.resize(num_tir_blks, BitSet::new_empty(num_tir_vars));
@@ -249,7 +244,7 @@ fn insert_phis(blocks: &mut Vec<ykpack::BasicBlock>, mir: &Mir,
249244
let a_u32 = a as u32;
250245
if !a_phi[y_usize].contains(a_u32) {
251246
a_phi[y_usize].insert(a_u32);
252-
if !a_orig[y].contains(a_u32) {
247+
if !a_orig[y].contains(&a_u32) {
253248
// The assertion in `tir_var()` has already checked the cast is safe.
254249
insert_phi(&mut blocks[y_usize], a as u32, mir.predecessors_for(y).len());
255250
w.insert(y);

0 commit comments

Comments
 (0)