Commit 5ee30f7d authored by zygzagZ's avatar zygzagZ

WIP live variables, flow analysis and register allocation

parent 093e7cbe
CC=g++ CC=g++
CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter
OBJS=Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o QuadrupleGenerator.o OBJS=Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o QuadrupleGenerator.o RegisterAllocator.o
.PHONY : clean distclean .PHONY : clean distclean
...@@ -53,6 +53,9 @@ BasicBlock.o : src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/codeGen/Basi ...@@ -53,6 +53,9 @@ BasicBlock.o : src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/codeGen/Basi
QuadrupleGenerator.o : src/codeGen/QuadrupleGenerator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/Compiler.h src/codeGen/QuadrupleGenerator.h QuadrupleGenerator.o : src/codeGen/QuadrupleGenerator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/Compiler.h src/codeGen/QuadrupleGenerator.h
${CC} ${CCFLAGS} -c src/codeGen/QuadrupleGenerator.cpp ${CC} ${CCFLAGS} -c src/codeGen/QuadrupleGenerator.cpp
RegisterAllocator.o : src/codeGen/RegisterAllocator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/codeGen/RegisterAllocator.h
${CC} ${CCFLAGS} -c src/codeGen/RegisterAllocator.cpp
Latte.o : src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h src/codeGen/QuadrupleGenerator.h Latte.o : src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h src/codeGen/QuadrupleGenerator.h
${CC} ${CCFLAGS} -c src/Latte.cpp ${CC} ${CCFLAGS} -c src/Latte.cpp
......
...@@ -2914,7 +2914,7 @@ bool ClassT::isEqual(Type const *other, bool sub) const { ...@@ -2914,7 +2914,7 @@ bool ClassT::isEqual(Type const *other, bool sub) const {
if (v1 == v2) return true; if (v1 == v2) return true;
if (!sub) return false; if (!sub) return false;
auto klass = static_pointer_cast<ClassInfo>(v2); auto klass = static_pointer_cast<ClassInfo>(v2);
if (auto parent = klass->getParent()) { if (auto parent = klass->getClassParent()) {
return isEqual(&*parent->type, sub); return isEqual(&*parent->type, sub);
} }
} }
......
...@@ -37,7 +37,7 @@ size_t ClassInfo::calculateSize() { ...@@ -37,7 +37,7 @@ size_t ClassInfo::calculateSize() {
if (size) return size; if (size) return size;
size = 4; // pointer to virtual methods table size = 4; // pointer to virtual methods table
if (auto p = getParent()) { // parent already has virt pointer included if (auto p = getClassParent()) { // parent already has virt pointer included
p->calculateSize(); p->calculateSize();
size = p->size; size = p->size;
functionCount = p->functionCount; functionCount = p->functionCount;
......
...@@ -72,7 +72,7 @@ public: ...@@ -72,7 +72,7 @@ public:
ClassInfo(PIdent *ident, BindingPtr parent = nullptr); ClassInfo(PIdent *ident, BindingPtr parent = nullptr);
virtual string kind() const { return "class"; } virtual string kind() const { return "class"; }
ClassInfoPtr getParent() { return dynamic_pointer_cast<ClassInfo>(parent.lock()); }; ClassInfoPtr getClassParent() { return dynamic_pointer_cast<ClassInfo>(parent.lock()); };
size_t calculateSize(); size_t calculateSize();
size_t size, functionCount; size_t size, functionCount;
}; };
......
#ifndef INFOLIST_HEADER #ifndef INFOLIST_HEADER
#define INFOLIST_HEADER #define INFOLIST_HEADER
#include "Info.h"
#include "ParseError.h" #include "ParseError.h"
#include "TypeDefs.h" #include "TypeDefs.h"
#include <iostream> #include <iostream>
......
//
// Created by zygzagz on 03.01.2021.
//
#include "BasicBlock.h" #include "BasicBlock.h"
#include "Quadruple.h" #include "Quadruple.h"
...@@ -17,4 +13,8 @@ void BasicBlock::finishQuads() { ...@@ -17,4 +13,8 @@ void BasicBlock::finishQuads() {
} }
afterInit.clear(); afterInit.clear();
for (auto q : quads) {
q->useVariables();
}
} }
//
// Created by zygzagz on 03.01.2021.
//
#ifndef ZAD2_BASICBLOCK_H #ifndef ZAD2_BASICBLOCK_H
#define ZAD2_BASICBLOCK_H #define ZAD2_BASICBLOCK_H
#include "../TypeDefs.h" #include "../TypeDefs.h"
#include <utility>
#include <vector> #include <vector>
#include <set> #include <map>
#include <cassert>
#include "Variable.h"
using namespace std; using namespace std;
class BasicBlock : public std::enable_shared_from_this<BasicBlock> { class BasicBlock : public std::enable_shared_from_this<BasicBlock> {
public: public:
BasicBlock() = default;; BasicBlock() = default;
vector<QuadruplePtr> quads; vector<QuadruplePtr> quads;
vector<QuadruplePtr> afterInit; vector<QuadruplePtr> afterInit;
vector<BasicBlockPtr> in, out; vector<BasicBlockPtr> in, out;
vector<map<VariablePtr, VariablePtr>> phi;
void append(const BasicBlockPtr& after) { void append(const BasicBlockPtr& after) {
out.push_back(after); out.push_back(after);
after->in.push_back(shared_from_this()); after->in.push_back(shared_from_this());
after->phi.emplace_back();
} }
void addJumpInitQuad(const QuadruplePtr& q) { void addJumpInitQuad(const QuadruplePtr& q) {
afterInit.push_back(q); afterInit.push_back(q);
} }
void addPhi(const BasicBlockPtr& blk, const VariablePtr& local, VariablePtr remote) {
assert(blk && local && remote);
assert(local->info && !local->info->isInstanceVariable());
auto it = find(in.begin(), in.end(), blk);
if (it == in.end()) throw runtime_error("blk not found in incoming blocks");
auto mit = phi.begin() + (it - in.begin());
(*mit)[local] = std::move(remote);
}
void finishQuads(); void finishQuads();
}; };
......
...@@ -11,7 +11,7 @@ static const std::string opNames[] = { "_U", "-", "!", "", "_UE", ...@@ -11,7 +11,7 @@ static const std::string opNames[] = { "_U", "-", "!", "", "_UE",
"_B", "+", "-", "*", "/", "%", "&", "|", "^", "_BE", "_B", "+", "-", "*", "/", "%", "&", "|", "^", "_BE",
"_C", "<", "<=", "==", "!=", ">=", ">", "_CE"}; "_C", "<", "<=", "==", "!=", ">=", ">", "_CE"};
class Quadruple { class Quadruple : public enable_shared_from_this<Quadruple> {
public: public:
class Op { class Op {
public: public:
...@@ -39,10 +39,13 @@ public: ...@@ -39,10 +39,13 @@ public:
}; };
int lineno; int lineno;
int index;
virtual ~Quadruple() {}; virtual ~Quadruple() = default;
virtual std::string toString() const { return to_string(lineno) + "\t"; }; virtual std::string toString() const { return to_string(lineno) + "\t"; };
virtual bool isFinal() const { return false; } virtual bool isFinal() const { return false; }
virtual void useVariables() {};
}; };
class QWriteVar : public Quadruple { class QWriteVar : public Quadruple {
...@@ -51,13 +54,16 @@ public: ...@@ -51,13 +54,16 @@ public:
explicit QWriteVar(VariablePtr loc) : Quadruple(), loc(std::move(loc)) {}; explicit QWriteVar(VariablePtr loc) : Quadruple(), loc(std::move(loc)) {};
std::string toString() const override { return Quadruple::toString() + "\t" + (loc ? (loc->name + " := ") : ""); } std::string toString() const override { return Quadruple::toString() + "\t" + (loc ? (loc->name + " := ") : ""); }
void useVariables() override {
if (loc) loc->writes.emplace_back(shared_from_this());
}
}; };
class QLabel : public Quadruple { class QLabel : public Quadruple {
public: public:
string label; string label;
std::string toString() const override { return Quadruple::toString() + "\"" + label + "\":"; } std::string toString() const override { return Quadruple::toString() + "\"" + label + "\":"; }
QLabel(std::string comment) : label(comment) {} explicit QLabel(std::string comment) : label(std::move(comment)) {}
}; };
class QAssign : public QWriteVar { class QAssign : public QWriteVar {
...@@ -75,6 +81,11 @@ public: ...@@ -75,6 +81,11 @@ public:
else else
return QWriteVar::toString() + args[0]->name + " " + Op::name(op) + " " + args[1]->name; return QWriteVar::toString() + args[0]->name + " " + Op::name(op) + " " + args[1]->name;
} }
void useVariables() override {
QWriteVar::useVariables();
auto self = shared_from_this();
for (const auto& a : args) if (a) a->uses.emplace_back(self);
}
}; };
class QJump : public Quadruple { class QJump : public Quadruple {
...@@ -107,7 +118,12 @@ public: ...@@ -107,7 +118,12 @@ public:
return Quadruple::toString() + "jump \"" + target->label + "\" if " + left->name + " " + Op::name(op) + " " + right->name; return Quadruple::toString() + "jump \"" + target->label + "\" if " + left->name + " " + Op::name(op) + " " + right->name;
} }
virtual bool isFinal() const { return true; } bool isFinal() const override { return true; }
void useVariables() override {
if (left) left->uses.emplace_back(shared_from_this());
if (right) right->uses.emplace_back(shared_from_this());
}
}; };
class QParam : public Quadruple { class QParam : public Quadruple {
...@@ -118,12 +134,18 @@ public: ...@@ -118,12 +134,18 @@ public:
QParam(VariablePtr param, int num) : param(std::move(param)), num(num) {}; QParam(VariablePtr param, int num) : param(std::move(param)), num(num) {};
std::string toString() const override { std::string toString() const override {
if (num == 0) { if (num < 0) {
return Quadruple::toString() + "\t" + param->name + " := param #" + to_string(-num);
} else if (num == 0) {
return Quadruple::toString() + "\tparam self " + param->name; return Quadruple::toString() + "\tparam self " + param->name;
} else { } else {
return Quadruple::toString() + "\tparam #" + to_string(num) + " <- " + param->name; return Quadruple::toString() + "\tparam #" + to_string(num) + " <- " + param->name;
} }
} }
void useVariables() override {
if (param) param->uses.emplace_back(shared_from_this());
}
}; };
class QCall : public QWriteVar { class QCall : public QWriteVar {
...@@ -141,6 +163,11 @@ public: ...@@ -141,6 +163,11 @@ public:
return QWriteVar::toString() + "call " + fn->name + " with " + to_string(params) + " params"; return QWriteVar::toString() + "call " + fn->name + " with " + to_string(params) + " params";
} }
} }
void useVariables() override {
QWriteVar::useVariables();
if (self) self->uses.emplace_back(shared_from_this());
}
}; };
class QReturn : public Quadruple { class QReturn : public Quadruple {
...@@ -156,7 +183,11 @@ public: ...@@ -156,7 +183,11 @@ public:
} }
} }
virtual bool isFinal() const { return true; } bool isFinal() const override { return true; }
void useVariables() override {
if (ret) ret->uses.emplace_back(shared_from_this());
}
}; };
class QAccess : public QWriteVar { class QAccess : public QWriteVar {
...@@ -167,13 +198,17 @@ public: ...@@ -167,13 +198,17 @@ public:
// leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8 // leal 8(,%eax,4), %eax # Arithmetic: multiply eax by 4 and add 8
// leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx // leal (%edx,%eax,2), %eax # Arithmetic: multiply eax by 2 and add edx
VariableLocation access; VariableLocation access;
bool lea = false;
std::string toString() const override { std::string toString() const override {
auto ret = QWriteVar::toString(); auto ret = QWriteVar::toString();
if (lea) ret += "&";
return ret + access.toString(); return ret + access.toString();
} }
void useVariables() override {
QWriteVar::useVariables();
if (access.base) access.base->uses.emplace_back(shared_from_this());
if (access.index) access.index->uses.emplace_back(shared_from_this());
}
}; };
class QWrite : public Quadruple { class QWrite : public Quadruple {
...@@ -185,6 +220,12 @@ public: ...@@ -185,6 +220,12 @@ public:
VariablePtr val; VariablePtr val;
std::string toString() const override { return Quadruple::toString() + "\t" + loc.toString() + " := " + val->name; } std::string toString() const override { return Quadruple::toString() + "\t" + loc.toString() + " := " + val->name; }
void useVariables() override {
if (loc.base) loc.base->uses.emplace_back(shared_from_this());
if (loc.index) loc.index->uses.emplace_back(shared_from_this());
if (val) val->uses.emplace_back(shared_from_this());
}
}; };
class QAlloc : public QWriteVar { class QAlloc : public QWriteVar {
...@@ -201,6 +242,11 @@ public: ...@@ -201,6 +242,11 @@ public:
if (!virtSymbol.empty()) { ret += " " + virtSymbol; } if (!virtSymbol.empty()) { ret += " " + virtSymbol; }
return ret; return ret;
} }
void useVariables() override {
QWriteVar::useVariables();
if (count) count->uses.emplace_back(shared_from_this());
}
}; };
......
...@@ -33,8 +33,10 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) { ...@@ -33,8 +33,10 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) {
} }
int label = 1; int label = 1;
int index = 1;
for (const auto& b : blocks) { for (const auto& b : blocks) {
for (const auto& q : b->quads) { for (const auto& q : b->quads) {
q->index = index++;
if (auto l = dynamic_pointer_cast<QLabel>(q)) { if (auto l = dynamic_pointer_cast<QLabel>(q)) {
if (!l->label.empty()) if (!l->label.empty())
l->label = to_string(label++) + "_" + l->label; l->label = to_string(label++) + "_" + l->label;
...@@ -47,6 +49,11 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) { ...@@ -47,6 +49,11 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) {
for (const auto& v : vars) { for (const auto& v : vars) {
if (v->info) if (v->info)
v->info->loc = nullptr; v->info->loc = nullptr;
cout << "\nvar " << v->name << endl;
for (const auto& q : v->writes)
cout << q->toString() << endl;
for (const auto& q : v->uses)
cout << q->toString() << endl;
} }
vars.clear(); vars.clear();
...@@ -75,10 +82,8 @@ VariableLayout QuadrupleGenerator::captureEnv() { ...@@ -75,10 +82,8 @@ VariableLayout QuadrupleGenerator::captureEnv() {
while (b) { while (b) {
for (const auto& info : b->variables) { for (const auto& info : b->variables) {
if (info->isInstanceVariable()) continue; if (info->isInstanceVariable()) continue;
if (info->loc) {
ret.add(info); ret.add(info);
} }
}
b = b->getParent(); b = b->getParent();
} }
return ret; return ret;
...@@ -224,7 +229,7 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) { ...@@ -224,7 +229,7 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
lastVar = l; lastVar = l;
} else { } else {
lastVar = alloc(var); lastVar = alloc(var);
auto quad = make_shared<QAccess>(lastVar, l, alloc(0), 0, offset); auto quad = make_shared<QAccess>(lastVar, l, nullptr, 0, offset);
addQuad(quad); addQuad(quad);
} }
} }
...@@ -400,29 +405,17 @@ void QuadrupleGenerator::compileCond(Expr *expr_, Stmt *stmt_1, Stmt *stmt_2) { ...@@ -400,29 +405,17 @@ void QuadrupleGenerator::compileCond(Expr *expr_, Stmt *stmt_1, Stmt *stmt_2) {
merge2Envs(&env1, stmt1Block, &env2, stmt2Block); merge2Envs(&env1, stmt1Block, &env2, stmt2Block);
} }
void QuadrupleGenerator::merge2Envs(VariableLayout *env1, BasicBlockPtr b1, VariableLayout *env2, BasicBlockPtr b2) { void QuadrupleGenerator::merge2Envs(VariableLayout *env1, const BasicBlockPtr& b1, VariableLayout *env2, const BasicBlockPtr& b2) {
for (int i = 0; i < 2; i++) { assert(env1->changes.size() == env2->changes.size());
for (const auto& p1 : env1->changes) { for (auto it = env1->changes.begin(), itt = env2->changes.begin(); it != env1->changes.end(); it++, itt++) {
if (p1.second.first == p1.second.second) continue; assert(it->first == itt->first);
auto info = p1.first; assert(it->second.first == itt->second.first);
auto it = env2->changes.find(info); if (it->second.second == itt->second.second) continue;
if (it != env2->changes.end()) { auto info = it->first;
auto p2 = *it;
// variables have been already merged
if (p1.second.first == p2.second.second) continue;
info->loc = nullptr; info->loc = nullptr;
auto merged = alloc(info); auto merged = alloc(info);
// assign both versions to merged variable location block->addPhi(b1, merged, it->second.second);
b1->addJumpInitQuad(make_shared<QAssign>(merged, Op::Copy, p1.second.second)); block->addPhi(b2, merged, itt->second.second);
b2->addJumpInitQuad(make_shared<QAssign>(merged, Op::Copy, p2.second.second));
} else {
// copy changes to another block that did not touch var
b2->addJumpInitQuad(make_shared<QAssign>(p1.second.second, Op::Copy, p1.second.first));
}
}
swap(env1, env2);
swap(b1, b2);
} }
} }
...@@ -446,6 +439,7 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -446,6 +439,7 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// save hooks for later // save hooks for later
env1.capture(); env1.capture();
// env2 starts with hooked variables // env2 starts with hooked variables
auto env2 = captureEnv(); auto env2 = captureEnv();
...@@ -459,6 +453,9 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -459,6 +453,9 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// restore env1 pre-hook variables // restore env1 pre-hook variables
env1.revert(); env1.revert();
beforeBlock->append(block);
block->append(loopBlock);
for (const auto& p : env2.changes) { for (const auto& p : env2.changes) {
auto info = p.first; auto info = p.first;
auto x1 = p.second.first; auto x1 = p.second.first;
...@@ -466,9 +463,9 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -466,9 +463,9 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// save hooks if used // save hooks if used
info->loc = x1; info->loc = x1;
// transition from pre-hook to hooked var [before -> cond] // transition from pre-hook to hooked var [before -> cond]
beforeBlock->addJumpInitQuad(make_shared<QAssign>(x1, Op::Copy, env1.changes[info].first)); block->addPhi(beforeBlock, x1, env1.changes[info].first);
// transition from loop var to hooked var [loop -> cond] // transition from loop var to hooked var [loop -> cond]
loopBlock->addJumpInitQuad(make_shared<QAssign>(x1, Op::Copy, x2)); loopBlock->addPhi(block, x1, x2);
} }
// expr uses pre-hook variables iff unused in loop // expr uses pre-hook variables iff unused in loop
...@@ -479,8 +476,6 @@ void QuadrupleGenerator::visitWhile(While *expr) { ...@@ -479,8 +476,6 @@ void QuadrupleGenerator::visitWhile(While *expr) {
// next block is ready to use updated variables // next block is ready to use updated variables
beforeBlock->append(condBlock);
condBlock->append(loopBlock);
condBlock->append(block); condBlock->append(block);
} }
......
...@@ -170,7 +170,7 @@ private: ...@@ -170,7 +170,7 @@ private:
void compileCond(Expr *cond, Stmt *stmt1, Stmt *stmt2); void compileCond(Expr *cond, Stmt *stmt1, Stmt *stmt2);
void merge2Envs(VariableLayout *env1, BasicBlockPtr b1, VariableLayout *env2, BasicBlockPtr b2); void merge2Envs(VariableLayout *env1, const BasicBlockPtr& b1, VariableLayout *env2, const BasicBlockPtr& b2);
void visitWhile(While *expr) override; void visitWhile(While *expr) override;
......
#include "RegisterAllocator.h"
void RegisterAllocator::analyseLive() {
}
\ No newline at end of file
#ifndef ZAD2_REGISTERALLOCATOR_H
#define ZAD2_REGISTERALLOCATOR_H
#include "Quadruple.h"
class Register : public std::enable_shared_from_this<Register> {
bool available;
set<VariablePtr> contains;
std::string name;
};
class RegisterAllocator {
public:
RegisterAllocator(vector<BasicBlockPtr> v) : blocks(v) {}
void processQJump(shared_ptr<QJump> q) {};
void processQJumpCond(shared_ptr<QJumpCond> q) {};
void processQLabel(shared_ptr<QLabel> q) {};
void processQParam(shared_ptr<QParam> q) {};
void processQReturn(shared_ptr<QReturn> q) {};
void processQWrite(shared_ptr<QWrite> q) {};
void processQAccess(shared_ptr<QAccess> q) {};
void processQAlloc(shared_ptr<QAlloc> q) {};
void processQAssign(shared_ptr<QAssign> q) {};
void processQCall(shared_ptr<QCall> q) {};
void analyseLive();
private:
vector<BasicBlockPtr> blocks;
};
#endif //ZAD2_REGISTERALLOCATOR_H
//
// Created by zygzagz on 02.01.2021.
//
#include "Variable.h" #include "Variable.h"
//
// Created by zygzagz on 02.01.2021.
//
#ifndef ZAD2_VARIABLE_H #ifndef ZAD2_VARIABLE_H
#define ZAD2_VARIABLE_H #define ZAD2_VARIABLE_H
...@@ -14,19 +10,33 @@ ...@@ -14,19 +10,33 @@
class Variable : std::enable_shared_from_this<Variable> { class Variable : std::enable_shared_from_this<Variable> {
public: public:
Variable() = default; Variable() = default;
explicit Variable(VarInfoPtr info) : info(std::move(info)), constExpr(false), val(0) {}; explicit Variable(VarInfoPtr info) : info(std::move(info)) {};
explicit Variable(int constVal) : type(new Int), constExpr(true), val(constVal) {}; explicit Variable(int constVal) : type(new Int), constExpr(true), val(constVal) {};
explicit Variable(std::string symbolName) {}; explicit Variable(std::string symbolName) : name(std::move(symbolName)) {};
VarInfoPtr info; VarInfoPtr info;
TypePtr type; TypePtr type;
bool constExpr; bool constExpr{false};
int val; int val{0};
std::string name; std::string name;
// chcemy znać lokalizację w pamięci gdzie zapisać z powrotem i gdzie leży ogólnie
// lok. może nie być, jeśli to tymczasowa vector<QuadruplePtr> uses;
// registers vector<QuadruplePtr> writes;
// is mem?
// where in mem - id or offset void clear(const QuadruplePtr& q) {
uses.erase(std::remove(uses.begin(), uses.end(), q), uses.end());
writes.erase(std::remove(writes.begin(), writes.end(), q), writes.end());
//
// for (auto it = uses.begin(); it != uses.end();) {
// if (*it == q)
// it = uses.erase(it);
// else it++;
// }
// for (auto it = writes.begin(); it != writes.end();) {
// if (*it == q)
// it = writes.erase(it);
// else it++;
// }
}
}; };
class VariableLocation { class VariableLocation {
...@@ -37,12 +47,12 @@ public: ...@@ -37,12 +47,12 @@ public:
{} {}
VariablePtr base; VariablePtr base;
VariablePtr index; VariablePtr index;
int multiplier; int multiplier{};
int offset; int offset{};
string toString() const { string toString() const {
std::string ret = "[" + base->name; std::string ret = "[" + base->name;
if (multiplier || !(index->constExpr || !index->val)) ret += " + " + to_string(multiplier) + "*" + index->name; if (index) if (multiplier || !(index->constExpr || !index->val)) ret += " + " + to_string(multiplier) + "*" + index->name;
if (offset) ret += " + " + to_string(offset); if (offset) ret += " + " + to_string(offset);
return ret + "]"; return ret + "]";
} }
...@@ -53,7 +63,7 @@ class VariableLayout { ...@@ -53,7 +63,7 @@ class VariableLayout {
public: public:
map<VarInfoPtr, pair<VariablePtr, VariablePtr>> changes; map<VarInfoPtr, pair<VariablePtr, VariablePtr>> changes;
void add(const VarInfoPtr& info) { void add(const VarInfoPtr& info) {
if (!changes.count(info) && info->loc) { if (!changes.count(info)) {
changes[info] = {info->loc, nullptr}; changes[info] = {info->loc, nullptr};
} }
} }
...@@ -62,12 +72,6 @@ public: ...@@ -62,12 +72,6 @@ public:
for (auto &p : changes) { for (auto &p : changes) {
p.second.second = p.first->loc; p.second.second = p.first->loc;
} }
for (auto it = changes.begin(); it != changes.end(); ) {
auto pit = it;
it++;
if (pit->second.first == pit->second.second)
changes.erase(pit);
}
} }
void revert() { void revert() {
......
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