Commit bc58b2c2 authored by zygzagZ's avatar zygzagZ

known alive variables after every quadruple

parent a83f92b3
......@@ -57,12 +57,23 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
auto quadEnv = quadGen.compileFunction(f);
RegisterAllocator regGen(quadEnv);
RegisterAllocator regGen = RegisterAllocator(quadEnv);
regGen.allocate();
int blkNo = 0;
for (const auto& b : quadEnv.blocks) {
buf << "------------------------------\n";
buf << "blok " << blkNo << " " << b->getName() << endl;
/*buf << "in: ";
for (auto in : b->in) {
buf << in->getName() << " ";
}
buf << "\nouts: ";
for (auto out : b->out) {
buf << out->getName() << " ";
}
buf << "\n";*/
if (!b->flow.in.empty()) {
buf << "in: ";
for (const auto& v : b->flow.in) {
......@@ -70,10 +81,28 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
}
buf << "\n----------\n";
}
if (!b->flow.def.empty()) {
buf << "def: ";
for (const auto& v : b->flow.def) {
buf << v->name << ", ";
}
buf << "\n----------\n";
}
for (const auto& q : b->quads) {
auto ret = q->toString();
if (!ret.empty())
buf << ret << endl;
if (!ret.empty()) {
buf << ret << " alive: ";
for (auto var : q->aliveAfter)
buf << var->name << " ";
buf << endl;
}
}
if (!b->flow.use.empty()) {
buf << "----------\nuse: ";
for (const auto &v : b->flow.use) {
buf << v->name << ", ";
}
buf << "\n";
}
if (!b->flow.out.empty()) {
buf << "----------\nout: ";
......@@ -82,5 +111,6 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
}
buf << "\n";
}
blkNo++;
}
}
......@@ -49,6 +49,15 @@ public:
after->phi->phi.emplace_back();
}
std::string getName() const {
for (const auto& q : quads) {
if (auto l = dynamic_pointer_cast<QLabel>(q)) {
return l->label;
}
}
return "?";
}
void addJumpInitQuad(const QuadruplePtr& q) {
afterInit.push_back(q);
}
......
......@@ -41,6 +41,7 @@ public:
int lineno;
int index;
BasicBlockPtr block;
set<VariablePtr> aliveAfter;
virtual ~Quadruple() = default;
virtual std::string toString() const { return to_string(lineno) + "\t"; };
......@@ -53,6 +54,7 @@ public:
}
};
virtual vector<VariablePtr> vars() const { return {}; };
virtual vector<VariablePtr> definitions() const { return {}; };
};
class QWriteVar : public Quadruple {
......@@ -65,6 +67,11 @@ public:
Quadruple::useVariables();
if (loc) loc->writes.emplace_back(shared_from_this());
}
vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions();
if (loc) ret.emplace_back(loc);
return ret;
};
};
class QLabel : public Quadruple {
......@@ -161,7 +168,14 @@ public:
void useVariables() override {
Quadruple::useVariables();
if (param && num < 0) param->writes.emplace_back(shared_from_this());
}};
}
vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions();
if (param && num < 0) ret.emplace_back(param);
return ret;
};
};
class QCall : public QWriteVar {
public:
......@@ -300,6 +314,18 @@ public:
}
}
vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions();
set<VariablePtr> written;
for (const auto& b : phi) {
for (const auto &v : b) {
written.emplace(v.first);
}
}
std::copy(written.begin(), written.end(), std::back_inserter(ret));
return ret;
};
std::string toString() const override {
if (phi.size() < 2) return "";
std::string ret = Quadruple::toString() + "phi ";
......
......@@ -381,6 +381,7 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
}
void QuadrupleGenerator::compileCond(Expr *expr_, Stmt *stmt_1, Stmt *stmt_2) {
// TODO: stmty nie składają się z jednego bloku tylko z wielu
auto elseBranch = make_shared<QLabel>("else");
auto after = make_shared<QLabel>("end_else");
......@@ -451,10 +452,11 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// env2 starts with hooked variables
auto env2 = captureEnv();
auto loopFirstBlock = block;
expr->stmt_->accept(this);
auto loopBlock = flushBasicBlock(); // jump <- cond
auto loopLastBlock = flushBasicBlock(); // jump <- cond
auto condBlock = block;
addQuad(cond);
......@@ -464,8 +466,8 @@ void QuadrupleGenerator::visitWhile(While *expr) {
env1.revert();
beforeBlock->append(condBlock);
condBlock->append(loopBlock);
loopBlock->append(condBlock);
condBlock->append(loopFirstBlock);
loopLastBlock->append(condBlock);
for (const auto& p : env2.changes) {
auto info = p.first;
......@@ -477,9 +479,9 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// transition from pre-hook to hooked var [before -> cond]
auto orig = env1.changes[info].first;
condBlock->addPhi(beforeBlock, hooked, orig);
condBlock->addPhi(loopBlock, hooked, looped);
condBlock->addPhi(loopLastBlock, hooked, looped);
// loopBlock doesn't need phi, it has only one incoming block
// loopLastBlock doesn't need phi, it has only one incoming block
}
// expr uses pre-hook variables iff unused in loop
......
......@@ -42,4 +42,35 @@ void RegisterAllocator::analyseLive() {
void RegisterAllocator::allocate() {
analyseLive();
buildGraph();
}
void RegisterAllocator::buildGraph() {
for (const auto& b : blocks) {
set<VariablePtr> alive = b->flow.in;
for (const auto& q : b->quads) {
alive += to_set(q->definitions());
vector<VariablePtr> dead;
for (const auto& var : alive) {
// this quad is the last quad that uses var
if ((var->uses.empty() || var->uses.back() == q) && !b->flow.out.contains(var)) {
dead.emplace_back(var);
}
}
alive -= to_set(dead);
q->aliveAfter = alive;
for (auto i : alive) {
for (auto j : alive) {
if (i != j) {
if (i.get() > j.get()) {
swap(i, j);
}
graphEdges.insert(make_pair(i, j));
}
}
}
}
}
}
......@@ -27,10 +27,12 @@ public:
void processQCall(shared_ptr<QCall> q);
void allocate();
void buildGraph();
private:
void analyseLive();
vector<BasicBlockPtr> blocks;
vector<VariablePtr> vars;
set<pair<VariablePtr, VariablePtr>> graphEdges;
};
......
......@@ -31,6 +31,18 @@ set<T>& operator+=(set<T> &l, const set<T> &r) {
return l;
}
template<typename T>
set<T>& operator-=(set<T> &l, const set<T> &r) {
auto diff = l - r;
return l = diff;
}
template<typename T>
set<T>& operator^=(set<T> &l, const set<T> &r) {
auto diff = l ^ r;
return l = diff;
}
template<typename T>
bool operator==(const set<T> &l, const set<T> &r) {
return (r^l).empty();
......@@ -41,4 +53,12 @@ bool operator!=(const set<T> &l, const set<T> &r) {
return !(r == l);
}
template <typename C>
set<typename C::value_type> to_set(const C &v) {
set<typename C::value_type> res;
for (auto &i : v)
res.emplace(i);
return res;
}
#endif //ZAD2_SETOVERLOADS_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment