/* Linear Scan Algorithm for SSA form (support splitting of interval) */
void RegisterAllocator::linearScanSSA () {
    // initialize four sets recording the system state
    active.clear();
    inactive.clear();
    handled.clear();
    unhandled.clear();
    for (int i = 0; i < iid_start_pairs.size(); i ++) 
        unhandled.insert(iid_start_pairs[i].first);
    // start linear scan algorithm
    std::cout << "Total number of intervals:" << all_intervals.size() << std::endl;
    int num_pre_intervals = iid_start_pairs.size();
    for (int i = 0; i < iid_start_pairs.size(); i ++) {
        int cur_iid = iid_start_pairs[i].first;
        int cur_start = iid_start_pairs[i].second;
        bool expire_after_processed = false;
        if (inactive.find(cur_iid) != inactive.end()) {
            // it must be splitted intervals
            inactive.erase(cur_iid);
            if (all_intervals[cur_iid]->liveranges.rbegin()->endpoint == cur_start) {
                // directly turn to handled since it is going to expire
                expire_after_processed = true;
            }
        }
        std::cout << "-------------------------------" << std::endl;
        std::cout << "Interval: " << cur_iid << ", cur: " << cur_start << ", end: " 
                  << all_intervals[cur_iid]->liveranges.rbegin()->endpoint
                  << std::endl;

        std::cout << "active_set_size: "   << active.size() << ", "
                  << "inactive_set_size: " << inactive.size() 
                  << std::endl;

        std::cout << ">> updateRAState(): " << std::endl;
        updateRAState(i); // update Register Allocation State

        std::cout << "active_set_size: "   << active.size() << ", "
                  << "inactive_set_size: " << inactive.size() 
                  << std::endl;
        std::cout << "active_iid: ";
        for (int iid : active) std::cout << iid << " ";
        std::cout <<  std::endl;
        std::cout << "inactive_iid: ";
        for (int iid : inactive) std::cout << iid << " ";
        std::cout <<  std::endl;
        
        int reg;
        if (active.size() == NUM_REGS) {
            // look for one occupied register to allocate
            std::cout << ">> allocateBlockedReg():" << std::endl;
            reg = allocateBlockedReg(i);
            int spill = register_map[reg];
            active.erase(spill);
            inactive.insert(spill);
            std::cout << "active_erase: " << spill 
                      << ", active_after: " << active.size()
                      << ", inactive_after: " << inactive.size()
                      << std::endl;
            splitInterval(spill, cur_start, reg);
        } else {
            // look for one register to allocate
            std::cout << ">> tryAllocateFreeReg():"  << std::endl;
            reg = tryAllocateFreeReg(i); 
        }
        std::cout << "register assigned = " << reg << std::endl;
        assigned_registers.push_back(reg);
        register_map[reg] = cur_iid;
        virtual2machine[cur_iid] = reg;
        if (!expire_after_processed && active.find(cur_iid)==active.end()) 
            active.insert(cur_iid);
        if (unhandled.find(cur_iid) != unhandled.end()) unhandled.erase(cur_iid);
        std::cout << "REGISTER_MAP: ";
        for (auto it=register_map.begin(); it!=register_map.end(); it++) 
            std::cout << it->first << ":" << it->second << " ";
        std::cout << std::endl;
        transitions.push_back(register_map);
    }

    //###########################################################
    // Assign register to live ranges
    //###########################################################
    assert(assigned_registers.size() == iid_start_pairs.size() 
            && "size equality constraint fails");
    for (int i = 0; i < iid_start_pairs.size(); i ++) {
        int cur_iid = iid_start_pairs[i].first;
        int cur_start = iid_start_pairs[i].second;
        Interval* itv = all_intervals[cur_iid];
        for (int j = 0; j < itv->liveranges.size(); j ++) {
            if (itv->liveranges[j].isInRange(cur_start)) {
                itv->liveranges[j].pos = assigned_registers[i];
                break;
            }
        }
    }

    //###########################################################
    // Print Physical Register Status Transition
    //###########################################################
    std::cout << "------------RegisterTransition---BEGIN-------" << std::endl;
    for (int i = 0; i < transitions.size(); i ++) {
        for (auto it=transitions[i].begin(); it!=transitions[i].end(); it++)  {
            std::cout << "r" << it->first << ":" << it->second << " ";
        }
        std::cout << std::endl;
    }
    std::cout << "------------RegisterTransition----END------" << std::endl;
}
Exemple #2
0
Fichier : modl.c Projet : nionjo/dm
/* --------------------------------------------------------------
 * brief   : do split, merge split, merge merge split operation
 *           and select the best operation to do
 * Interval M : current Intervals
 * int l      : number of current Intervals
 * Interval I : greedinited Intervals
 * int m      : number of greedinited Intervals
 * int n      : number of elements
 * int *ol    : number of optimized Intervals, the final solution
 * return     : the delta of optimization
 * -------------------------------------------------------------- */
static double optimize(Interval * M, int l,  Interval * I, int m, int n, int *ol, double * LogD){
    int i,j,k;
    int spi = 0, msi = 0, mmsi = 0;
    double mxspd,spd,mxmsd,msd,mxmmsd,mmsd;
    Interval s1, s2, ss1, ss2, ms1, ms2, mms1, mms2, t, tt;

    // split operation
    mxspd = -10e12;
    for (i = 0; i< l; i++){
        memmove(t, M[i], sizeof(Interval));
        spd = splitInterval(t,s1,s2,I,l,m,n, LogD);
        if (spd > mxspd){
            mxspd = spd;
            memmove(ss1,s1,sizeof(Interval));
            memmove(ss2,s2,sizeof(Interval));
            spi = i;
        }
    }

    // merge split operation
    mxmsd = -10e12;
    for( i = 0; i < l - 1; i++){
        j = i + 1;
        memmove(t,M[i],sizeof(Interval));
        mergeInterval(t,M[j]);
        msd = getDelta(M[i],M[j],t,l,n,LogD);
        msd += splitInterval(t, s1, s2, I, l - 1, m, n, LogD);
        if (msd > mxmsd){
            mxmsd = msd;
            memmove(ms1,s1,sizeof(Interval));
            memmove(ms2,s2,sizeof(Interval));
            msi = i;
        }
    }

    // merge merge split operation
    mxmmsd = -10e12;
    for (i = 0; i< l - 2; i++){
        j = i + 1; k = i + 2;
        memmove(t,M[i],sizeof(Interval));
        mergeInterval(t,M[j]);
        mmsd = getDelta(M[i], M[j], t, l, n, LogD);
        memmove(tt,t,sizeof(Interval));
        mergeInterval(t,M[k]);
        mmsd += getDelta(tt, M[k], t, l - 1, n, LogD);
        mmsd += splitInterval(t,s1,s2,I,l - 2,m,n, LogD);
        if (mmsd > mxmmsd){
            mxmmsd = mmsd;
            memmove(mms1,s1,sizeof(Interval));
            memmove(mms2,s2,sizeof(Interval));
            mmsi = i;
        }
    }

    *ol = l;
    if (mxspd > 0.0 && mxspd >= mxmsd && mxspd >= mxmmsd){
        if (spi < l - 1){
            memmove(M[spi + 2], M[spi + 1], sizeof(Interval) * (l - spi - 1));
        }
        memmove(M[spi],ss1,sizeof(Interval));
        memmove(M[spi + 1],ss2,sizeof(Interval));
        *ol += 1;
        return mxspd;
    }
    else if (mxmsd > 0.0 && mxmsd >= mxspd && mxmsd >= mxmmsd){
        memmove(M[msi],ms1,sizeof(Interval));
        memmove(M[msi + 1],ms2,sizeof(Interval));
        return mxmsd;
    }
    else if (mxmmsd > 0.0 && mxmmsd >= mxspd && mxmmsd >= mxmsd){
        memmove(M[mmsi],mms1,sizeof(Interval));
        memmove(M[mmsi + 1], mms2, sizeof(Interval));
        if (mmsi < l - 3){
            memmove(M[mmsi + 2],M[mmsi + 3],sizeof(Interval) * (l - mmsi - 3));
        }
        *ol -= 1;
        return mxmmsd;
    }
    else{
        return -1.0;
    }
}