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
for (const auto& b : quadEnv.blocks) {
buf << COMMENT "----------------------------------------------------------------------------\n";
buf << COMMENT "blok " << blkNo << " " << b->getName() << endl;
/*buf << "in: ";
buf << COMMENT "in: ";
for (auto in : b->in) {
buf << in->getName() << " ";
}
buf << "\nouts: ";
for (auto buf : b->buf) {
buf << buf->getName() << " ";
buf << "\n" COMMENT "outs: ";
for (auto out : b->out) {
buf << out->getName() << " ";
}
buf << "\n";*/
buf << "\n";
if (!b->flow.in.empty()) {
buf << COMMENT "in: ";
for (const auto& v : b->flow.in) {
......@@ -304,6 +304,12 @@ void Compiler::generateQReturn(QReturn &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) {
auto tg = Register(q.self);
auto eax = Register(0);
......@@ -374,7 +380,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) {
// remap registers
for (uint x = 1; x < regMap.size(); x++) {
auto ri = Register(x);
auto &rj = regMap[x];
auto rj = regMap[x];
if (rj == 0 || ri == rj) continue;
int riUses = 0, rjUses = 0;
for (auto r : regMap) {
......@@ -389,7 +395,7 @@ void Compiler::generatePhiXCHG(const map<VariablePtr, VariablePtr> &varMap) {
}
} else {
append("MOVL", rj, ri);
rj = 0;
regMap[x] = 0;
}
}
// load from memory
......
......@@ -3,6 +3,7 @@
#include "../Compiler.h"
void BasicBlock::finishQuads() {
assert(afterInit.empty());
if (!afterInit.empty()) {
while (!quads.empty() && quads.back()->isFinal()) {
auto final = quads.back();
......@@ -17,7 +18,6 @@ void BasicBlock::finishQuads() {
afterInit.clear();
}
auto self = this->shared_from_this();
for (const auto& q : quads) {
q->useVariables();
}
......
......@@ -52,9 +52,11 @@ public:
void addPhi(const BasicBlockPtr& blk, const VariablePtr& local, VariablePtr 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());
auto &phiMap = findPhi(blk);
phiMap[local] = std::move(remote);
phiMap[local] = remote;
}
void finishQuads();
......@@ -63,7 +65,7 @@ public:
set<VariablePtr> in, out, def, use;
BasicBlock *b {};
void addUse(const VariablePtr& v) {
if (!def.count(v)) use.emplace(v);
use.emplace(v);
}
void addDef(const VariablePtr &v) {
......@@ -75,7 +77,10 @@ public:
set<VariablePtr> ret;
for (const auto& var : b->findPhi(q)) {
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;
}
......
......@@ -282,6 +282,11 @@ public:
if (access.index) ret.emplace_back(access.index);
return ret;
}
vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions();
if (loc) ret.emplace_back(loc);
return ret;
};
void generateAsm(Compiler &c) override;
};
......
......@@ -640,10 +640,14 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
if (!change.second.first) continue;
auto info = change.first;
info->loc = nullptr;
alloc(info);
auto replaced = alloc(info);
if (info == arr->info)
arr = replaced;
}
VarInfoPtr iter = make_shared<VarInfo>("_it", make_shared<Int>());
assert(iter);
assert(!iter->loc);
auto iter1 = alloc(iter);
// save hooks for later
......@@ -655,6 +659,7 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
auto iterInfo = expr->pident_->getVar();
assert(iterInfo);
assert(!iterInfo->loc);
auto iterVar = alloc(iterInfo);
addQuad<QAccess>(iterVar, arr, iter1, 4, 4);
......@@ -692,10 +697,11 @@ void QuadrupleGenerator::visitForEach(ForEach *expr) {
}
condFirstBlock->addPhi(beforeBlock, iter1, alloc(0));
assert(iter1 != iter2);
condFirstBlock->addPhi(loopLastBlock, iter1, iter2);
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);
auto condLastBlock = flushBasicBlock(true); // jump -> loop
......
......@@ -30,7 +30,7 @@ void RegisterAllocator::analyseLive() {
auto &f = b->flow;
pIn.swap(f.in);
pOut.swap(f.out);
f.in = f.use + (pOut - f.def);
f.in = (f.use + pOut) - f.def;
for (const auto& succ : b->out) {
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