fn rewrite_insert(
        &self,
        insert_before: LinkedHashMap<usize, Vec<Box<ASMCode>>>,
        insert_after: LinkedHashMap<usize, Vec<Box<ASMCode>>>
    ) -> Box<ASMCode> {
        trace!("insert spilling code");
        let mut ret = ASMCode {
            name: self.name.clone(),
            entry: self.entry.clone(),
            code: vec![],
            blocks: linked_hashmap!{},
            frame_size_patchpoints: vec![]
        };

        // how many instructions have been inserted
        let mut inst_offset = 0;
        let mut cur_block_start = usize::MAX;

        // inst N in old machine code is N' in new machine code
        // this map stores the relationship
        let mut location_map: LinkedHashMap<usize, usize> = LinkedHashMap::new();

        // iterate through old machine code
        for i in 0..self.number_of_insts() {
            trace!("Inst{}", i);

            if self.is_block_start(i) {
                cur_block_start = i + inst_offset;
                trace!("  block start is shifted to {}", cur_block_start);
            }

            // insert code before this instruction
            if insert_before.contains_key(&i) {
                for insert in insert_before.get(&i).unwrap() {
                    ret.append_code_sequence_all(insert);
                    inst_offset += insert.number_of_insts();
                    trace!("  inserted {} insts before", insert.number_of_insts());
                }
            }

            // copy this instruction
            let mut inst = self.code[i].clone();

            // old ith inst is now the (i + inst_offset)th instruction
            location_map.insert(i, i + inst_offset);
            trace!("  Inst{} is now Inst{}", i, i + inst_offset);

            // this instruction has been offset by several instructions('inst_offset')
            // update its info
            // 1. fix defines and uses
            for locs in inst.defines.values_mut() {
                for loc in locs {
                    debug_assert!(loc.line == i);
                    loc.line += inst_offset;
                }
            }
            for locs in inst.uses.values_mut() {
                for loc in locs {
                    debug_assert!(loc.line == i);
                    loc.line += inst_offset;
                }
            }
            // 2. we need to delete existing preds/succs - CFA is required later
            inst.preds.clear();
            inst.succs.clear();
            // 3. add the inst
            ret.code.push(inst);


            // insert code after this instruction
            if insert_after.contains_key(&i) {
                for insert in insert_after.get(&i).unwrap() {
                    ret.append_code_sequence_all(insert);
                    inst_offset += insert.number_of_insts();
                    trace!("  inserted {} insts after", insert.number_of_insts());
                }
            }

            // if we finish a block
            if self.is_last_inst_in_block(i) {
                let cur_block_end = i + 1 + inst_offset;

                // copy the block
                let (name, block) = self.get_block_by_inst(i);

                let new_block = ASMBlock {
                    start_inst: cur_block_start,
                    end_inst: cur_block_end,

                    livein: vec![],
                    liveout: vec![]
                };

                trace!("  old block: {:?}", block);
                trace!("  new block: {:?}", new_block);

                cur_block_start = usize::MAX;

                // add to the new code
                ret.blocks.insert(name.clone(), new_block);
            }
        }

        // fix patchpoints
        for patchpoint in self.frame_size_patchpoints.iter() {
            let new_patchpoint = ASMLocation {
                line: *location_map.get(&patchpoint.line).unwrap(),
                index: patchpoint.index,
                len: patchpoint.len,
                oplen: patchpoint.oplen
            };

            ret.frame_size_patchpoints.push(new_patchpoint);
        }

        ret.control_flow_analysis();

        Box::new(ret)
    }
/// rewrites code by inserting instructions in certain locations
/// This function is used for inserting spilling instructions. It takes
/// two hashmaps as arguments, the keys of which are line numbers where
/// we should insert code, and the values are the code to be inserted.
/// We need to carefully ensure the metadata for existing code is
/// still correct after insertion. This function returns the resulting code.
rewrites code by inserting instructions in certain locations
This function is used for inserting spilling instructions. It takes
two hashmaps as arguments, the keys of which are line numbers where
we should insert code, and the values are the code to be inserted.
We need to carefully ensure the metadata for existing code is
still correct after insertion. This function returns the resulting code.
rewrites code by inserting instructions in certain locations This function is used for inserting spilling instructions . It takes two hashmaps as arguments the keys of which are line numbers where we should insert code and the values are the code to be inserted . We need to carefully ensure the metadata for existing code is still correct after insertion . This function returns the resulting code .
fn rewrite_insert(
        &self,
        insert_before: LinkedHashMap<usize, Vec<Box<ASMCode>>>,
        insert_after: LinkedHashMap<usize, Vec<Box<ASMCode>>>
    ) -> Box<ASMCode> {
        trace!("insert spilling code");
        let mut ret = ASMCode {
            name: self.name.clone(),
            entry: self.entry.clone(),
            code: vec![],
            blocks: linked_hashmap!{},
            frame_size_patchpoints: vec![]
        };
        // how many instructions have been inserted
        let mut inst_offset = 0;
        let mut cur_block_start = usize::MAX;
        // inst N in old machine code is N' in new machine code
        // this map stores the relationship
        let mut location_map: LinkedHashMap<usize, usize> = LinkedHashMap::new();
        // iterate through old machine code
        for i in 0..self.number_of_insts() {
            trace!("Inst{}", i);
            if self.is_block_start(i) {
                cur_block_start = i + inst_offset;
                trace!("  block start is shifted to {}", cur_block_start);
            }
            // insert code before this instruction
            if insert_before.contains_key(&i) {
                for insert in insert_before.get(&i).unwrap() {
                    ret.append_code_sequence_all(insert);
                    inst_offset += insert.number_of_insts();
                    trace!("  inserted {} insts before", insert.number_of_insts());
                }
            }
            // copy this instruction
            let mut inst = self.code[i].clone();
            // old ith inst is now the (i + inst_offset)th instruction
            location_map.insert(i, i + inst_offset);
            trace!("  Inst{} is now Inst{}", i, i + inst_offset);
            // this instruction has been offset by several instructions('inst_offset')
            // update its info
            // 1. fix defines and uses
            for locs in inst.defines.values_mut() {
                for loc in locs {
                    debug_assert!(loc.line == i);
                    loc.line += inst_offset;
                }
            }
            for locs in inst.uses.values_mut() {
                for loc in locs {
                    debug_assert!(loc.line == i);
                    loc.line += inst_offset;
                }
            }
            // 2. we need to delete existing preds/succs - CFA is required later
            inst.preds.clear();
            inst.succs.clear();
            // 3. add the inst
            ret.code.push(inst);
            // insert code after this instruction
            if insert_after.contains_key(&i) {
                for insert in insert_after.get(&i).unwrap() {
                    ret.append_code_sequence_all(insert);
                    inst_offset += insert.number_of_insts();
                    trace!("  inserted {} insts after", insert.number_of_insts());
                }
            }
            // if we finish a block
            if self.is_last_inst_in_block(i) {
                let cur_block_end = i + 1 + inst_offset;
                // copy the block
                let (name, block) = self.get_block_by_inst(i);
                let new_block = ASMBlock {
                    start_inst: cur_block_start,
                    end_inst: cur_block_end,
                    livein: vec![],
                    liveout: vec![]
                };
                trace!("  old block: {:?}", block);
                trace!("  new block: {:?}", new_block);
                cur_block_start = usize::MAX;
                // add to the new code
                ret.blocks.insert(name.clone(), new_block);
            }
        }
        // fix patchpoints
        for patchpoint in self.frame_size_patchpoints.iter() {
            let new_patchpoint = ASMLocation {
                line: *location_map.get(&patchpoint.line).unwrap(),
                index: patchpoint.index,
                len: patchpoint.len,
                oplen: patchpoint.oplen
            };
            ret.frame_size_patchpoints.push(new_patchpoint);
        }
        ret.control_flow_analysis();
        Box::new(ret)
    }
fn rewrite_insert ( & self , insert_before : LinkedHashMap < usize , Vec < Box < ASMCode > > > , insert_after : LinkedHashMap < usize , Vec < Box < ASMCode > > > ) -> Box < ASMCode > { trace ! ( " " ) ; let mut ret = ASMCode { name : self . name . clone ( ) , entry : self . entry . clone ( ) , code : vec ! [ ] , blocks : linked_hashmap ! { } , frame_size_patchpoints : vec ! [ ] } ; // how many instructions have been inserted let mut inst_offset = 0 ; let mut cur_block_start = usize :: MAX ; // inst N in old machine code is N' in new machine code // this map stores the relationship let mut location_map : LinkedHashMap < usize , usize > = LinkedHashMap :: new ( ) ; // iterate through old machine code for i in 0 .. self . number_of_insts ( ) { trace ! ( " " i ) ; if self . is_block_start ( i ) { cur_block_start = i + inst_offset ; trace ! ( " " cur_block_start ) ; } // insert code before this instruction if insert_before . contains_key ( & i ) { for insert in insert_before . get ( & i ) . unwrap ( ) { ret . append_code_sequence_all ( insert ) ; inst_offset += insert . number_of_insts ( ) ; trace ! ( " " insert number_of_insts ( ) ) ; } } // copy this instruction let mut inst = self . code [ i ] . clone ( ) ; // old ith inst is now the (i + inst_offset)th instruction location_map . insert ( i , i + inst_offset ) ; trace ! ( " " i i inst_offset ) ; // this instruction has been offset by several instructions('inst_offset') // update its info // 1. fix defines and uses for locs in inst . defines . values_mut ( ) { for loc in locs { debug_assert ! ( loc line i ) ; loc . line += inst_offset ; } } for locs in inst . uses . values_mut ( ) { for loc in locs { debug_assert ! ( loc line i ) ; loc . line += inst_offset ; } } // 2. we need to delete existing preds/succs - CFA is required later inst . preds . clear ( ) ; inst . succs . clear ( ) ; // 3. add the inst ret . code . push ( inst ) ; // insert code after this instruction if insert_after . contains_key ( & i ) { for insert in insert_after . get ( & i ) . unwrap ( ) { ret . append_code_sequence_all ( insert ) ; inst_offset += insert . number_of_insts ( ) ; trace ! ( " " insert number_of_insts ( ) ) ; } } // if we finish a block if self . is_last_inst_in_block ( i ) { let cur_block_end = i + 1 + inst_offset ; // copy the block let ( name , block ) = self . get_block_by_inst ( i ) ; let new_block = ASMBlock { start_inst : cur_block_start , end_inst : cur_block_end , livein : vec ! [ ] , liveout : vec ! [ ] } ; trace ! ( " " block ) ; trace ! ( " " new_block ) ; cur_block_start = usize :: MAX ; // add to the new code ret . blocks . insert ( name . clone ( ) , new_block ) ; } } // fix patchpoints for patchpoint in self . frame_size_patchpoints . iter ( ) { let new_patchpoint = ASMLocation { line : * location_map . get ( & patchpoint . line ) . unwrap ( ) , index : patchpoint . index , len : patchpoint . len , oplen : patchpoint . oplen } ; ret . frame_size_patchpoints . push ( new_patchpoint ) ; } ret . control_flow_analysis ( ) ; Box :: new ( ret ) }
rewrites code by inserting instructions in certain locations
This function is used for inserting spilling instructions.
rewrites code by inserting instructions in certain locations This function is used for inserting spilling instructions .
&self
insert_before
LinkedHashMap<usize, Vec<Box<ASMCode>>>
insert_after
LinkedHashMap<usize, Vec<Box<ASMCode>>>
&self
insert_before
LinkedHashMap<usize, Vec<Box<ASMCode>>>
insert_after
LinkedHashMap<usize, Vec<Box<ASMCode>>>