/// Prepare a new lowering context for the given IR function.
Prepare a new lowering context for the given IR function.
Prepare a new lowering context for the given IR function .
pub fn new(
        f: &'func Function,
        abi: Box<dyn ABICallee<I = I>>,
        emit_info: I::Info,
        block_order: BlockLoweringOrder,
    ) -> CodegenResult<Lower<'func, I>> {
        let mut vcode = VCodeBuilder::new(abi, emit_info, block_order);
        let mut next_vreg: u32 = 0;
        let mut value_regs = SecondaryMap::with_default(Reg::invalid());
        // Assign a vreg to each block param and each inst result.
        for bb in f.layout.blocks() {
            for &param in f.dfg.block_params(bb) {
                let ty = f.dfg.value_type(param);
                let vreg = alloc_vreg(&mut value_regs, I::rc_for_type(ty)?, param, &mut next_vreg);
                vcode.set_vreg_type(vreg, ty);
                debug!("bb {} param {}: vreg {:?}", bb, param, vreg);
            }
            for inst in f.layout.block_insts(bb) {
                for &result in f.dfg.inst_results(inst) {
                    let ty = f.dfg.value_type(result);
                    let vreg =
                        alloc_vreg(&mut value_regs, I::rc_for_type(ty)?, result, &mut next_vreg);
                    vcode.set_vreg_type(vreg, ty);
                    debug!(
                        "bb {} inst {} ({:?}): result vreg {:?}",
                        bb, inst, f.dfg[inst], vreg
                    );
                }
            }
        }
        let vm_context = f
            .signature
            .special_param_index(ArgumentPurpose::VMContext)
            .map(|vm_context_index| {
                let entry_block = f.layout.entry_block().unwrap();
                let param = f.dfg.block_params(entry_block)[vm_context_index];
                value_regs[param]
            });
        // Assign a vreg to each return value.
        let mut retval_regs = vec![];
        for ret in &f.signature.returns {
            let v = next_vreg;
            next_vreg += 1;
            let regclass = I::rc_for_type(ret.value_type)?;
            let vreg = Reg::new_virtual(regclass, v);
            retval_regs.push(vreg);
            vcode.set_vreg_type(vreg.as_virtual_reg().unwrap(), ret.value_type);
        }
        // Compute instruction colors, find constant instructions, and find instructions with
        // side-effects, in one combined pass.
        let mut cur_color = 0;
        let mut inst_colors = SecondaryMap::with_default(InstColor::new(0));
        let mut inst_constants = FxHashMap::default();
        let mut inst_needed = SecondaryMap::with_default(false);
        for bb in f.layout.blocks() {
            cur_color += 1;
            for inst in f.layout.block_insts(bb) {
                let side_effect = has_lowering_side_effect(f, inst);
                // Assign colors. A new color is chosen *after* any side-effecting instruction.
                inst_colors[inst] = InstColor::new(cur_color);
                debug!("bb {} inst {} has color {}", bb, inst, cur_color);
                if side_effect {
                    debug!(" -> side-effecting");
                    inst_needed[inst] = true;
                    cur_color += 1;
                }
                // Determine if this is a constant; if so, add to the table.
                if let Some(c) = is_constant_64bit(f, inst) {
                    debug!(" -> constant: {}", c);
                    inst_constants.insert(inst, c);
                }
            }
        }
        let vreg_needed = std::iter::repeat(false).take(next_vreg as usize).collect();
        Ok(Lower {
            f,
            vcode,
            value_regs,
            retval_regs,
            inst_colors,
            inst_constants,
            inst_needed,
            vreg_needed,
            next_vreg,
            block_insts: vec![],
            block_ranges: vec![],
            bb_insts: vec![],
            ir_insts: vec![],
            pinned_reg: None,
            vm_context,
        })
    }
pub fn new ( f : & ' func Function , abi : Box < dyn ABICallee < I = I > > , emit_info : I :: Info , block_order : BlockLoweringOrder , ) -> CodegenResult < Lower < ' func , I > > { let mut vcode = VCodeBuilder :: new ( abi , emit_info , block_order ) ; let mut next_vreg : u32 = 0 ; let mut value_regs = SecondaryMap :: with_default ( Reg :: invalid ( ) ) ; // Assign a vreg to each block param and each inst result. for bb in f . layout . blocks ( ) { for & param in f . dfg . block_params ( bb ) { let ty = f . dfg . value_type ( param ) ; let vreg = alloc_vreg ( & mut value_regs , I :: rc_for_type ( ty ) ? , param , & mut next_vreg ) ; vcode . set_vreg_type ( vreg , ty ) ; debug ! ( " " bb param vreg ) ; } for inst in f . layout . block_insts ( bb ) { for & result in f . dfg . inst_results ( inst ) { let ty = f . dfg . value_type ( result ) ; let vreg = alloc_vreg ( & mut value_regs , I :: rc_for_type ( ty ) ? , result , & mut next_vreg ) ; vcode . set_vreg_type ( vreg , ty ) ; debug ! ( " " bb inst f dfg [ inst ] vreg ) ; } } } let vm_context = f . signature . special_param_index ( ArgumentPurpose :: VMContext ) . map ( | vm_context_index | { let entry_block = f . layout . entry_block ( ) . unwrap ( ) ; let param = f . dfg . block_params ( entry_block ) [ vm_context_index ] ; value_regs [ param ] } ) ; // Assign a vreg to each return value. let mut retval_regs = vec ! [ ] ; for ret in & f . signature . returns { let v = next_vreg ; next_vreg += 1 ; let regclass = I :: rc_for_type ( ret . value_type ) ? ; let vreg = Reg :: new_virtual ( regclass , v ) ; retval_regs . push ( vreg ) ; vcode . set_vreg_type ( vreg . as_virtual_reg ( ) . unwrap ( ) , ret . value_type ) ; } // Compute instruction colors, find constant instructions, and find instructions with // side-effects, in one combined pass. let mut cur_color = 0 ; let mut inst_colors = SecondaryMap :: with_default ( InstColor :: new ( 0 ) ) ; let mut inst_constants = FxHashMap :: default ( ) ; let mut inst_needed = SecondaryMap :: with_default ( false ) ; for bb in f . layout . blocks ( ) { cur_color += 1 ; for inst in f . layout . block_insts ( bb ) { let side_effect = has_lowering_side_effect ( f , inst ) ; // Assign colors. A new color is chosen *after* any side-effecting instruction. inst_colors [ inst ] = InstColor :: new ( cur_color ) ; debug ! ( " " bb inst cur_color ) ; if side_effect { debug ! ( " " ) ; inst_needed [ inst ] = true ; cur_color += 1 ; } // Determine if this is a constant; if so, add to the table. if let Some ( c ) = is_constant_64bit ( f , inst ) { debug ! ( " " c ) ; inst_constants . insert ( inst , c ) ; } } } let vreg_needed = std :: iter :: repeat ( false ) . take ( next_vreg as usize ) . collect ( ) ; Ok ( Lower { f , vcode , value_regs , retval_regs , inst_colors , inst_constants , inst_needed , vreg_needed , next_vreg , block_insts : vec ! [ ] , block_ranges : vec ! [ ] , bb_insts : vec ! [ ] , ir_insts : vec ! [ ] , pinned_reg : None , vm_context , } ) }
Prepare a new lowering context for the given IR function.
Prepare a new lowering context for the given IR function .
f
&'func Function
abi
Box<dyn ABICallee<I = I>>
emit_info
I::Info
block_order
BlockLoweringOrder