use less temporaries

This commit is contained in:
Thomas Lindner 2023-01-05 19:52:27 +01:00
parent 577581f2ce
commit d46f7fb91f
2 changed files with 32 additions and 25 deletions

View file

@ -3,6 +3,11 @@
namespace xlang { namespace xlang {
std::string EmitVisitor::tmp() {
last = "%t" + std::to_string(tmpcount++);
return last;
}
EmitVisitor::EmitVisitor(std::string_view outputfile) : output{outputfile} {} EmitVisitor::EmitVisitor(std::string_view outputfile) : output{outputfile} {}
std::any EmitVisitor::visitFile(xlangParser::FileContext *ctx) { std::any EmitVisitor::visitFile(xlangParser::FileContext *ctx) {
@ -32,8 +37,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
if (auto identifier = ctx->Identifier()) { if (auto identifier = ctx->Identifier()) {
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitExpr(ctx->expr());
output << " %_" << identifier->getSymbol()->getText() << " = w copy %t" output << " %_" << identifier->getSymbol()->getText() << " = w copy "
<< tmpcount - 1 << std::endl; << last << std::endl;
return {}; return {};
} }
if (ctx->If()) { if (ctx->If()) {
@ -41,8 +46,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
output << "@if" << block << "_expr" << std::endl; output << "@if" << block << "_expr" << std::endl;
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitExpr(ctx->expr());
output << " jnz %t" << tmpcount - 1 << ", @if" << block << "_then, @if" output << " jnz " << last << ", @if" << block << "_then, @if" << block
<< block << "_else" << std::endl; << "_else" << std::endl;
output << "@if" << block << "_then" << std::endl; output << "@if" << block << "_then" << std::endl;
visitBlock(ctx->block(0)); visitBlock(ctx->block(0));
output << " jmp @if" << block << "_end" << std::endl; output << " jmp @if" << block << "_end" << std::endl;
@ -58,8 +63,8 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
output << "@while" << block << "_expr" << std::endl; output << "@while" << block << "_expr" << std::endl;
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitExpr(ctx->expr());
output << " jnz %t" << tmpcount - 1 << ", @while" << block output << " jnz " << last << ", @while" << block << "_body, @while"
<< "_body, @while" << block << "_end" << std::endl; << block << "_end" << std::endl;
output << "@while" << block << "_body" << std::endl; output << "@while" << block << "_body" << std::endl;
visitBlock(ctx->block(0)); visitBlock(ctx->block(0));
output << " jmp @while" << block << "_expr" << std::endl; output << " jmp @while" << block << "_expr" << std::endl;
@ -69,14 +74,14 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
if (ctx->Return()) { if (ctx->Return()) {
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitExpr(ctx->expr());
output << " ret %t" << tmpcount - 1 << std::endl; output << " ret " << last << std::endl;
output << "@dead" << blockcount++ << std::endl; output << "@dead" << blockcount++ << std::endl;
return {}; return {};
} }
if (ctx->Print()) { if (ctx->Print()) {
tmpcount = 0; tmpcount = 0;
visitExpr(ctx->expr()); visitExpr(ctx->expr());
output << " call $printf(l $printformat, ..., w %t" << tmpcount - 1 << ")" output << " call $printf(l $printformat, ..., w " << last << ")"
<< std::endl; << std::endl;
return {}; return {};
} }
@ -84,15 +89,15 @@ std::any EmitVisitor::visitStatement(xlangParser::StatementContext *ctx) {
return {}; return {};
} }
#define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \ #define OPERATOR(Operator, visitLeft, left, visitRight, right, ssa_op) \
if (ctx->Operator()) { \ if (ctx->Operator()) { \
visitLeft(ctx->left); \ visitLeft(ctx->left); \
int l = tmpcount - 1; \ std::string l = last; \
visitRight(ctx->right); \ visitRight(ctx->right); \
output << " %t" << tmpcount << " = w " ssa_op " %t" << l << ", %t" \ std::string r = last; \
<< tmpcount - 1 << std::endl; \ output << " " << tmp() << " = w " ssa_op " " << l << ", " << r \
tmpcount++; \ << std::endl; \
return {}; \ return {}; \
} }
std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) { std::any EmitVisitor::visitExpr(xlangParser::ExprContext *ctx) {
@ -122,28 +127,26 @@ std::any EmitVisitor::visitTerm(xlangParser::TermContext *ctx) {
std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) { std::any EmitVisitor::visitFactor(xlangParser::FactorContext *ctx) {
if (auto integer = ctx->Integer()) { if (auto integer = ctx->Integer()) {
output << " %t" << tmpcount++ << " = w copy " last = integer->getSymbol()->getText();
<< integer->getSymbol()->getText() << std::endl;
return {}; return {};
} }
if (auto identifier = ctx->Identifier()) { if (auto identifier = ctx->Identifier()) {
if (ctx->LeftParen()) { if (ctx->LeftParen()) {
std::vector<int> args; std::vector<std::string> args;
if (auto expr_list = ctx->exprList()) { if (auto expr_list = ctx->exprList()) {
for (auto expr : expr_list->expr()) { for (auto expr : expr_list->expr()) {
visitExpr(expr); visitExpr(expr);
args.push_back(tmpcount - 1); args.push_back(last);
} }
} }
output << " %t" << tmpcount++ << " = w call $" output << " " << tmp() << " = w call $"
<< identifier->getSymbol()->getText() << "("; << identifier->getSymbol()->getText() << "(";
for (auto arg : args) { for (auto arg : args) {
output << "w %t" << arg << ", "; output << "w " << arg << ", ";
} }
output << ")" << std::endl; output << ")" << std::endl;
} else { } else {
output << " %t" << tmpcount++ << " = w copy %_" last = "%_" + identifier->getSymbol()->getText();
<< identifier->getSymbol()->getText() << std::endl;
} }
return {}; return {};
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <fstream> #include <fstream>
#include <string>
#include <string_view> #include <string_view>
#include <xlangBaseVisitor.h> #include <xlangBaseVisitor.h>
@ -10,6 +11,9 @@ class EmitVisitor : public xlangBaseVisitor {
std::ofstream output; std::ofstream output;
int blockcount; int blockcount;
int tmpcount; int tmpcount;
std::string last;
std::string tmp();
public: public:
EmitVisitor(std::string_view outputfile); EmitVisitor(std::string_view outputfile);