mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
YJIT: Visualize live ranges on register spill (#6651)
This commit is contained in:
parent
cbf15e5cbe
commit
0d1e1987d1
Notes:
git
2022-11-01 19:06:01 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
1 changed files with 37 additions and 6 deletions
|
@ -932,15 +932,14 @@ impl Assembler
|
|||
|
||||
// Mutate the pool bitmap to indicate that the register at that index
|
||||
// has been allocated and is live.
|
||||
fn alloc_reg(pool: &mut u32, regs: &Vec<Reg>) -> Reg {
|
||||
fn alloc_reg(pool: &mut u32, regs: &Vec<Reg>) -> Option<Reg> {
|
||||
for (index, reg) in regs.iter().enumerate() {
|
||||
if (*pool & (1 << index)) == 0 {
|
||||
*pool |= 1 << index;
|
||||
return *reg;
|
||||
return Some(*reg);
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!("Register spill not supported");
|
||||
None
|
||||
}
|
||||
|
||||
// Allocate a specific register
|
||||
|
@ -966,6 +965,29 @@ impl Assembler
|
|||
}
|
||||
}
|
||||
|
||||
// Dump live registers for register spill debugging.
|
||||
fn dump_live_regs(insns: Vec<Insn>, live_ranges: Vec<usize>, num_regs: usize, spill_index: usize) {
|
||||
// Convert live_ranges to live_regs: the number of live registers at each index
|
||||
let mut live_regs: Vec<usize> = vec![];
|
||||
let mut end_idxs: Vec<usize> = vec![];
|
||||
for (cur_idx, &end_idx) in live_ranges.iter().enumerate() {
|
||||
end_idxs.push(end_idx);
|
||||
while let Some(end_idx) = end_idxs.iter().position(|&end_idx| cur_idx == end_idx) {
|
||||
end_idxs.remove(end_idx);
|
||||
}
|
||||
live_regs.push(end_idxs.len());
|
||||
}
|
||||
|
||||
// Dump insns along with live registers
|
||||
for (insn_idx, insn) in insns.iter().enumerate() {
|
||||
print!("{:3} ", if spill_index == insn_idx { "==>" } else { "" });
|
||||
for reg in 0..=num_regs {
|
||||
print!("{:1}", if reg < live_regs[insn_idx] { "|" } else { "" });
|
||||
}
|
||||
println!(" [{:3}] {:?}", insn_idx, insn);
|
||||
}
|
||||
}
|
||||
|
||||
let live_ranges: Vec<usize> = take(&mut self.live_ranges);
|
||||
let mut asm = Assembler::new_with_label_names(take(&mut self.label_names));
|
||||
let mut iterator = self.into_draining_iter();
|
||||
|
@ -1050,8 +1072,17 @@ impl Assembler
|
|||
let reg = opnd.unwrap_reg();
|
||||
Some(take_reg(&mut pool, ®s, ®))
|
||||
},
|
||||
_ => {
|
||||
Some(alloc_reg(&mut pool, ®s))
|
||||
_ => match alloc_reg(&mut pool, ®s) {
|
||||
Some(reg) => Some(reg),
|
||||
None => {
|
||||
let mut insns = asm.insns;
|
||||
insns.push(insn);
|
||||
for insn in iterator.insns {
|
||||
insns.push(insn);
|
||||
}
|
||||
dump_live_regs(insns, live_ranges, regs.len(), index);
|
||||
unreachable!("Register spill not supported");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue