Skip to content

Commit e530854

Browse files
authored
Move edits out of Env (#143)
* Move edits out of Env Return move edits from `resolve_inserted_moves` instead of eagerly allocating that vector in `Env`. * Move the final edit iteration into a method on Edits * Make fields on Edits private, and add a sort method
1 parent 24c1180 commit e530854

3 files changed

Lines changed: 59 additions & 27 deletions

File tree

src/ion/data_structures.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ pub struct Env<'a, F: Function> {
433433
pub multi_fixed_reg_fixups: Vec<MultiFixedRegFixup>,
434434

435435
// Output:
436-
pub edits: Vec<(PosWithPrio, Edit)>,
437436
pub allocs: Vec<Allocation>,
438437
pub inst_alloc_offsets: Vec<u32>,
439438
pub num_spillslots: u32,
@@ -692,6 +691,51 @@ impl InsertedMoves {
692691
}
693692
}
694693

694+
#[derive(Clone, Debug)]
695+
pub struct Edits {
696+
edits: Vec<(PosWithPrio, Edit)>,
697+
}
698+
699+
impl Edits {
700+
#[inline(always)]
701+
pub fn with_capacity(n: usize) -> Self {
702+
Self {
703+
edits: Vec::with_capacity(n),
704+
}
705+
}
706+
707+
#[inline(always)]
708+
pub fn len(&self) -> usize {
709+
self.edits.len()
710+
}
711+
712+
#[inline(always)]
713+
pub fn iter(&self) -> impl Iterator<Item = &(PosWithPrio, Edit)> {
714+
self.edits.iter()
715+
}
716+
717+
#[inline(always)]
718+
pub fn into_edits(self) -> impl Iterator<Item = (ProgPoint, Edit)> {
719+
self.edits.into_iter().map(|(pos, edit)| (pos.pos, edit))
720+
}
721+
722+
/// Sort edits by the combination of their program position and priority. This is a stable sort
723+
/// to preserve the order of the moves the parallel move resolver inserts.
724+
#[inline(always)]
725+
pub fn sort(&mut self) {
726+
self.edits.sort_by_key(|&(pos_prio, _)| pos_prio.key());
727+
}
728+
729+
pub fn add(&mut self, pos_prio: PosWithPrio, from: Allocation, to: Allocation) {
730+
if from != to {
731+
if from.is_reg() && to.is_reg() {
732+
debug_assert_eq!(from.as_reg().unwrap().class(), to.as_reg().unwrap().class());
733+
}
734+
self.edits.push((pos_prio, Edit::Move { from, to }));
735+
}
736+
}
737+
}
738+
695739
/// The fields in this struct are reversed in sort order so that the entire
696740
/// struct can be treated as a u64 for sorting purposes.
697741
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

src/ion/mod.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ impl<'a, F: Function> Env<'a, F> {
7474
preferred_victim_by_class: [PReg::invalid(), PReg::invalid(), PReg::invalid()],
7575

7676
multi_fixed_reg_fixups: vec![],
77-
edits: Vec::with_capacity(n),
7877
allocs: Vec::with_capacity(4 * n),
7978
inst_alloc_offsets: vec![],
8079
num_spillslots: 0,
@@ -103,14 +102,14 @@ impl<'a, F: Function> Env<'a, F> {
103102
Ok(())
104103
}
105104

106-
pub(crate) fn run(&mut self) -> Result<(), RegAllocError> {
105+
pub(crate) fn run(&mut self) -> Result<Edits, RegAllocError> {
107106
self.process_bundles()?;
108107
self.try_allocating_regs_for_spilled_bundles();
109108
self.allocate_spillslots();
110109
let moves = self.apply_allocations_and_insert_moves();
111-
self.resolve_inserted_moves(moves);
110+
let edits = self.resolve_inserted_moves(moves);
112111
self.compute_stackmaps();
113-
Ok(())
112+
Ok(edits)
114113
}
115114
}
116115

@@ -129,18 +128,14 @@ pub fn run<F: Function>(
129128
let mut env = Env::new(func, mach_env, cfginfo, enable_annotations);
130129
env.init()?;
131130

132-
env.run()?;
131+
let edits = env.run()?;
133132

134133
if enable_annotations {
135134
env.dump_results();
136135
}
137136

138137
Ok(Output {
139-
edits: env
140-
.edits
141-
.into_iter()
142-
.map(|(pos_prio, edit)| (pos_prio.pos, edit))
143-
.collect(),
138+
edits: edits.into_edits().collect(),
144139
allocs: env.allocs,
145140
inst_alloc_offsets: env.inst_alloc_offsets,
146141
num_spillslots: env.num_spillslots as usize,

src/ion/moves.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use super::{
1717
RedundantMoveEliminator, VRegIndex, SLOT_NONE,
1818
};
1919
use crate::ion::data_structures::{
20-
u64_key, BlockparamIn, BlockparamOut, CodeRange, FixedRegFixupLevel, LiveRangeKey,
21-
LiveRangeListEntry, PosWithPrio,
20+
u64_key, BlockparamIn, BlockparamOut, CodeRange, Edits, FixedRegFixupLevel, LiveRangeKey,
21+
LiveRangeListEntry,
2222
};
2323
use crate::ion::reg_traversal::RegTraversalIter;
2424
use crate::moves::{MoveAndScratchResolver, ParallelMoves};
@@ -772,7 +772,7 @@ impl<'a, F: Function> Env<'a, F> {
772772
inserted_moves
773773
}
774774

775-
pub fn resolve_inserted_moves(&mut self, mut inserted_moves: InsertedMoves) {
775+
pub fn resolve_inserted_moves(&mut self, mut inserted_moves: InsertedMoves) -> Edits {
776776
// For each program point, gather all moves together. Then
777777
// resolve (see cases below).
778778
let mut i = 0;
@@ -839,6 +839,7 @@ impl<'a, F: Function> Env<'a, F> {
839839
}
840840

841841
let mut last_pos = ProgPoint::before(Inst::new(0));
842+
let mut edits = Edits::with_capacity(self.func.num_insts());
842843

843844
while i < inserted_moves.moves.len() {
844845
let start = i;
@@ -982,7 +983,7 @@ impl<'a, F: Function> Env<'a, F> {
982983
trace!(" resolved: {} -> {} ({:?})", src, dst, to_vreg);
983984
let action = redundant_moves.process_move(src, dst, to_vreg);
984985
if !action.elide {
985-
self.add_move_edit(pos_prio, src, dst);
986+
edits.add(pos_prio, src, dst);
986987
} else {
987988
trace!(" -> redundant move elided");
988989
}
@@ -994,28 +995,20 @@ impl<'a, F: Function> Env<'a, F> {
994995
// be a stable sort! We have to keep the order produced by the
995996
// parallel-move resolver for all moves within a single sort
996997
// key.
997-
self.edits.sort_by_key(|&(pos_prio, _)| pos_prio.key());
998-
self.stats.edits_count = self.edits.len();
998+
edits.sort();
999+
self.stats.edits_count = edits.len();
9991000

10001001
// Add debug annotations.
10011002
if self.annotations_enabled {
1002-
for i in 0..self.edits.len() {
1003-
let &(pos_prio, ref edit) = &self.edits[i];
1003+
for &(pos_prio, ref edit) in edits.iter() {
10041004
match edit {
10051005
&Edit::Move { from, to } => {
10061006
self.annotate(pos_prio.pos, format!("move {} -> {}", from, to));
10071007
}
10081008
}
10091009
}
10101010
}
1011-
}
10121011

1013-
pub fn add_move_edit(&mut self, pos_prio: PosWithPrio, from: Allocation, to: Allocation) {
1014-
if from != to {
1015-
if from.is_reg() && to.is_reg() {
1016-
debug_assert_eq!(from.as_reg().unwrap().class(), to.as_reg().unwrap().class());
1017-
}
1018-
self.edits.push((pos_prio, Edit::Move { from, to }));
1019-
}
1012+
edits
10201013
}
10211014
}

0 commit comments

Comments
 (0)