Helper for adjusting `OpPhi` source label IDs, when the terminator of the `original_label_id`-labeled block got moved to `blocks[original_block_idx]`.
(original_label_id: Word, blocks: &mut [Block], new_block_idx: usize)
| 1067 | /// Helper for adjusting `OpPhi` source label IDs, when the terminator of the |
| 1068 | /// `original_label_id`-labeled block got moved to `blocks[original_block_idx]`. |
| 1069 | fn rewrite_phi_sources(original_label_id: Word, blocks: &mut [Block], new_block_idx: usize) { |
| 1070 | let new_label_id = blocks[new_block_idx].label_id().unwrap(); |
| 1071 | |
| 1072 | // HACK(eddyb) can't keep `blocks` borrowed, the loop needs mutable access. |
| 1073 | let target_ids: SmallVec<[_; 4]> = outgoing_edges(&blocks[new_block_idx]).collect(); |
| 1074 | |
| 1075 | for target_id in target_ids { |
| 1076 | let target_block = blocks |
| 1077 | .iter_mut() |
| 1078 | .find(|b| b.label_id().unwrap() == target_id) |
| 1079 | .unwrap(); |
| 1080 | let phis = target_block |
| 1081 | .instructions |
| 1082 | .iter_mut() |
| 1083 | .filter(|inst| { |
| 1084 | // These are the only instructions that are allowed before `OpPhi`. |
| 1085 | !matches!(inst.class.opcode, Op::Line | Op::NoLine) |
| 1086 | }) |
| 1087 | .take_while(|inst| inst.class.opcode == Op::Phi); |
| 1088 | for phi in phis { |
| 1089 | for value_and_source_id in phi.operands.chunks_mut(2) { |
| 1090 | let source_id = value_and_source_id[1].id_ref_any_mut().unwrap(); |
| 1091 | if *source_id == original_label_id { |
| 1092 | *source_id = new_label_id; |
| 1093 | break; |
| 1094 | } |
| 1095 | } |
| 1096 | } |
| 1097 | } |
| 1098 | } |
no test coverage detected