[LLVMdev] Recalculating live intervals

Fernando Magno Quintao Pereira fernando at CS.UCLA.EDU
Mon Aug 21 12:03:47 PDT 2006


> So what addIntervalsToSpills returns are new intervals to allocate with
> infinite weights, right?
> And I need not to allocate the old interval. Should hasStackSlot return true
> on its register then?
>

I am not very sure about addIntervalsToSpill, but, for all the registers
created to replace a spilled registers, they must have a stack slot
assigned to them. I am sending you my spilling method, so you can have an
example:

//===--------------------------------------------------------------------------
// This method performs register spilling. The parameter indicates a class
of
// registers. The spilling algorithm must evict a register from the same
class
// as the parameter. I am using the VirtRegMap class to place loads and
stores.
//===--------------------------------------------------------------------------
void RegAllocChordal_Fer::spill(
    unsigned v_reg,
    KillingSites_Fer & ks,
    const MachineBasicBlock & mbb
) {
    // First, find a place to store this register. Of course, this will be
done
    // by the implementation of vrm. We just have to ask it.
    int slot = vrm->assignVirt2StackSlot(v_reg);
    unsigned p_reg = this->reg_mapping->get_physical_location(v_reg);

    // Now, it is necessary to break the live range of the spilled
register.
    // This is done by creating new virtual registers, and substituting
the
    // spilled register by the new registers.
    MachineInstr * last_seen;
    std::vector< MachineInstr * > & use_sites =

this->def_use_sites->get_use_sites(v_reg);
    for(unsigned u = 0; u < use_sites.size(); u++) {
        MachineInstr * mi = use_sites[u];
        if(mi == last_seen) {
            continue; // this happens when the same virtual is used
multiple
                      // times in the same instruction.
        }
        unsigned new_reg = create_new_virtual_register(v_reg);
        if(mi->getParent()->getNumber() ==
ks.get_basic_block()->getNumber()) {
            ks.replace_used_reg(mi, new_reg, v_reg);
        }
        this->vrm->grow();
        this->reg_mapping->grow();
        this->vrm->assignVirt2StackSlot(new_reg, slot);
        for(unsigned t = 0; t < mi->getNumOperands(); t++) {
            MachineOperand & mo_aux = mi->getOperand(t);
            if(mo_aux.isRegister() && mo_aux.getReg() && mo_aux.isUse()) {
                if(mo_aux.getReg() == v_reg) {
                    mo_aux.setReg(new_reg);
                    this->reg_mapping->set_color_spilled_register
                                                           (new_reg, p_reg);
                }
            }
        }
        last_seen = mi;
    }

    // this method will clean the machine register, e.g. p_reg, that is
been
    // currently used to hold the color of v_reg.
    this->reg_mapping->liberate_color(p_reg);

    clean_live_range(ks, v_reg, mbb);
}



More information about the llvm-dev mailing list