Skip to content

Commit 7662cd0

Browse files
authored
Refactor inserted move handling (#135)
* Return inserted moves from move insertion * Avoid adding moves to the queue with the same source and dest
1 parent a655d4f commit 7662cd0

File tree

3 files changed

+72
-56
lines changed

3 files changed

+72
-56
lines changed

src/ion/data_structures.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ pub struct Env<'a, F: Function> {
434434
// was to the approprate PReg.
435435
pub multi_fixed_reg_fixups: Vec<MultiFixedRegFixup>,
436436

437-
pub inserted_moves: Vec<InsertedMove>,
438-
439437
// Output:
440438
pub edits: Vec<(PosWithPrio, Edit)>,
441439
pub allocs: Vec<Allocation>,
@@ -652,6 +650,50 @@ pub enum InsertMovePrio {
652650
OutEdgeMoves,
653651
}
654652

653+
#[derive(Debug, Default)]
654+
pub struct InsertedMoves {
655+
pub moves: Vec<InsertedMove>,
656+
}
657+
658+
impl InsertedMoves {
659+
pub fn push(
660+
&mut self,
661+
pos: ProgPoint,
662+
prio: InsertMovePrio,
663+
from_alloc: Allocation,
664+
to_alloc: Allocation,
665+
to_vreg: VReg,
666+
) {
667+
trace!(
668+
"insert_move: pos {:?} prio {:?} from_alloc {:?} to_alloc {:?} to_vreg {:?}",
669+
pos,
670+
prio,
671+
from_alloc,
672+
to_alloc,
673+
to_vreg
674+
);
675+
if from_alloc == to_alloc {
676+
trace!(" -> skipping move with same source and dest");
677+
return;
678+
}
679+
if let Some(from) = from_alloc.as_reg() {
680+
debug_assert_eq!(from.class(), to_vreg.class());
681+
}
682+
if let Some(to) = to_alloc.as_reg() {
683+
debug_assert_eq!(to.class(), to_vreg.class());
684+
}
685+
self.moves.push(InsertedMove {
686+
pos_prio: PosWithPrio {
687+
pos,
688+
prio: prio as u32,
689+
},
690+
from_alloc,
691+
to_alloc,
692+
to_vreg,
693+
});
694+
}
695+
}
696+
655697
/// The fields in this struct are reversed in sort order so that the entire
656698
/// struct can be treated as a u64 for sorting purposes.
657699
#[derive(Clone, Copy, Debug, PartialEq, Eq)]

src/ion/mod.rs

Lines changed: 2 additions & 3 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-
inserted_moves: vec![],
7877
edits: Vec::with_capacity(n),
7978
allocs: Vec::with_capacity(4 * n),
8079
inst_alloc_offsets: vec![],
@@ -108,8 +107,8 @@ impl<'a, F: Function> Env<'a, F> {
108107
self.process_bundles()?;
109108
self.try_allocating_regs_for_spilled_bundles();
110109
self.allocate_spillslots();
111-
self.apply_allocations_and_insert_moves();
112-
self.resolve_inserted_moves();
110+
let moves = self.apply_allocations_and_insert_moves();
111+
self.resolve_inserted_moves(moves);
113112
self.compute_stackmaps();
114113
Ok(())
115114
}

src/ion/moves.rs

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
//! Move resolution.
1414
1515
use super::{
16-
Env, InsertMovePrio, InsertedMove, LiveRangeFlag, LiveRangeIndex, RedundantMoveEliminator,
17-
VRegIndex, SLOT_NONE,
16+
Env, InsertMovePrio, InsertedMove, InsertedMoves, LiveRangeFlag, LiveRangeIndex,
17+
RedundantMoveEliminator, VRegIndex, SLOT_NONE,
1818
};
1919
use crate::ion::data_structures::{
2020
u128_key, u64_key, BlockparamIn, BlockparamOut, CodeRange, FixedRegFixupLevel, LiveRangeKey,
@@ -24,7 +24,7 @@ use crate::ion::reg_traversal::RegTraversalIter;
2424
use crate::moves::{MoveAndScratchResolver, ParallelMoves};
2525
use crate::{
2626
Allocation, Block, Edit, Function, FxHashMap, Inst, InstPosition, OperandConstraint,
27-
OperandKind, OperandPos, PReg, ProgPoint, RegClass, SpillSlot, VReg,
27+
OperandKind, OperandPos, PReg, ProgPoint, RegClass, SpillSlot,
2828
};
2929
use alloc::vec::Vec;
3030
use alloc::{format, vec};
@@ -41,39 +41,6 @@ impl<'a, F: Function> Env<'a, F> {
4141
pos == self.cfginfo.block_exit[block.index()]
4242
}
4343

44-
pub fn insert_move(
45-
&mut self,
46-
pos: ProgPoint,
47-
prio: InsertMovePrio,
48-
from_alloc: Allocation,
49-
to_alloc: Allocation,
50-
to_vreg: VReg,
51-
) {
52-
trace!(
53-
"insert_move: pos {:?} prio {:?} from_alloc {:?} to_alloc {:?} to_vreg {:?}",
54-
pos,
55-
prio,
56-
from_alloc,
57-
to_alloc,
58-
to_vreg
59-
);
60-
if let Some(from) = from_alloc.as_reg() {
61-
debug_assert_eq!(from.class(), to_vreg.class());
62-
}
63-
if let Some(to) = to_alloc.as_reg() {
64-
debug_assert_eq!(to.class(), to_vreg.class());
65-
}
66-
self.inserted_moves.push(InsertedMove {
67-
pos_prio: PosWithPrio {
68-
pos,
69-
prio: prio as u32,
70-
},
71-
from_alloc,
72-
to_alloc,
73-
to_vreg,
74-
});
75-
}
76-
7744
pub fn get_alloc(&self, inst: Inst, slot: usize) -> Allocation {
7845
let inst_allocs = &self.allocs[self.inst_alloc_offsets[inst.index()] as usize..];
7946
inst_allocs[slot]
@@ -102,11 +69,13 @@ impl<'a, F: Function> Env<'a, F> {
10269
}
10370
}
10471

105-
pub fn apply_allocations_and_insert_moves(&mut self) {
72+
pub fn apply_allocations_and_insert_moves(&mut self) -> InsertedMoves {
10673
trace!("apply_allocations_and_insert_moves");
10774
trace!("blockparam_ins: {:?}", self.blockparam_ins);
10875
trace!("blockparam_outs: {:?}", self.blockparam_outs);
10976

77+
let mut inserted_moves = InsertedMoves::default();
78+
11079
// Now that all splits are done, we can pay the cost once to
11180
// sort VReg range lists and update with the final ranges.
11281
for vreg in &mut self.vregs {
@@ -394,7 +363,7 @@ impl<'a, F: Function> Env<'a, F> {
394363
vreg.index()
395364
);
396365
debug_assert_eq!(range.from.pos(), InstPosition::Before);
397-
self.insert_move(
366+
inserted_moves.push(
398367
range.from,
399368
InsertMovePrio::Regular,
400369
prev_alloc,
@@ -670,7 +639,7 @@ impl<'a, F: Function> Env<'a, F> {
670639
);
671640

672641
let (pos, prio) = choose_move_location(self, dest.from, dest.to);
673-
self.insert_move(pos, prio, src, dest.alloc, vreg);
642+
inserted_moves.push(pos, prio, src, dest.alloc, vreg);
674643
}
675644
}
676645

@@ -710,7 +679,13 @@ impl<'a, F: Function> Env<'a, F> {
710679

711680
let (pos, prio) =
712681
choose_move_location(self, dest.from_block, dest.to_block);
713-
self.insert_move(pos, prio, src.alloc, dest.alloc, self.vreg(dest.to_vreg));
682+
inserted_moves.push(
683+
pos,
684+
prio,
685+
src.alloc,
686+
dest.alloc,
687+
self.vreg(dest.to_vreg),
688+
);
714689

715690
// We don't advance the block_param_sources iterator here because there
716691
// could be additional destinations that would take from that source. Thus,
@@ -740,7 +715,7 @@ impl<'a, F: Function> Env<'a, F> {
740715
FixedRegFixupLevel::Initial => InsertMovePrio::MultiFixedRegInitial,
741716
FixedRegFixupLevel::Secondary => InsertMovePrio::MultiFixedRegSecondary,
742717
};
743-
self.insert_move(fixup.pos, prio, from_alloc, to_alloc, self.vreg(fixup.vreg));
718+
inserted_moves.push(fixup.pos, prio, from_alloc, to_alloc, self.vreg(fixup.vreg));
744719
self.set_alloc(
745720
fixup.pos.inst(),
746721
fixup.to_slot as usize,
@@ -819,7 +794,7 @@ impl<'a, F: Function> Env<'a, F> {
819794
);
820795
}
821796
let input_operand = self.func.inst_operands(inst)[input_idx];
822-
self.insert_move(
797+
inserted_moves.push(
823798
ProgPoint::before(inst),
824799
InsertMovePrio::ReusedInput,
825800
input_alloc,
@@ -835,13 +810,16 @@ impl<'a, F: Function> Env<'a, F> {
835810
// Sort the debug-locations vector; we provide this
836811
// invariant to the client.
837812
self.debug_locations.sort_unstable();
813+
814+
inserted_moves
838815
}
839816

840-
pub fn resolve_inserted_moves(&mut self) {
817+
pub fn resolve_inserted_moves(&mut self, mut inserted_moves: InsertedMoves) {
841818
// For each program point, gather all moves together. Then
842819
// resolve (see cases below).
843820
let mut i = 0;
844-
self.inserted_moves
821+
inserted_moves
822+
.moves
845823
.sort_unstable_by_key(|m| m.pos_prio.key());
846824

847825
// Redundant-move elimination state tracker.
@@ -897,13 +875,13 @@ impl<'a, F: Function> Env<'a, F> {
897875

898876
let mut last_pos = ProgPoint::before(Inst::new(0));
899877

900-
while i < self.inserted_moves.len() {
878+
while i < inserted_moves.moves.len() {
901879
let start = i;
902-
let pos_prio = self.inserted_moves[i].pos_prio;
903-
while i < self.inserted_moves.len() && self.inserted_moves[i].pos_prio == pos_prio {
880+
let pos_prio = inserted_moves.moves[i].pos_prio;
881+
while i < inserted_moves.moves.len() && inserted_moves.moves[i].pos_prio == pos_prio {
904882
i += 1;
905883
}
906-
let moves = &self.inserted_moves[start..i];
884+
let moves = &inserted_moves.moves[start..i];
907885

908886
redundant_move_process_side_effects(self, &mut redundant_moves, last_pos, pos_prio.pos);
909887
last_pos = pos_prio.pos;
@@ -919,9 +897,6 @@ impl<'a, F: Function> Env<'a, F> {
919897
let mut vec_moves: SmallVec<[InsertedMove; 8]> = smallvec![];
920898

921899
for m in moves {
922-
if m.from_alloc == m.to_alloc {
923-
continue;
924-
}
925900
match m.to_vreg.class() {
926901
RegClass::Int => {
927902
int_moves.push(m.clone());

0 commit comments

Comments
 (0)