Commit 5ea4aec5 authored by zygzagZ's avatar zygzagZ

Flow + fix Makefile for CLion

parent 5ee30f7d
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 RegisterAllocator.o
.PHONY : clean distclean .PHONY : clean distclean
all : latc all : latc
...@@ -10,9 +8,9 @@ all : latc ...@@ -10,9 +8,9 @@ all : latc
clean : clean :
rm -f *.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar rm -f *.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
latc : ${OBJS} Latte.o 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
@echo "Linking latc..." @echo "Linking latc..."
${CC} ${CCFLAGS} ${OBJS} Latte.o -lstdc++fs -o latc ${CC} ${CCFLAGS} $^ -lstdc++fs -o latc
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
...@@ -44,10 +42,10 @@ ParseError.o : src/ParseError.cpp src/Info.h src/InfoList.h src/Absyn.h src/Pars ...@@ -44,10 +42,10 @@ ParseError.o : src/ParseError.cpp src/Info.h src/InfoList.h src/Absyn.h src/Pars
Quadruple.o : src/codeGen/Quadruple.cpp src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h Quadruple.o : src/codeGen/Quadruple.cpp src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h
${CC} ${CCFLAGS} -c src/codeGen/Quadruple.cpp ${CC} ${CCFLAGS} -c src/codeGen/Quadruple.cpp
Variable.o : src/codeGen/Quadruple.h src/codeGen/Variable.cpp src/Info.h src/InfoList.h src/Absyn.h Variable.o : src/codeGen/Variable.cpp src/codeGen/Quadruple.h src/Info.h src/InfoList.h src/Absyn.h
${CC} ${CCFLAGS} -c src/codeGen/Variable.cpp ${CC} ${CCFLAGS} -c src/codeGen/Variable.cpp
BasicBlock.o : src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/codeGen/BasicBlock.cpp src/codeGen/Variable.h src/Info.h src/InfoList.h src/Absyn.h BasicBlock.o : src/codeGen/BasicBlock.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/codeGen/Variable.h src/Info.h src/InfoList.h src/Absyn.h
${CC} ${CCFLAGS} -c src/codeGen/BasicBlock.cpp ${CC} ${CCFLAGS} -c src/codeGen/BasicBlock.cpp
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
......
#include "Compiler.h" #include "Compiler.h"
#include "codeGen/Quadruple.h" #include "codeGen/Quadruple.h"
#include "codeGen/RegisterAllocator.h"
#include <filesystem> #include <filesystem>
#include <iostream> #include <iostream>
#include <cassert> #include <cassert>
...@@ -54,9 +55,11 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) { ...@@ -54,9 +55,11 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
buf << "\"" << name << "\":\n"; buf << "\"" << name << "\":\n";
auto blocks = quadGen.compileFunction(f); auto quadEnv = quadGen.compileFunction(f);
for (const auto& b : blocks) { RegisterAllocator regGen(quadEnv);
for (const auto& b : quadEnv.blocks) {
for (const auto& q : b->quads) { for (const auto& q : b->quads) {
buf << q->toString() << endl; buf << q->toString() << endl;
} }
......
...@@ -14,7 +14,9 @@ void BasicBlock::finishQuads() { ...@@ -14,7 +14,9 @@ void BasicBlock::finishQuads() {
afterInit.clear(); afterInit.clear();
for (auto q : quads) { auto self = shared_from_this();
for (const auto& q : quads) {
q->useVariables(); q->useVariables();
q->block = self;
} }
} }
...@@ -11,12 +11,15 @@ using namespace std; ...@@ -11,12 +11,15 @@ using namespace std;
class BasicBlock : public std::enable_shared_from_this<BasicBlock> { class BasicBlock : public std::enable_shared_from_this<BasicBlock> {
public: public:
struct FlowAnalysisData {
set<VariablePtr> in, out, def, use;
};
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; vector<map<VariablePtr, VariablePtr>> phi;
FlowAnalysisData flow;
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());
......
...@@ -40,6 +40,7 @@ public: ...@@ -40,6 +40,7 @@ public:
int lineno; int lineno;
int index; int index;
BasicBlockPtr block;
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"; };
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "../Compiler.h" #include "../Compiler.h"
#include "QuadrupleGenerator.h" #include "QuadrupleGenerator.h"
vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) { QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f) {
if (!f->block) return {}; if (!f->block) return {};
scope->currentFunction = f; scope->currentFunction = f;
...@@ -55,10 +55,9 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) { ...@@ -55,10 +55,9 @@ vector<BasicBlockPtr> QuadrupleGenerator::compileFunction(FunctionInfoPtr f) {
for (const auto& q : v->uses) for (const auto& q : v->uses)
cout << q->toString() << endl; cout << q->toString() << endl;
} }
QuadrupleGenerator::Result ret;
vars.clear(); vars.swap(ret.vars);
vector<BasicBlockPtr> ret; blocks.swap(ret.blocks);
blocks.swap(ret);
scope->currentFunction = nullptr; scope->currentFunction = nullptr;
return ret; return ret;
......
...@@ -13,10 +13,15 @@ ...@@ -13,10 +13,15 @@
#include "Quadruple.h" #include "Quadruple.h"
#include "BasicBlock.h" #include "BasicBlock.h"
class QuadrupleGenerator : public Skeleton { class QuadrupleGenerator : public Skeleton {
public: public:
QuadrupleGenerator(shared_ptr<Scope> s) : lineno(0), scope(std::move(s)) {} struct Result {
vector<BasicBlockPtr> compileFunction(FunctionInfoPtr f); vector<BasicBlockPtr> blocks;
vector<VariablePtr> vars;
};
explicit QuadrupleGenerator(shared_ptr<Scope> s) : lineno(0), scope(std::move(s)) {}
Result compileFunction(FunctionInfoPtr f);
private: private:
vector<VariablePtr> vars; vector<VariablePtr> vars;
vector<BasicBlockPtr> blocks; vector<BasicBlockPtr> blocks;
......
#include "RegisterAllocator.h" #include "RegisterAllocator.h"
#include "BasicBlock.h"
#include "setOverloads.h"
void RegisterAllocator::analyseLive() { void RegisterAllocator::analyseLive() {
for (auto v : vars) {
for (auto q : v->uses) {
q->block->flow.use.emplace(v);
}
for (auto q : v->writes) {
q->block->flow.def.emplace(v);
}
}
for (const auto& b : blocks) {
for (const auto& phiMap : b->phi) {
for (const auto& phiRow : phiMap) {
b->flow.def.emplace(phiRow.first);
b->flow.use.emplace(phiRow.second);
}
}
}
while (true) {
bool changed = false;
for (const auto& b : blocks) {
set<VariablePtr> pIn, pOut, diff;
auto &f = b->flow;
pIn.swap(f.in);
pOut.swap(f.out);
f.in = f.use + (pOut - f.def);
for (const auto& succ : b->out) {
f.out += succ->flow.in;
}
if (f.in != pIn || f.out != pOut) changed = true;
}
if (!changed) break;
}
} }
\ No newline at end of file
#ifndef ZAD2_REGISTERALLOCATOR_H #ifndef ZAD2_REGISTERALLOCATOR_H
#define ZAD2_REGISTERALLOCATOR_H #define ZAD2_REGISTERALLOCATOR_H
#include <utility>
#include "Quadruple.h" #include "Quadruple.h"
#include "QuadrupleGenerator.h"
class Register : public std::enable_shared_from_this<Register> { class Register : public std::enable_shared_from_this<Register> {
bool available; bool available;
...@@ -11,21 +14,22 @@ class Register : public std::enable_shared_from_this<Register> { ...@@ -11,21 +14,22 @@ class Register : public std::enable_shared_from_this<Register> {
class RegisterAllocator { class RegisterAllocator {
public: public:
RegisterAllocator(vector<BasicBlockPtr> v) : blocks(v) {} RegisterAllocator(const QuadrupleGenerator::Result &r) : blocks(r.blocks), vars(r.vars) {}
void processQJump(shared_ptr<QJump> q) {}; void processQJump(shared_ptr<QJump> q);
void processQJumpCond(shared_ptr<QJumpCond> q) {}; void processQJumpCond(shared_ptr<QJumpCond> q);
void processQLabel(shared_ptr<QLabel> q) {}; void processQLabel(shared_ptr<QLabel> q);
void processQParam(shared_ptr<QParam> q) {}; void processQParam(shared_ptr<QParam> q);
void processQReturn(shared_ptr<QReturn> q) {}; void processQReturn(shared_ptr<QReturn> q);
void processQWrite(shared_ptr<QWrite> q) {}; void processQWrite(shared_ptr<QWrite> q);
void processQAccess(shared_ptr<QAccess> q) {}; void processQAccess(shared_ptr<QAccess> q);
void processQAlloc(shared_ptr<QAlloc> q) {}; void processQAlloc(shared_ptr<QAlloc> q);
void processQAssign(shared_ptr<QAssign> q) {}; void processQAssign(shared_ptr<QAssign> q);
void processQCall(shared_ptr<QCall> q) {}; void processQCall(shared_ptr<QCall> q);
void analyseLive(); void analyseLive();
private: private:
vector<BasicBlockPtr> blocks; vector<BasicBlockPtr> blocks;
vector<VariablePtr> vars;
}; };
......
#ifndef ZAD2_SETOVERLOADS_H
#define ZAD2_SETOVERLOADS_H
#include <set>
using namespace std;
template<typename T>
set<T> operator+ (const set<T> &l, const set<T> &r) {
set<T> ret;
set_union(l.begin(), l.end(), r.begin(), r.end(), std::inserter(ret, ret.begin()));
return ret;
}
template<typename T>
set<T> operator- (const set<T> &l, const set<T> &r) {
set<T> ret;
set_difference(l.begin(), l.end(), r.begin(), r.end(), std::inserter(ret, ret.begin()));
return ret;
}
template<typename T>
set<T> operator^(const set<T> &l, const set<T> &r) {
set<T> ret;
set_symmetric_difference(l.begin(), l.end(), r.begin(), r.end(), std::inserter(ret, ret.begin()));
return ret;
}
template<typename T>
set<T>& operator+=(set<T> &l, const set<T> &r) {
auto diff = r - l;
l.insert(diff.begin(), diff.end());
return l;
}
template<typename T>
bool operator==(const set<T> &l, const set<T> &r) {
return (r^l).empty();
}
template<typename T>
bool operator!=(const set<T> &l, const set<T> &r) {
return !(r == l);
}
#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