Skip to content

Commit c53face

Browse files
committed
cleanup
1 parent 2e89c14 commit c53face

File tree

1 file changed

+53
-116
lines changed

1 file changed

+53
-116
lines changed

src/fastalloc/mod.rs

Lines changed: 53 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ use crate::{
55
AllocationKind, Block, FxHashMap, Inst, InstPosition, Operand, OperandConstraint, OperandKind,
66
OperandPos, PReg, PRegSet, RegClass, SpillSlot, VReg,
77
};
8-
use alloc::vec::Vec;
8+
use alloc::format;
9+
use alloc::{vec, vec::Vec};
910
use core::convert::TryInto;
11+
use core::fmt;
1012
use core::iter::FromIterator;
1113
use core::ops::{Index, IndexMut};
1214

@@ -194,8 +196,6 @@ impl<T> IndexMut<OperandPos> for PartedByOperandPos<T> {
194196
}
195197
}
196198

197-
use core::fmt;
198-
199199
impl<T: fmt::Display> fmt::Display for PartedByOperandPos<T> {
200200
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201201
write!(f, "{{ early: {}, late: {} }}", self.items[0], self.items[1])
@@ -243,7 +243,6 @@ pub struct Env<'a, F: Function> {
243243

244244
impl<'a, F: Function> Env<'a, F> {
245245
fn new(func: &'a F, env: &'a MachineEnv) -> Self {
246-
use alloc::vec;
247246
let mut regs = [
248247
env.preferred_regs_by_class[RegClass::Int as usize].clone(),
249248
env.preferred_regs_by_class[RegClass::Float as usize].clone(),
@@ -333,33 +332,37 @@ impl<'a, F: Function> Env<'a, F> {
333332
class: RegClass,
334333
pos: InstPosition,
335334
) -> Result<(), RegAllocError> {
336-
use OperandPos::{Early, Late};
337-
let reg = self.get_scratch_reg(
338-
inst,
339-
class,
340-
self.available_pregs[Late] & self.available_pregs[Early],
341-
pos,
342-
)?;
343-
self.edits.scratch_regs[class] = Some(reg);
344-
self.available_pregs[OperandPos::Early].remove(reg);
345-
self.available_pregs[OperandPos::Late].remove(reg);
346-
Ok(())
335+
let avail_regs =
336+
self.available_pregs[OperandPos::Late] & self.available_pregs[OperandPos::Early];
337+
if let Some(preg) = self.lrus[class].last(avail_regs) {
338+
if self.vreg_in_preg[preg.index()] != VReg::invalid() {
339+
self.evict_vreg_in_preg(inst, preg, pos)?;
340+
}
341+
self.edits.scratch_regs[class] = Some(preg);
342+
self.available_pregs[OperandPos::Early].remove(preg);
343+
self.available_pregs[OperandPos::Late].remove(preg);
344+
Ok(())
345+
} else {
346+
Err(RegAllocError::TooManyLiveRegs)
347+
}
347348
}
348349

349-
fn get_scratch_reg(
350+
fn add_move(
350351
&mut self,
351352
inst: Inst,
353+
from: Allocation,
354+
to: Allocation,
352355
class: RegClass,
353-
avail_regs: PRegSet,
354356
pos: InstPosition,
355-
) -> Result<PReg, RegAllocError> {
356-
let Some(preg) = self.lrus[class].last(avail_regs) else {
357-
return Err(RegAllocError::TooManyLiveRegs);
358-
};
359-
if self.vreg_in_preg[preg.index()] != VReg::invalid() {
360-
self.evict_vreg_in_preg(inst, preg, pos);
357+
) -> Result<(), RegAllocError> {
358+
if self.edits.is_stack(from)
359+
&& self.edits.is_stack(to)
360+
&& self.edits.scratch_regs[class].is_none()
361+
{
362+
self.alloc_scratch_reg(inst, class, pos)?;
361363
}
362-
Ok(preg)
364+
self.edits.add_move(inst, from, to, class, pos);
365+
Ok(())
363366
}
364367

365368
fn reserve_reg_for_fixed_operand(
@@ -453,7 +456,12 @@ impl<'a, F: Function> Env<'a, F> {
453456
}
454457
}
455458

456-
fn evict_vreg_in_preg(&mut self, inst: Inst, preg: PReg, pos: InstPosition) {
459+
fn evict_vreg_in_preg(
460+
&mut self,
461+
inst: Inst,
462+
preg: PReg,
463+
pos: InstPosition,
464+
) -> Result<(), RegAllocError> {
457465
trace!("Removing the vreg in preg {} for eviction", preg);
458466
let evicted_vreg = self.vreg_in_preg[preg.index()];
459467
trace!("The removed vreg: {}", evicted_vreg);
@@ -464,13 +472,13 @@ impl<'a, F: Function> Env<'a, F> {
464472
let slot = self.vreg_spillslots[evicted_vreg.vreg()];
465473
self.vreg_allocs[evicted_vreg.vreg()] = Allocation::stack(slot);
466474
trace!("Move reason: eviction");
467-
self.edits.add_move(
475+
self.add_move(
468476
inst,
469477
self.vreg_allocs[evicted_vreg.vreg()],
470478
Allocation::reg(preg),
471479
evicted_vreg.class(),
472480
pos,
473-
);
481+
)
474482
}
475483

476484
fn freealloc(&mut self, vreg: VReg) {
@@ -526,7 +534,7 @@ impl<'a, F: Function> Env<'a, F> {
526534
return Err(RegAllocError::TooManyLiveRegs);
527535
};
528536
if self.vreg_in_preg[preg.index()] != VReg::invalid() {
529-
self.evict_vreg_in_preg(inst, preg, InstPosition::After);
537+
self.evict_vreg_in_preg(inst, preg, InstPosition::After)?;
530538
}
531539
trace!("The allocated register for vreg {}: {}", op.vreg(), preg);
532540
self.lrus[op.class()].poke(preg);
@@ -623,23 +631,9 @@ impl<'a, F: Function> Env<'a, F> {
623631
// used (in `prev_alloc`, that is).
624632
else {
625633
trace!("Move reason: Prev allocation doesn't meet constraints");
626-
if self.edits.is_stack(new_alloc)
627-
&& self.edits.is_stack(curr_alloc)
628-
&& self.edits.scratch_regs[op.class()].is_none()
629-
{
630-
self.alloc_scratch_reg(inst, op.class(), InstPosition::After)?;
631-
}
632634
if op.kind() == OperandKind::Def {
633635
trace!("Adding edit from {new_alloc:?} to {curr_alloc:?} after inst {inst:?} for {op}");
634-
self.edits.add_move(
635-
inst,
636-
new_alloc,
637-
curr_alloc,
638-
op.class(),
639-
InstPosition::After,
640-
);
641-
// No need to set vreg_in_preg because it will be set during
642-
// `freealloc` if needed.
636+
self.add_move(inst, new_alloc, curr_alloc, op.class(), InstPosition::After)?;
643637
}
644638
// Edits for use operands are added later to avoid inserting
645639
// edits out of order.
@@ -713,7 +707,6 @@ impl<'a, F: Function> Env<'a, F> {
713707
/// this function places branch arguments in the spillslots
714708
/// expected by the destination blocks.
715709
fn process_branch(&mut self, block: Block, inst: Inst) -> Result<(), RegAllocError> {
716-
use OperandPos::*;
717710
trace!("Processing branch instruction {inst:?} in block {block:?}");
718711

719712
let mut int_parallel_moves = ParallelMoves::new();
@@ -742,26 +735,13 @@ impl<'a, F: Function> Env<'a, F> {
742735
self.live_vregs.insert(*vreg);
743736
self.vreg_to_live_inst_range[vreg.vreg()].1 = ProgPoint::before(inst);
744737
} else if curr_alloc != vreg_spill {
745-
if self.edits.is_stack(curr_alloc)
746-
&& self.edits.scratch_regs[vreg.class()].is_none()
747-
{
748-
let reg = self.get_scratch_reg(
749-
inst,
750-
vreg.class(),
751-
self.available_pregs[Early] & self.available_pregs[Late],
752-
InstPosition::Before,
753-
)?;
754-
self.edits.scratch_regs[vreg.class()] = Some(reg);
755-
self.available_pregs[OperandPos::Early].remove(reg);
756-
self.available_pregs[OperandPos::Late].remove(reg);
757-
}
758-
self.edits.add_move(
738+
self.add_move(
759739
inst,
760740
vreg_spill,
761741
curr_alloc,
762742
vreg.class(),
763743
InstPosition::Before,
764-
);
744+
)?;
765745
}
766746
self.vreg_allocs[vreg.vreg()] = vreg_spill;
767747
let parallel_moves = match vreg.class() {
@@ -781,7 +761,8 @@ impl<'a, F: Function> Env<'a, F> {
781761
let resolved_vec = vec_parallel_moves.resolve();
782762
let mut scratch_regs = self.edits.scratch_regs.clone();
783763
let mut num_spillslots = self.stack.num_spillslots;
784-
let mut avail_regs = self.available_pregs[Early] & self.available_pregs[Late];
764+
let mut avail_regs =
765+
self.available_pregs[OperandPos::Early] & self.available_pregs[OperandPos::Late];
785766

786767
trace!("Resolving parallel moves");
787768
for (resolved, class) in [
@@ -871,12 +852,7 @@ impl<'a, F: Function> Env<'a, F> {
871852
"Evicting {} from fixed register {preg}",
872853
self.vreg_in_preg[preg.index()]
873854
);
874-
if self.fixed_stack_slots.contains(preg)
875-
&& self.edits.scratch_regs[preg.class()].is_none()
876-
{
877-
self.alloc_scratch_reg(inst, preg.class(), InstPosition::After)?;
878-
}
879-
self.evict_vreg_in_preg(inst, preg, InstPosition::After);
855+
self.evict_vreg_in_preg(inst, preg, InstPosition::After)?;
880856
self.vreg_in_preg[preg.index()] = VReg::invalid();
881857
}
882858
}
@@ -887,12 +863,7 @@ impl<'a, F: Function> Env<'a, F> {
887863
"Evicting {} from clobber {preg}",
888864
self.vreg_in_preg[preg.index()]
889865
);
890-
if self.fixed_stack_slots.contains(preg)
891-
&& self.edits.scratch_regs[preg.class()].is_none()
892-
{
893-
self.alloc_scratch_reg(inst, preg.class(), InstPosition::After)?;
894-
}
895-
self.evict_vreg_in_preg(inst, preg, InstPosition::After);
866+
self.evict_vreg_in_preg(inst, preg, InstPosition::After)?;
896867
self.vreg_in_preg[preg.index()] = VReg::invalid();
897868
}
898869
}
@@ -911,24 +882,9 @@ impl<'a, F: Function> Env<'a, F> {
911882
if slot.is_valid() {
912883
self.vreg_to_live_inst_range[op.vreg().vreg()].2 = Allocation::stack(slot);
913884
let curr_alloc = self.vreg_allocs[op.vreg().vreg()];
914-
let vreg_slot = self.vreg_spillslots[op.vreg().vreg()];
915-
let (is_stack_to_stack, src_and_dest_are_same) =
916-
if let Some(curr_alloc) = curr_alloc.as_stack() {
917-
(true, curr_alloc == vreg_slot)
918-
} else {
919-
(self.edits.is_stack(curr_alloc), false)
920-
};
921-
if !src_and_dest_are_same {
922-
if is_stack_to_stack && self.edits.scratch_regs[op.class()].is_none() {
923-
self.alloc_scratch_reg(inst, op.class(), InstPosition::After)?;
924-
};
925-
self.edits.add_move(
926-
inst,
927-
self.vreg_allocs[op.vreg().vreg()],
928-
Allocation::stack(self.vreg_spillslots[op.vreg().vreg()]),
929-
op.class(),
930-
InstPosition::After,
931-
);
885+
let new_alloc = Allocation::stack(self.vreg_spillslots[op.vreg().vreg()]);
886+
if curr_alloc != new_alloc {
887+
self.add_move(inst, curr_alloc, new_alloc, op.class(), InstPosition::After)?;
932888
}
933889
}
934890
self.vreg_to_live_inst_range[op.vreg().vreg()].0 = ProgPoint::after(inst);
@@ -955,24 +911,17 @@ impl<'a, F: Function> Env<'a, F> {
955911
if op.as_fixed_nonallocatable().is_some() {
956912
continue;
957913
}
958-
if self.vreg_allocs[op.vreg().vreg()] != self.allocs[(inst.index(), op_idx)] {
959-
let curr_alloc = self.vreg_allocs[op.vreg().vreg()];
960-
let new_alloc = self.allocs[(inst.index(), op_idx)];
914+
let curr_alloc = self.vreg_allocs[op.vreg().vreg()];
915+
let new_alloc = self.allocs[(inst.index(), op_idx)];
916+
if curr_alloc != new_alloc {
961917
trace!("Adding edit from {curr_alloc:?} to {new_alloc:?} before inst {inst:?} for {op}");
962-
if curr_alloc != new_alloc
963-
&& self.edits.is_stack(curr_alloc)
964-
&& self.edits.is_stack(new_alloc)
965-
&& self.edits.scratch_regs[op.class()].is_none()
966-
{
967-
self.alloc_scratch_reg(inst, op.class(), InstPosition::Before)?;
968-
}
969-
self.edits.add_move(
918+
self.add_move(
970919
inst,
971920
curr_alloc,
972921
new_alloc,
973922
op.class(),
974923
InstPosition::Before,
975-
);
924+
)?;
976925
}
977926
}
978927
if self.func.is_branch(inst) {
@@ -1051,22 +1000,13 @@ impl<'a, F: Function> Env<'a, F> {
10511000
"Move reason: reload {} at begin - move from its spillslot",
10521001
vreg
10531002
);
1054-
if self.edits.is_stack(prev_alloc) && self.edits.scratch_regs[vreg.class()].is_none() {
1055-
let reg = self.get_scratch_reg(
1056-
first_inst,
1057-
vreg.class(),
1058-
avail_regs_for_scratch,
1059-
InstPosition::Before,
1060-
)?;
1061-
self.edits.scratch_regs[vreg.class()] = Some(reg);
1062-
}
1063-
self.edits.add_move(
1003+
self.add_move(
10641004
self.func.block_insns(block).first(),
10651005
slot,
10661006
prev_alloc,
10671007
vreg.class(),
10681008
InstPosition::Before,
1069-
);
1009+
)?;
10701010
}
10711011
for vreg in self.live_vregs.iter() {
10721012
trace!("Processing {}", vreg);
@@ -1142,7 +1082,6 @@ impl<'a, F: Function> Env<'a, F> {
11421082
}
11431083

11441084
fn log_post_reload_at_begin_state(&self, block: Block) {
1145-
use alloc::format;
11461085
trace!("");
11471086
trace!("State after instruction reload_at_begin of {:?}", block);
11481087
let mut map = FxHashMap::default();
@@ -1165,7 +1104,6 @@ impl<'a, F: Function> Env<'a, F> {
11651104
}
11661105

11671106
fn log_post_inst_processing_state(&self, inst: Inst) {
1168-
use alloc::format;
11691107
trace!("");
11701108
trace!("State after instruction {:?}", inst);
11711109
let mut map = FxHashMap::default();
@@ -1259,7 +1197,6 @@ fn log_function<F: Function>(func: &F) {
12591197

12601198
fn log_output<'a, F: Function>(env: &Env<'a, F>) {
12611199
trace!("Done!");
1262-
use alloc::format;
12631200
let mut v = Vec::new();
12641201
for i in 0..env.func.num_vregs() {
12651202
if env.vreg_spillslots[i].is_valid() {

0 commit comments

Comments
 (0)