Commit 459ffddf authored by zygzagZ's avatar zygzagZ

Dopychanie kolanem

parent e694f348
...@@ -3,14 +3,14 @@ CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter ...@@ -3,14 +3,14 @@ CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter
.PHONY : clean distclean .PHONY : clean distclean
all : latc all : latc_x86
clean : clean :
rm -f *.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar rm -f *.o latc_x86 Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
latc : 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 Latte.o latc_x86 : 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 Latte.o
@echo "Linking latc..." @echo "Linking latc_x86..."
${CC} ${CCFLAGS} $^ -lstdc++fs -o latc ${CC} ${CCFLAGS} $^ -lstdc++fs -o latc_x86
Absyn.o : src/Absyn.cpp src/Absyn.h Absyn.o : src/Absyn.cpp src/Absyn.h
${CC} ${CCFLAGS} -c src/Absyn.cpp ${CC} ${CCFLAGS} -c src/Absyn.cpp
...@@ -30,7 +30,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h ...@@ -30,7 +30,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h
TypeCheck.o : src/TypeCheck.cpp src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h TypeCheck.o : src/TypeCheck.cpp src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h
${CC} ${CCFLAGS} -c src/TypeCheck.cpp ${CC} ${CCFLAGS} -c src/TypeCheck.cpp
Compiler.o : src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h src/codeGen/QuadrupleGenerator.h src/codeGen/RegisterAllocator.h src/codeGen/Graph.h Compiler.o : src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h src/codeGen/QuadrupleGenerator.h src/codeGen/RegisterAllocator.h src/codeGen/Graph.h src/codeGen/BasicBlock.h
${CC} ${CCFLAGS} -c src/Compiler.cpp ${CC} ${CCFLAGS} -c src/Compiler.cpp
Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
......
This diff is collapsed.
...@@ -38,6 +38,13 @@ public: ...@@ -38,6 +38,13 @@ public:
void generateQJump(QJump &q); void generateQJump(QJump &q);
void generateQAssign(QAssign &q); void generateQAssign(QAssign &q);
void generateQLabel(QLabel &q); void generateQLabel(QLabel &q);
static std::string mangleFunctionName(const FunctionInfoPtr& f) {
if (auto c = f->klass.lock()) {
return c->name + "::" + f->name;
}
return f->name;
}
private: private:
std::filesystem::path file; std::filesystem::path file;
std::stringstream buf; std::stringstream buf;
...@@ -52,7 +59,14 @@ private: ...@@ -52,7 +59,14 @@ private:
class Register { class Register {
public: public:
Register(string n) : name(std::move(n)) {}; Register(string n) : name(n) {
for (auto reg : Compiler::regs) {
if (name == reg) {
return;
}
}
throw runtime_error("Invalid register name");
};
Register(int n) { name = Compiler::regs[n]; } Register(int n) { name = Compiler::regs[n]; }
Register(const VariablePtr &v) { name = Compiler::regs[v->registerColor + 1]; } Register(const VariablePtr &v) { name = Compiler::regs[v->registerColor + 1]; }
string name; string name;
...@@ -61,16 +75,12 @@ private: ...@@ -61,16 +75,12 @@ private:
bool operator!=(const Register &other) const { return name != other.name; } bool operator!=(const Register &other) const { return name != other.name; }
}; };
static std::string mangleFunctionName(const FunctionInfoPtr& f) {
if (auto c = f->klass.lock()) {
return c->name + "::" + f->name;
}
return f->name;
}
string getRef(VariablePtr &v); string getRef(VariablePtr &v);
static const char* const regs[6]; static const char* const regs[6];
static const int callerSavedRegisters[2];
static const int calleeSavedRegisters[3];
static string getOpName(Quadruple::Op op) { static string getOpName(Quadruple::Op op) {
switch(op.op) { switch(op.op) {
...@@ -79,10 +89,12 @@ private: ...@@ -79,10 +89,12 @@ private:
case Op::Mul: return "IMULL"; case Op::Mul: return "IMULL";
case Op::Div: case Op::Div:
case Op::Mod: throw runtime_error("Impossible to handle division with default"); case Op::Mod: throw runtime_error("Impossible to handle division with default");
case Op::Not: return "SETZ";
case Op::Copy: return "SETNZ";
case Op::LT: return "SETL"; case Op::LT: return "SETL";
case Op::LE: return "SETLE"; case Op::LE: return "SETLE";
case Op::EQ: return "SETE"; case Op::EQ: return "SETZ";
case Op::NEQ: return "SETNE"; case Op::NEQ: return "SETNZ";
case Op::GE: return "SETGE"; case Op::GE: return "SETGE";
case Op::GT: return "SETG"; case Op::GT: return "SETG";
default: return "Op" + to_string(op.op) + "?"; default: return "Op" + to_string(op.op) + "?";
...@@ -121,7 +133,57 @@ private: ...@@ -121,7 +133,57 @@ private:
} }
void append(string cmd, string op1 = "", string op2 = "", string op3 = "") { void append(string cmd, string op1 = "", string op2 = "", string op3 = "") {
buf << "\t" << cmd << " " << op1 << " " << op2 << " " << op3 << endl; append({cmd, op1, op2, op3});
}
void append(vector<string> ops) {
static const char* const delimiters = "\t ,,,,";
assert(ops.size() < 6);
while (ops.size() && ops.back().empty())
ops.pop_back();
buf << "\t";
for (uint i = 0; i < ops.size(); i++) {
buf << delimiters[i] << ops[i];
}
buf << endl;
}
string getBlockLabelText(const QuadruplePtr &q) {
return getBlockLabelText(q->block);
}
string getBlockLabelText(BasicBlockPtr &b) {
auto n = b->getName();
if (n.empty()) throw runtime_error("Attempt to get label text of unlabeled block");
return "\"" + n + "\"";
}
shared_ptr<QLabel> exitLabel;
void generateStandardReturn() {
append("JMP", "\"" + exitLabel->label + "\"");
}
vector<Register> registersToSave(QCall &q) {
const int noRegs = sizeof(callerSavedRegisters) / sizeof(*callerSavedRegisters);
bool saved[noRegs];
int notSaved = noRegs;
for (auto &i : saved) i = false;
for (auto &live : q.aliveAfter) {
for (int i = 0; i < noRegs; i++) {
int r = callerSavedRegisters[i];
if (!saved[i] && Register(live) == Register(r)) {
saved[i] = true;
--notSaved;
}
}
if (notSaved == 0) break;
}
vector<Register> ret;
for (int i = 0; i < noRegs; i++) {
if (saved[i]) ret.emplace_back(callerSavedRegisters[i]);
}
return ret;
} }
}; };
......
...@@ -50,7 +50,7 @@ public: ...@@ -50,7 +50,7 @@ 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);
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] = std::move(remote);
} }
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
using namespace std; using namespace std;
class Compiler; class Compiler;
static const std::string opNames[] = { "_U", "-", "!", "", "_UE", static const std::string opNames[] = { "_U", "!", "", "-", "_UE",
"_B", "+", "-", "*", "/", "%", "&", "|", "^", "_BE", "_B", "+", "-", "*", "/", "%", "&", "|", "^", "_BE",
"_C", "<", "<=", "==", "!=", ">=", ">", "_CE"}; "_C", "<", ">=", "<=", ">", "==", "!=", "_CE"};
class Quadruple : public enable_shared_from_this<Quadruple> { class Quadruple : public enable_shared_from_this<Quadruple> {
public: public:
...@@ -19,22 +19,35 @@ public: ...@@ -19,22 +19,35 @@ public:
public: public:
enum OpType { enum OpType {
UNARY, UNARY,
Neg, Not, Copy, UNARY_END, Not, Copy, Neg, UNARY_END,
BINARY, BINARY,
Plus, Minus, Mul, Div, Mod, And, Or, Xor, BINARY_END, Plus, Minus, Mul, Div, Mod, And, Or, Xor, BINARY_END,
CMP, CMP,
LT, LE, EQ, NEQ, GE, GT, CMP_END LT, GE, LE, GT, EQ, NEQ, CMP_END
}; };
OpType op; OpType op;
Op(OpType op = UNARY) : op(op) {}; Op(OpType op = UNARY) : op(op) {};
operator OpType() const { return op; }; operator OpType() const { return op; };
Op neg() const {
if (op <= Op::Copy)
return OpType(UNARY + 1 + ((int)(op - UNARY - 1)^1));
if (op > Op::CMP)
return OpType(CMP + 1 + ((int)(op - CMP - 1)^1));
throw runtime_error("Invalid argument to Op::neg()");
};
static OpType kind(OpType op) { static OpType kind(OpType op) {
if (op <= UNARY_END) return UNARY; if (op <= UNARY_END) return UNARY;
if (op <= BINARY_END) return BINARY; if (op <= BINARY_END) return BINARY;
return CMP; return CMP;
}; };
OpType kind() const {
return Op::kind(*this);
};
static const std::string& name(OpType op) { static const std::string& name(OpType op) {
return opNames[op]; return opNames[op];
} }
...@@ -71,7 +84,7 @@ public: ...@@ -71,7 +84,7 @@ public:
std::string toString() const override { return Quadruple::toString() + "\t" + (loc ? (loc->name + " := ") : ""); } std::string toString() const override { return Quadruple::toString() + "\t" + (loc ? (loc->name + " := ") : ""); }
vector<VariablePtr> definitions() const override { vector<VariablePtr> definitions() const override {
auto ret = Quadruple::definitions(); auto ret = Quadruple::definitions();
if (loc) ret.emplace_back(loc); if (loc && !loc->constExpr) ret.emplace_back(loc);
return ret; return ret;
}; };
}; };
...@@ -147,13 +160,16 @@ public: ...@@ -147,13 +160,16 @@ public:
} }
void generateAsm(Compiler &c) override; void generateAsm(Compiler &c) override;
}; };
class QCall;
class QParam : public Quadruple { class QParam : public Quadruple {
public: public:
VariablePtr param; VariablePtr param;
int num; int num;
QParam(VariablePtr param, int num) : param(std::move(param)), num(num) {}; shared_ptr<QCall> call;
QParam(VariablePtr param, int num, shared_ptr<QCall> call = nullptr) : param(std::move(param)), num(num), call(std::move(call)) {};
std::string toString() const override { std::string toString() const override {
if (num < 0) { if (num < 0) {
......
...@@ -46,10 +46,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f ...@@ -46,10 +46,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
for (const auto& q : b->quads) { for (const auto& q : b->quads) {
q->index = index++; q->index = index++;
if (auto l = dynamic_pointer_cast<QLabel>(q)) { if (auto l = dynamic_pointer_cast<QLabel>(q)) {
if (!l->label.empty()) auto old = l->label;
l->label = to_string(label++) + "_" + l->label; l->label = "." + to_string(label++) + "_" + Compiler::mangleFunctionName(f);
else if (!old.empty())
l->label = to_string(label++); l->label += "_" + old;
} }
} }
} }
...@@ -109,10 +109,12 @@ void QuadrupleGenerator::visitELitInt(ELitInt *p) { ...@@ -109,10 +109,12 @@ void QuadrupleGenerator::visitELitInt(ELitInt *p) {
void QuadrupleGenerator::visitELitTrue(ELitTrue *p) { void QuadrupleGenerator::visitELitTrue(ELitTrue *p) {
lastVar = alloc(1); lastVar = alloc(1);
if (labelTrue) addQuad<QJump>(labelTrue);
} }
void QuadrupleGenerator::visitELitFalse(ELitFalse *p) { void QuadrupleGenerator::visitELitFalse(ELitFalse *p) {
lastVar = alloc(0); lastVar = alloc(0);
if (labelFalse) addQuad<QJump>(labelFalse);
} }
void QuadrupleGenerator::visitEString(EString *p) { void QuadrupleGenerator::visitEString(EString *p) {
...@@ -128,12 +130,20 @@ void QuadrupleGenerator::visitNeg(Neg *p) { ...@@ -128,12 +130,20 @@ void QuadrupleGenerator::visitNeg(Neg *p) {
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
lastVar = alloc(); lastVar = alloc();
addQuad<QAssign>(lastVar, Op::Neg, var); addQuad<QAssign>(lastVar, Op::Neg, var);
if ((lastVar->constExpr = var->constExpr)) {
lastVar->val = -var->val;
}
} }
void QuadrupleGenerator::visitNot(Not *p) { void QuadrupleGenerator::visitNot(Not *p) {
swap(labelTrue, labelFalse);
auto var = evalExpr(p->expr_); auto var = evalExpr(p->expr_);
swap(labelTrue, labelFalse);
lastVar = alloc(); lastVar = alloc();
addQuad<QAssign>(lastVar, Op::Not, var); addQuad<QAssign>(lastVar, Op::Not, var);
if ((lastVar->constExpr = var->constExpr)) {
lastVar->val = !var->val;
}
} }
void QuadrupleGenerator::visitEMul(EMul *p) { void QuadrupleGenerator::visitEMul(EMul *p) {
...@@ -142,6 +152,16 @@ void QuadrupleGenerator::visitEMul(EMul *p) { ...@@ -142,6 +152,16 @@ void QuadrupleGenerator::visitEMul(EMul *p) {
lastVar = alloc(); lastVar = alloc();
p->mulop_->accept(this); p->mulop_->accept(this);
addQuad<QAssign>(lastVar, l, op, r); addQuad<QAssign>(lastVar, l, op, r);
if ((lastVar->constExpr = l->constExpr && r->constExpr)) {
if (op == Op::Mul)
lastVar->val = l->val * r->val;
else if (r->val == 0)
throw ParseError("Division by 0", p);
else if (op == Op::Div)
lastVar->val = l->val / r->val;
else if (op == Op::Mod)
lastVar->val = l->val % r->val;
}
} }
void QuadrupleGenerator::visitEAdd(EAdd *p) { void QuadrupleGenerator::visitEAdd(EAdd *p) {
...@@ -150,48 +170,120 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) { ...@@ -150,48 +170,120 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) {
lastVar = alloc(); lastVar = alloc();
p->addop_->accept(this); p->addop_->accept(this);
addQuad<QAssign>(lastVar, l, op, r); addQuad<QAssign>(lastVar, l, op, r);
if ((lastVar->constExpr = l->constExpr && r->constExpr)) {
if (op == Op::Minus)
lastVar->val = l->val - r->val;
else if (op == Op::Plus)
lastVar->val = l->val + r->val;
}
} }
void QuadrupleGenerator::visitERel(ERel *p) { void QuadrupleGenerator::visitERel(ERel *p) {
auto l = evalExpr(p->expr_1); auto l = evalJump(p->expr_1, nullptr, nullptr);
auto r = evalExpr(p->expr_2); auto r = evalJump(p->expr_2, nullptr, nullptr);
lastVar = alloc(); lastVar = alloc();
p->relop_->accept(this); p->relop_->accept(this);
if ((lastVar->constExpr = l->constExpr && r->constExpr)) {
if (op == Op::LT)
lastVar->val = l->val < r->val;
else if (op == Op::LE)
lastVar->val = l->val <= r->val;
else if (op == Op::EQ)
lastVar->val = l->val == r->val;
else if (op == Op::NEQ)
lastVar->val = l->val != r->val;
else if (op == Op::GE)
lastVar->val = l->val >= r->val;
else if (op == Op::GT)
lastVar->val = l->val > r->val;
addQuad<QAssign>(lastVar, l, op, r); addQuad<QAssign>(lastVar, l, op, r);
}
addLastVarCondJump(l, op, r);
} }
void QuadrupleGenerator::visitEAnd(EAnd *p) { void QuadrupleGenerator::visitEAnd(EAnd *p) {
auto l = evalExpr(p->expr_1); auto labelAfter = make_shared<QLabel>("and_else");
auto labelLeft = make_shared<QLabel>("use_left"); auto l = evalJump(p->expr_1, nullptr, labelFalse);
auto labelAfter = make_shared<QLabel>("end_and"); if (!l) return;
if (l->constExpr) {
lastVar = l->val ? evalJump(p->expr_2, labelTrue, labelFalse) : l;
// jest git skoczymy pozniej bo to constexpr
return;
} else {
auto leftValBlock = block;
auto llq = make_shared<QJumpCond>(labelFalse ? labelFalse : labelAfter, Op::Not, l);
addQuad(llq);
flushBasicBlock();
leftValBlock->append(block);
addQuad<QJumpCond>(labelLeft, Op::Not, l); auto r = evalJump(p->expr_2, labelTrue, labelFalse);
auto r = evalExpr(p->expr_2);
lastVar = alloc();
addQuad<QAssign>(lastVar, Op::Copy, r); if (!r || r->constExpr) {
addQuad<QJump>(labelAfter); assert(leftValBlock->quads.back() == llq);
addQuad(labelLeft); leftValBlock->quads.pop_back();
addQuad<QAssign>(lastVar, Op::Copy, alloc(0)); // could merge basic blocks now, but why bother
if (r) {
lastVar = r->val ? l : r;
}
} else {
auto rightValBlock = block;
flushBasicBlock();
addQuad(labelAfter); addQuad(labelAfter);
rightValBlock->append(block);
leftValBlock->append(block);
if (!labelTrue || !labelFalse) {
lastVar = alloc();
block->addPhi(rightValBlock, lastVar, r);
block->addPhi(leftValBlock, lastVar, l);
} else {
lastVar = nullptr;
}
}
}
} }
void QuadrupleGenerator::visitEOr(EOr *p) { void QuadrupleGenerator::visitEOr(EOr *p) {
auto l = evalExpr(p->expr_1); auto labelAfter = make_shared<QLabel>("or_else");
auto labelLeft = make_shared<QLabel>("use_left"); auto l = evalJump(p->expr_1, labelTrue, nullptr);
auto labelAfter = make_shared<QLabel>("end_or"); if (!l) return;
if (l->constExpr) {
addQuad<QJumpCond>(labelLeft, Op::Copy, l); lastVar = l->val ? l : evalJump(p->expr_2, labelTrue, labelFalse);
// jest git skoczymy pozniej bo to constexpr
return;
} else {
auto leftValBlock = block;
auto llq = make_shared<QJumpCond>(labelTrue ? labelTrue : labelAfter, Op::Copy, l);
addQuad(llq);
flushBasicBlock();
leftValBlock->append(block);
auto r = evalExpr(p->expr_2); auto r = evalExpr(p->expr_2);
lastVar = alloc(); if (!r) return;
addQuad<QAssign>(lastVar, Op::Copy, r); if (r->constExpr) {
addQuad<QJump>(labelAfter); assert(leftValBlock->quads.back() == llq);
addQuad(labelLeft); leftValBlock->quads.pop_back();
addQuad<QAssign>(lastVar, Op::Copy, alloc(1)); // could merge basic blocks now, but why bother
lastVar = r->val ? r : l;
} else {
auto rightValBlock = block;
flushBasicBlock();
addQuad(labelAfter); addQuad(labelAfter);
rightValBlock->append(block);
leftValBlock->append(block);
if (!labelTrue || !labelFalse) {
lastVar = alloc();
block->addPhi(rightValBlock, lastVar, r);
block->addPhi(leftValBlock, lastVar, l);
} else {
lastVar = nullptr;
}
}
}
} }
/// complex extensions /// complex extensions
...@@ -219,6 +311,10 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) { ...@@ -219,6 +311,10 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) {
} }
auto quad = make_shared<QAccess>(lastVar, lhs, index, 4, 0); auto quad = make_shared<QAccess>(lastVar, lhs, index, 4, 0);
addQuad(quad); addQuad(quad);
Bool b;
if (type->type_->isEqual(&b)) {
addLastVarCondJump(nullptr, Op::Copy, lastVar);
}
} }
void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) { void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
...@@ -240,6 +336,10 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) { ...@@ -240,6 +336,10 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
auto quad = make_shared<QAccess>(lastVar, l, nullptr, 0, offset); auto quad = make_shared<QAccess>(lastVar, l, nullptr, 0, offset);
addQuad(quad); addQuad(quad);
} }
Bool b;
if (var->type->isEqual(&b)) {
addLastVarCondJump(nullptr, Op::Copy, lastVar);
}
} }
void QuadrupleGenerator::visitEApp(EApp *p) { void QuadrupleGenerator::visitEApp(EApp *p) {
...@@ -270,18 +370,24 @@ void QuadrupleGenerator::visitEApp(EApp *p) { ...@@ -270,18 +370,24 @@ void QuadrupleGenerator::visitEApp(EApp *p) {
throw ParseError("Unimplemented EApp instantiation (neither EClsMmbr nor EVar", p); throw ParseError("Unimplemented EApp instantiation (neither EClsMmbr nor EVar", p);
} }
int i = 1; auto call = make_shared<QCall>(lastVar, info, p->listexpr_->size(), self);
int i = 0;
for (auto param : *p->listexpr_) { for (auto param : *p->listexpr_) {
auto var = evalExpr(param); auto var = evalExpr(param);
addQuad<QParam>(var, i++); addQuad<QParam>(var, ++i, call);
} }
if (self) { if (self) {
addQuad<QParam>(self, 0); addQuad<QParam>(self, 0, call);
} }
lastVar = alloc(); lastVar = alloc();
addQuad<QCall>(lastVar, info, i, self); addQuad(call);
Bool b;
if (info->type->isEqual(&b)) {
addLastVarCondJump(nullptr, Op::Copy, lastVar);
}
} }
void QuadrupleGenerator::visitENewArray(ENewArray *p) { void QuadrupleGenerator::visitENewArray(ENewArray *p) {
...@@ -387,17 +493,16 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) { ...@@ -387,17 +493,16 @@ 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>("if_else"); auto elseBranch = make_shared<QLabel>("if_else");
auto after = make_shared<QLabel>("end_else"); auto after = make_shared<QLabel>("end_else");
auto ifBranch = make_shared<QLabel>("if_true");
auto var = evalExpr(expr_); evalJump(expr_, ifBranch, elseBranch);
addQuad<QJumpCond>(elseBranch, Op::Not, var);
auto beforeBlock = flushBasicBlock(); // possible jump -> else auto beforeBlock = flushBasicBlock(); // possible jump -> else
auto envIf = captureEnv(), envElse = envIf; auto envIf = captureEnv(), envElse = envIf;
auto stmtIfFirstBlock = block; auto stmtIfFirstBlock = block;
addQuad<QLabel>("if_true"); addQuad(ifBranch);
stmt_1->accept(this); stmt_1->accept(this);
addQuad<QJump>(after); addQuad<QJump>(after);
auto stmtIfLastBlock = flushBasicBlock(); // jump -> after auto stmtIfLastBlock = flushBasicBlock(); // jump -> after
......
...@@ -30,6 +30,7 @@ private: ...@@ -30,6 +30,7 @@ private:
VariablePtr lastVar; VariablePtr lastVar;
int lineno; int lineno;
shared_ptr<Scope> scope; shared_ptr<Scope> scope;
shared_ptr<QLabel> labelTrue, labelFalse;
VariablePtr evalLVal(Visitable *expr) { VariablePtr evalLVal(Visitable *expr) {
auto info = evalExpr(expr)->info; auto info = evalExpr(expr)->info;
...@@ -55,6 +56,17 @@ private: ...@@ -55,6 +56,17 @@ private:
return ret; return ret;
} }
VariablePtr evalJump(Visitable *expr, shared_ptr<QLabel> tLabel, shared_ptr<QLabel> fLabel) {
if (!expr) throw runtime_error("No expr to eval");
lineno = expr->lineno;
swap(labelTrue, tLabel);
swap(labelFalse ,fLabel);
auto ret = evalExpr(expr);
swap(labelTrue, tLabel);
swap(labelFalse ,fLabel);
return ret;
}
VariablePtr alloc(const VarInfoPtr& info) { VariablePtr alloc(const VarInfoPtr& info) {
if (info->loc) { if (info->loc) {
return info->loc; return info->loc;
...@@ -84,6 +96,22 @@ private: ...@@ -84,6 +96,22 @@ private:
return quad; return quad;
} }
void addLastVarCondJump(const VariablePtr& l, Quadruple::Op op, const VariablePtr& r) {
if (labelTrue && labelFalse) {
addQuad<QJumpCond>(labelTrue, l, op, r);
addQuad<QAssign>(lastVar, l, op, r);
addQuad<QJump>(labelFalse);
return;
} else if (labelTrue) {
addQuad<QJumpCond>(labelTrue, l, op, r);
lastVar = alloc(0);
} else if (labelFalse) {
addQuad<QJumpCond>(labelFalse, l, op.neg(), r);
lastVar = alloc(1);
} else return;
addQuad<QAssign>(lastVar, l, op, r);
}
QuadruplePtr lastQuad; QuadruplePtr lastQuad;
BasicBlockPtr newBlock() { BasicBlockPtr newBlock() {
......
...@@ -104,7 +104,7 @@ void RegisterAllocator::buildGraph() { ...@@ -104,7 +104,7 @@ void RegisterAllocator::buildGraph() {
if (v.second == -1) { if (v.second == -1) {
gNumSpill++; gNumSpill++;
} else { } else {
v.first->name += "-r" + to_string(v.second); v.first->name += "-r" + to_string(v.second + 2);
} }
} }
for (auto &v : g2.getAllocation()) { for (auto &v : g2.getAllocation()) {
......
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