luaur_code_gen/functions/
get_next_inst_use.rs1use crate::enums::ir_block_kind::IrBlockKind;
2use crate::enums::ir_op_kind::IrOpKind;
3use crate::functions::is_pseudo::is_pseudo;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::ir_function::IrFunction;
6use crate::records::ir_op::IrOp;
7use luaur_common::FFlag;
8
9pub fn get_next_inst_use(
10 function: &mut IrFunction,
11 target_inst_idx: u32,
12 start_inst_idx: u32,
13 in_vm_exit_sync: &mut bool,
14) -> u32 {
15 CODEGEN_ASSERT!((start_inst_idx as usize) < function.instructions.len());
16
17 let target_last_use = function.instructions[target_inst_idx as usize].last_use;
18
19 for inst_idx in start_inst_idx..=target_last_use {
20 let inst = function.instructions[inst_idx as usize].clone();
21
22 if is_pseudo(inst.cmd) {
23 continue;
24 }
25
26 if FFlag::LuauCodegenVmExitSync.get() {
27 for op in inst.ops.as_slice() {
28 if is_inst_use_for_op(function, inst_idx, target_inst_idx, *op, in_vm_exit_sync) {
29 return inst_idx;
30 }
31 }
32 } else {
33 for op in inst.ops.as_slice() {
34 if op.kind() == IrOpKind::Inst && op.index() == target_inst_idx {
35 return inst_idx;
36 }
37 }
38 }
39 }
40
41 CODEGEN_ASSERT!(false);
42 target_last_use
43}
44
45fn is_inst_use_for_op(
46 function: &mut IrFunction,
47 inst_idx: u32,
48 target_inst_idx: u32,
49 op: IrOp,
50 in_vm_exit_sync: &mut bool,
51) -> bool {
52 if op.kind() == IrOpKind::Inst {
53 return op.index() == target_inst_idx;
54 }
55
56 if op.kind() == IrOpKind::Block
57 && function.blocks[op.index() as usize].kind == IrBlockKind::ExitSync
58 {
59 if let Some(sync_info) = function.vm_exit_info.find(&inst_idx) {
60 for arg_op in sync_info.arg_ops.as_slice() {
61 CODEGEN_ASSERT!(arg_op.kind() == IrOpKind::Inst);
62
63 if arg_op.index() == target_inst_idx {
64 *in_vm_exit_sync = true;
65 return true;
66 }
67 }
68 }
69 }
70
71 false
72}