Commit 19fd741d authored by zygzagZ's avatar zygzagZ

Fix phi xchg, improv liveness analysis to see through qphi

parent cacba274
...@@ -112,15 +112,15 @@ void Compiler::printFunction(const QuadrupleGenerator::Result& quadEnv, const Fu ...@@ -112,15 +112,15 @@ void Compiler::printFunction(const QuadrupleGenerator::Result& quadEnv, const Fu
for (const auto& b : quadEnv.blocks) { for (const auto& b : quadEnv.blocks) {
buf << COMMENT "----------------------------------------------------------------------------\n"; buf << COMMENT "----------------------------------------------------------------------------\n";
buf << COMMENT "blok " << blkNo << " " << b->getName() << endl; buf << COMMENT "blok " << blkNo << " " << b->getName() << endl;
/*buf << "in: "; buf << COMMENT "in: ";
for (auto in : b->in) { for (auto in : b->in) {
buf << in->getName() << " "; buf << in->getName() << " ";
} }
buf << "\nouts: "; buf << "\n" COMMENT "outs: ";
for (auto buf : b->buf) { for (auto out : b->out) {
buf << buf->getName() << " "; buf << out->getName() << " ";
} }
buf << "\n";*/ buf << "\n";
if (!b->flow.in.empty()) { if (!b->flow.in.empty()) {
buf << COMMENT "in: "; buf << COMMENT "in: ";
for (const auto& v : b->flow.in) { for (const auto& v : b->flow.in) {
...@@ -304,6 +304,12 @@ void Compiler::generateQReturn(QReturn &q) { ...@@ -304,6 +304,12 @@ void Compiler::generateQReturn(QReturn &q) {
} }
void Compiler::generateQCall(QCall &q) { void Compiler::generateQCall(QCall &q) {
if (!q.params && !q.self) {
for (auto r : registersToSave(q)) {
if (r != Register(q.loc))
append("PUSHL", r);
}
}
if (q.self) { if (q.self) {
auto tg = Register(q.self); auto tg = Register(q.self);
auto eax = Register(0); auto eax = Register(0);
...@@ -374,7 +380,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) { ...@@ -374,7 +380,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) {
// remap registers // remap registers
for (uint x = 1; x < regMap.size(); x++) { for (uint x = 1; x < regMap.size(); x++) {
auto ri = Register(x); auto ri = Register(x);
auto &rj = regMap[x]; auto rj = regMap[x];
if (rj == 0 || ri == rj) continue; if (rj == 0 || ri == rj) continue;
int riUses = 0, rjUses = 0; int riUses = 0, rjUses = 0;
for (auto r : regMap) { for (auto r : regMap) {
...@@ -389,7 +395,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) { ...@@ -389,7 +395,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) {
} }
} else { } else {
append("MOVL", rj, ri); append("MOVL", rj, ri);
rj = 0; regMap[x] = 0;
} }
} }
// load from memory // load from memory
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include "../Compiler.h" #include "../Compiler.h"
void BasicBlock::finishQuads() { void BasicBlock::finishQuads() {
assert(afterInit.empty());
if (!afterInit.empty()) { if (!afterInit.empty()) {
while (!quads.empty() && quads.back()->isFinal()) { while (!quads.empty() && quads.back()->isFinal()) {
auto final = quads.back(); auto final = quads.back();
...@@ -17,7 +18,6 @@ void BasicBlock::finishQuads() { ...@@ -17,7 +18,6 @@ void BasicBlock::finishQuads() {
afterInit.clear(); afterInit.clear();
} }
auto self = this->shared_from_this();
for (const auto& q : quads) { for (const auto& q : quads) {
q->useVariables(); q->useVariables();
} }
......
...@@ -52,9 +52,11 @@ public: ...@@ -52,9 +52,11 @@ public:
void addPhi(const BasicBlockPtr& blk, const VariablePtr& local, VariablePtr remote) { void addPhi(const BasicBlockPtr& blk, const VariablePtr& local, VariablePtr remote) {
assert(blk && local && remote); assert(blk && local && remote);
// must be possible to add local == remote, otherwise it might not live through the loop
// liveness analisys needs it in order to know that it is still used
assert(!local->info || !local->info->isInstanceVariable()); assert(!local->info || !local->info->isInstanceVariable());
auto &phiMap = findPhi(blk); auto &phiMap = findPhi(blk);
phiMap[local] = std::move(remote); phiMap[local] = remote;
} }
void finishQuads(); void finishQuads();
...@@ -63,7 +65,7 @@ public: ...@@ -63,7 +65,7 @@ public:
set<VariablePtr> in, out, def, use; set<VariablePtr> in, out, def, use;
BasicBlock *b {}; BasicBlock *b {};
void addUse(const VariablePtr& v) { void addUse(const VariablePtr& v) {
if (!def.count(v)) use.emplace(v); use.emplace(v);
} }
void addDef(const VariablePtr &v) { void addDef(const VariablePtr &v) {
...@@ -75,7 +77,10 @@ public: ...@@ -75,7 +77,10 @@ public:
set<VariablePtr> ret; set<VariablePtr> ret;
for (const auto& var : b->findPhi(q)) { for (const auto& var : b->findPhi(q)) {
if (var.second->constExpr) continue; if (var.second->constExpr) continue;
ret.emplace(var.second); // necessary because variables unused later are added to later phis
if (out.count(var.first) || use.count(var.first)) {
ret.emplace(var.second);
}
} }
return in + ret; return in + ret;
} }
......
...@@ -282,6 +282,11 @@ public: ...@@ -282,6 +282,11 @@ public:
if (access.index) ret.emplace_back(access.index); if (access.index) ret.emplace_back(access.index);
return ret; return ret;
} }
vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions();
if (loc) ret.emplace_back(loc);
return ret;
};
void generateAsm(Compiler &c) override; void generateAsm(Compiler &c) override;
}; };
......
...@@ -640,10 +640,14 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) { ...@@ -640,10 +640,14 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
if (!change.second.first) continue; if (!change.second.first) continue;
auto info = change.first; auto info = change.first;
info->loc = nullptr; info->loc = nullptr;
alloc(info); auto replaced = alloc(info);
if (info == arr->info)
arr = replaced;
} }
VarInfoPtr iter = make_shared<VarInfo>("_it", make_shared<Int>()); VarInfoPtr iter = make_shared<VarInfo>("_it", make_shared<Int>());
assert(iter);
assert(!iter->loc);
auto iter1 = alloc(iter); auto iter1 = alloc(iter);
// save hooks for later // save hooks for later
...@@ -655,6 +659,7 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) { ...@@ -655,6 +659,7 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
auto iterInfo = expr->pident_->getVar(); auto iterInfo = expr->pident_->getVar();
assert(iterInfo); assert(iterInfo);
assert(!iterInfo->loc);
auto iterVar = alloc(iterInfo); auto iterVar = alloc(iterInfo);
addQuad<QAccess>(iterVar, arr, iter1, 4, 4); addQuad<QAccess>(iterVar, arr, iter1, 4, 4);
...@@ -692,10 +697,11 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) { ...@@ -692,10 +697,11 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
} }
condFirstBlock->addPhi(beforeBlock, iter1, alloc(0)); condFirstBlock->addPhi(beforeBlock, iter1, alloc(0));
assert(iter1 != iter2);
condFirstBlock->addPhi(loopLastBlock, iter1, iter2); condFirstBlock->addPhi(loopLastBlock, iter1, iter2);
auto len = alloc(); auto len = alloc();
addQuad<QAccess>(len, arr, nullptr, 0, 0); addQuad<QAccess>(len, arr, nullptr, 0, 0); // should we use hooked arr or original arr?
addQuad<QJumpCond>(loop, iter1, Op::LT, len); addQuad<QJumpCond>(loop, iter1, Op::LT, len);
auto condLastBlock = flushBasicBlock(true); // jump -> loop auto condLastBlock = flushBasicBlock(true); // jump -> loop
......
...@@ -30,7 +30,7 @@ void RegisterAllocator::analyseLive() { ...@@ -30,7 +30,7 @@ void RegisterAllocator::analyseLive() {
auto &f = b->flow; auto &f = b->flow;
pIn.swap(f.in); pIn.swap(f.in);
pOut.swap(f.out); pOut.swap(f.out);
f.in = f.use + (pOut - f.def); f.in = (f.use + pOut) - f.def;
for (const auto& succ : b->out) { for (const auto& succ : b->out) {
f.out += succ->flow.inForBlock(b); f.out += succ->flow.inForBlock(b);
} }
......
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