/* 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; }
/* -------------------------------------------------------------- * 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; } }