luaur_code_gen/functions/
setup_block_entry_state_optimize_const_prop.rs1use crate::functions::propagate_tags_from_predecessors::propagate_tags_from_predecessors;
2use crate::functions::try_get_luau_tag_for_bc_type::try_get_luau_tag_for_bc_type;
3use crate::records::bytecode_type_info::BytecodeTypeInfo;
4use crate::records::cfg_info::CfgInfo;
5use crate::records::const_prop_state::ConstPropState;
6use crate::records::ir_block::IrBlock;
7use crate::records::ir_builder::IrBuilder;
8use crate::records::ir_function::IrFunction;
9use luaur_common::enums::luau_bytecode_type::LuauBytecodeType;
10
11fn luau_bytecode_type_optional_bit() -> u8 {
12 LuauBytecodeType::LBC_TYPE_OPTIONAL_BIT.0 as u8
13}
14
15pub fn setup_block_entry_state_ir_builder_ir_function_ir_block_const_prop_state(
16 build: &mut IrBuilder,
17 function: &mut IrFunction,
18 block: &IrBlock,
19 state: &mut ConstPropState,
20) {
21 let block_flags = block.flags;
22 let entry_arg_check_bit = 1u8 << 2;
23 if (block_flags & entry_arg_check_bit) != 0 {
24 return;
25 }
26
27 let type_info: &BytecodeTypeInfo = &function.bc_original_type_info;
28
29 for i in 0..type_info.argument_types.len() {
30 let et = type_info.argument_types[i];
31 let tag = et & !luau_bytecode_type_optional_bit();
32
33 if tag == LuauBytecodeType::LBC_TYPE_ANY.0 as u8
34 || (et & luau_bytecode_type_optional_bit()) != 0
35 {
36 continue;
37 }
38
39 let cfg: &CfgInfo = &function.cfg;
40 if (cfg.written.regs[i / 64] & (1u64 << (i % 64))) != 0 {
41 continue;
42 }
43
44 if cfg.written.vararg_seq && i >= cfg.written.vararg_start as usize {
45 continue;
46 }
47
48 if (cfg.captured.regs[i / 64] & (1u64 << (i % 64))) != 0 {
49 continue;
50 }
51
52 if let Some(vm_tag) =
53 try_get_luau_tag_for_bc_type(tag, true)
54 {
55 let op = build.vm_reg(i as u8);
56 state.update_tag(op, vm_tag);
57 }
58 }
59
60 let state_ptr = state as *mut ConstPropState;
61 let build_ptr = build as *mut IrBuilder;
62 propagate_tags_from_predecessors(
63 function,
64 block,
65 Box::new(move |i: usize| unsafe { (*state_ptr).regs[i].tag }),
66 Box::new(move |i: usize, tag: u8| unsafe {
67 let op = (*build_ptr).vm_reg(i as u8);
68 (*state_ptr).update_tag(op, tag);
69 }),
70 );
71}