#include "regalloc.hpp" #include "Instruction.h" #include "liverange.hpp" #include using std::for_each; using namespace RA; bool RA::no_reg_alloca(Value *v) { auto instr = static_cast(v); return instr->is_alloca() or instr->is_cmp() or instr->is_fcmp() or instr->is_zext(); } void RegAllocator::reset() { regmap.clear(); active.clear(); for_each(used, used + R + 1, [](bool &u) { u = false; }); } void RegAllocator::LinearScan(const LVITS &liveints) { reset(); int reg; for (auto liveint : liveints) { if (no_reg_alloca(liveint.second)) continue; ExpireOldIntervals(liveint); if (active.size() == R) SpillAtInterval(liveint); else { for (reg = 1; reg <= R and used[reg]; ++reg) ; used[reg] = true; regmap[liveint.second] = reg; active.insert(liveint); } } } void RegAllocator::ExpireOldIntervals(LiveInterval liveint) { auto it = active.begin(); for (; it != active.end() and it->first.j < liveint.first.i; ++it) used[regmap.at(it->second)] = false; active.erase(active.begin(), it); } void RegAllocator::SpillAtInterval(LiveInterval liveint) { auto spill = *active.rbegin(); if (spill.first.j > liveint.first.j) { // cancel reg allocation for spill regmap[liveint.second] = regmap.at(spill.second); active.erase(spill); regmap.erase(spill.second); } }