(&mut self, block: usize, from_block: Option<usize>)
| 476 | } |
| 477 | |
| 478 | fn rename(&mut self, block: usize, from_block: Option<usize>) { |
| 479 | let original_stack = self.stack.len(); |
| 480 | |
| 481 | if let Some(from_block) = from_block { |
| 482 | if self.blocks_with_phi.contains(&block) { |
| 483 | let new_top = self.insert_phi_value(block, from_block); |
| 484 | self.stack.push(new_top); |
| 485 | } |
| 486 | } |
| 487 | |
| 488 | if !self.visited.insert(block) { |
| 489 | while self.stack.len() > original_stack { |
| 490 | self.stack.pop(); |
| 491 | } |
| 492 | return; |
| 493 | } |
| 494 | |
| 495 | for inst in &mut self.blocks[block].instructions { |
| 496 | if inst.class.opcode == Op::Variable && inst.operands.len() > 1 { |
| 497 | let ptr = inst.result_id.unwrap(); |
| 498 | let val = inst.operands[1].id_ref_any().unwrap(); |
| 499 | if let Some(var_info) = self.var_map.get(&ptr) { |
| 500 | assert_eq!(var_info.indices, Vec::<u32>::new()); |
| 501 | self.stack.push(val); |
| 502 | } |
| 503 | } else if inst.class.opcode == Op::Store { |
| 504 | let ptr = inst.operands[0].id_ref_any().unwrap(); |
| 505 | let val = inst.operands[1].id_ref_any().unwrap(); |
| 506 | if let Some(var_info) = self.var_map.get(&ptr) { |
| 507 | if var_info.indices.is_empty() { |
| 508 | *inst = Instruction::new(Op::Nop, None, None, vec![]); |
| 509 | self.stack.push(val); |
| 510 | } else { |
| 511 | let new_id = id(self.header); |
| 512 | let prev_comp = top_stack_or_undef( |
| 513 | self.header, |
| 514 | self.types_global_values, |
| 515 | &self.stack, |
| 516 | self.base_var_type, |
| 517 | ); |
| 518 | let mut operands = vec![Operand::IdRef(val), Operand::IdRef(prev_comp)]; |
| 519 | operands |
| 520 | .extend(var_info.indices.iter().copied().map(Operand::LiteralInt32)); |
| 521 | *inst = Instruction::new( |
| 522 | Op::CompositeInsert, |
| 523 | Some(self.base_var_type), |
| 524 | Some(new_id), |
| 525 | operands, |
| 526 | ); |
| 527 | self.stack.push(new_id); |
| 528 | } |
| 529 | } |
| 530 | } else if inst.class.opcode == Op::Load { |
| 531 | let ptr = inst.operands[0].id_ref_any().unwrap(); |
| 532 | if let Some(var_info) = self.var_map.get(&ptr) { |
| 533 | let loaded_val = inst.result_id.unwrap(); |
| 534 | // TODO: Should this do something more sane if it's undef? |
| 535 | let current_obj = top_stack_or_undef( |
no test coverage detected