Convert LOAD_CONST for small integers to LOAD_SMALL_INT maybe_instr_make_load_smallint
(&mut self)
| 1454 | /// Convert LOAD_CONST for small integers to LOAD_SMALL_INT |
| 1455 | /// maybe_instr_make_load_smallint |
| 1456 | fn convert_to_load_small_int(&mut self) { |
| 1457 | for block in &mut self.blocks { |
| 1458 | for instr in &mut block.instructions { |
| 1459 | // Check if it's a LOAD_CONST instruction |
| 1460 | let Some(Instruction::LoadConst { .. }) = instr.instr.real() else { |
| 1461 | continue; |
| 1462 | }; |
| 1463 | |
| 1464 | // Get the constant value |
| 1465 | let const_idx = u32::from(instr.arg) as usize; |
| 1466 | let Some(constant) = self.metadata.consts.get_index(const_idx) else { |
| 1467 | continue; |
| 1468 | }; |
| 1469 | |
| 1470 | // Check if it's a small integer |
| 1471 | let ConstantData::Integer { value } = constant else { |
| 1472 | continue; |
| 1473 | }; |
| 1474 | |
| 1475 | // LOAD_SMALL_INT oparg is unsigned, so only 0..=255 can be encoded |
| 1476 | if let Some(small) = value.to_i32().filter(|v| (0..=255).contains(v)) { |
| 1477 | // Convert LOAD_CONST to LOAD_SMALL_INT |
| 1478 | instr.instr = Instruction::LoadSmallInt { i: Arg::marker() }.into(); |
| 1479 | // The arg is the i32 value stored as u32 (two's complement) |
| 1480 | instr.arg = OpArg::new(small as u32); |
| 1481 | } |
| 1482 | } |
| 1483 | } |
| 1484 | } |
| 1485 | |
| 1486 | /// Remove constants that are no longer referenced by LOAD_CONST instructions. |
| 1487 | /// remove_unused_consts |