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) { ...@@ -57,12 +57,23 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
auto quadEnv = quadGen.compileFunction(f); auto quadEnv = quadGen.compileFunction(f);
RegisterAllocator regGen(quadEnv); RegisterAllocator regGen = RegisterAllocator(quadEnv);
regGen.allocate(); regGen.allocate();
int blkNo = 0;
for (const auto& b : quadEnv.blocks) { for (const auto& b : quadEnv.blocks) {
buf << "------------------------------\n"; 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()) { if (!b->flow.in.empty()) {
buf << "in: "; buf << "in: ";
for (const auto& v : b->flow.in) { for (const auto& v : b->flow.in) {
...@@ -70,10 +81,28 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) { ...@@ -70,10 +81,28 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
} }
buf << "\n----------\n"; 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) { for (const auto& q : b->quads) {
auto ret = q->toString(); auto ret = q->toString();
if (!ret.empty()) if (!ret.empty()) {
buf << ret << endl; 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()) { if (!b->flow.out.empty()) {
buf << "----------\nout: "; buf << "----------\nout: ";
...@@ -82,5 +111,6 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) { ...@@ -82,5 +111,6 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
} }
buf << "\n"; buf << "\n";
} }
blkNo++;
} }
} }
...@@ -49,6 +49,15 @@ public: ...@@ -49,6 +49,15 @@ public:
after->phi->phi.emplace_back(); 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) { void addJumpInitQuad(const QuadruplePtr& q) {
afterInit.push_back(q); afterInit.push_back(q);
} }
......
...@@ -41,6 +41,7 @@ public: ...@@ -41,6 +41,7 @@ public:
int lineno; int lineno;
int index; int index;
BasicBlockPtr block; BasicBlockPtr block;
set<VariablePtr> aliveAfter;
virtual ~Quadruple() = default; virtual ~Quadruple() = default;
virtual std::string toString() const { return to_string(lineno) + "\t"; }; virtual std::string toString() const { return to_string(lineno) + "\t"; };
...@@ -53,6 +54,7 @@ public: ...@@ -53,6 +54,7 @@ public:
} }
}; };
virtual vector<VariablePtr> vars() const { return {}; }; virtual vector<VariablePtr> vars() const { return {}; };
virtual vector<VariablePtr> definitions() const { return {}; };
}; };
class QWriteVar : public Quadruple { class QWriteVar : public Quadruple {
...@@ -65,6 +67,11 @@ public: ...@@ -65,6 +67,11 @@ public:
Quadruple::useVariables(); Quadruple::useVariables();
if (loc) loc->writes.emplace_back(shared_from_this()); 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 { class QLabel : public Quadruple {
...@@ -161,7 +168,14 @@ public: ...@@ -161,7 +168,14 @@ public:
void useVariables() override { void useVariables() override {
Quadruple::useVariables(); Quadruple::useVariables();
if (param && num < 0) param->writes.emplace_back(shared_from_this()); 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 { class QCall : public QWriteVar {
public: public:
...@@ -300,6 +314,18 @@ 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 { std::string toString() const override {
if (phi.size() < 2) return ""; if (phi.size() < 2) return "";
std::string ret = Quadruple::toString() + "phi "; std::string ret = Quadruple::toString() + "phi ";
......
...@@ -381,6 +381,7 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) { ...@@ -381,6 +381,7 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
} }
void QuadrupleGenerator::compileCond(Expr *expr_, Stmt *stmt_1, Stmt *stmt_2) { 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 elseBranch = make_shared<QLabel>("else");
auto after = make_shared<QLabel>("end_else"); auto after = make_shared<QLabel>("end_else");
...@@ -451,10 +452,11 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -451,10 +452,11 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// env2 starts with hooked variables // env2 starts with hooked variables
auto env2 = captureEnv(); auto env2 = captureEnv();
auto loopFirstBlock = block;
expr->stmt_->accept(this); expr->stmt_->accept(this);
auto loopBlock = flushBasicBlock(); // jump <- cond auto loopLastBlock = flushBasicBlock(); // jump <- cond
auto condBlock = block; auto condBlock = block;
addQuad(cond); addQuad(cond);
...@@ -464,8 +466,8 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -464,8 +466,8 @@ void QuadrupleGenerator::visitWhile(While *expr) {
env1.revert(); env1.revert();
beforeBlock->append(condBlock); beforeBlock->append(condBlock);
condBlock->append(loopBlock); condBlock->append(loopFirstBlock);
loopBlock->append(condBlock); loopLastBlock->append(condBlock);
for (const auto& p : env2.changes) { for (const auto& p : env2.changes) {
auto info = p.first; auto info = p.first;
...@@ -477,9 +479,9 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -477,9 +479,9 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// transition from pre-hook to hooked var [before -> cond] // transition from pre-hook to hooked var [before -> cond]
auto orig = env1.changes[info].first; auto orig = env1.changes[info].first;
condBlock->addPhi(beforeBlock, hooked, orig); 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 // expr uses pre-hook variables iff unused in loop
......
...@@ -42,4 +42,35 @@ void RegisterAllocator::analyseLive() { ...@@ -42,4 +42,35 @@ void RegisterAllocator::analyseLive() {
void RegisterAllocator::allocate() { void RegisterAllocator::allocate() {
analyseLive(); 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: ...@@ -27,10 +27,12 @@ public:
void processQCall(shared_ptr<QCall> q); void processQCall(shared_ptr<QCall> q);
void allocate(); void allocate();
void buildGraph();
private: private:
void analyseLive(); void analyseLive();
vector<BasicBlockPtr> blocks; vector<BasicBlockPtr> blocks;
vector<VariablePtr> vars; vector<VariablePtr> vars;
set<pair<VariablePtr, VariablePtr>> graphEdges;
}; };
......
...@@ -31,6 +31,18 @@ set<T>& operator+=(set<T> &l, const set<T> &r) { ...@@ -31,6 +31,18 @@ set<T>& operator+=(set<T> &l, const set<T> &r) {
return l; 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> template<typename T>
bool operator==(const set<T> &l, const set<T> &r) { bool operator==(const set<T> &l, const set<T> &r) {
return (r^l).empty(); return (r^l).empty();
...@@ -41,4 +53,12 @@ bool operator!=(const set<T> &l, const set<T> &r) { ...@@ -41,4 +53,12 @@ bool operator!=(const set<T> &l, const set<T> &r) {
return !(r == l); 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 #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