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…
	
	Add table
		Add a link
		
	
		Reference in a new issue