Merge branch 'array_add'

This commit is contained in:
lixuanwang
2025-06-22 14:24:00 +08:00
23 changed files with 5657 additions and 3162 deletions

217
src/include/Backend.h Normal file
View File

@@ -0,0 +1,217 @@
#pragma once
/**
* 后端设计需要注意的点
*
* label分配 :
* 全局变量的label,常量的label,basicblock的label,函数入口label,函数出口label
* 全局数据处理
* 常量处理
* 临时变量的处理(包括函数参数也是临时变量)
* 函数参数的处理
* 块参数的处理 (如果SSA问题通过块传参解决则需要处理块参数)
* 函数栈空间结构的设计
* 块的遍历问题
* arm32的过程调用约定
*
* 后端测试需要注意的点
*
* 如何汇编与链接.
* qemu以及树莓派如何运行.
*/
#include <algorithm>
#include <set>
#include <string>
#include <vector>
#include "IR.h"
using std::find;
using std::map;
using std::pair;
using std::set;
using std::string;
using std::to_string;
using std::vector;
#define Macro_ERROR_MSG(...) \
do { \
fprintf(stderr, "ERROR in line-%d of %s: ", __LINE__, __FILE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
fflush(stderr); \
exit(1); \
} while (0);
#define M_emitInst(STR) (space + STR + eol)
#define M_emitComment(STR) (space + "//" + STR + eol)
#define M_emitLabel(STR) (STR + ":" + eol)
// #define REG_EXP
static const string space = string(4, ' ');
static const string eol = "\n";
// only for armv7
static const int int_align = 4;
static const int int_size = 4;
static const int int_p2align = 2;
static const int reg_size = 4;
// default arm32 max imm
//
static const uint32_t maxMovImm = 0xFFF;
static const string stackIndexReg = "fp";
static uint16_t getWordHigh(uint32_t cval) { return (cval >> 16) & 0xFFFF; }
static uint16_t getWordLow(uint32_t cval) { return cval & 0xFFFF; }
//
static string emitInst_1srcR_noDstR(string name, string srcReg) {
return space + name + " " + srcReg + eol;
}
static string emitInst_2srcR_1dstR(string name, string srcReg0, string srcReg1,
string dstReg) {
return space + name + " " + dstReg + ", " + srcReg0 + ", " + srcReg1 + eol;
}
namespace sysy {
//
class RegManager {
public:
//{0,1,2,3,4,5,6,7,8,9,10};
enum RegId : unsigned {
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
RNONE = 1024,
RANY = 2048,
};
static string toString(RegId reg) {
if (reg == RNONE)
return "RNONE";
if (reg == RANY)
return "RANY";
return "r" + to_string(reg);
}
};
class Operand {
public:
using RegId = RegManager::RegId;
enum Kind {
kReg,
kImm,
};
Kind kind;
union {
uint32_t imm;
RegId regId;
};
Operand(){};
Operand(uint32_t imm) : kind(kImm), imm(imm) {}
Operand(RegId regId) : kind(kReg), regId(regId) {}
bool isImm(void) { return kind == kImm; }
bool isReg(void) { return kind == kReg; }
uint32_t getImm(void) {
assert(kind == kImm);
return imm;
}
RegId getRegId(void) {
assert(kind == kReg);
return regId;
}
string toString(void) {
if (kind == kImm)
return "#" + to_string(imm);
else
return RegManager::toString(regId);
}
};
class CodeGen {
public:
using RegId = RegManager::RegId;
private:
sysy::Module *module;
Function *curFunc;
BasicBlock *curBB;
//
RegManager regm;
// globalValue
bool loadGlobalValByMOVWT = true;
// basicBlock
vector<BasicBlock *> linear_bb;
int bb_no = 0;
// function params, return value and localVar
map<Argument *, int> paramsStOffset;
map<Instruction *, int> localVarStOffset;
int retValueStOffset = 0;
size_t stOffsetAcc = 0;
// label manager
map<BasicBlock *, string> bb_labels;
uint64_t label_no = 0;
public:
CodeGen(Module *module) : module(module) {}
// code_gen function list
string code_gen();
string module_gen(Module *module);
string function_gen(Function *func);
string basicBlock_gen(BasicBlock *bb);
string instruction_gen(Instruction *instr);
string globaldata_gen();
string prologueCode_gen(Function *func);
string epilogueCode_gen(Function *func);
string literalPoolsCode_gen(Function *func);
string functionHead_gen(Function *func);
// Module
void clearModuleRecord(Module *module) { label_no = 0; }
// instruction gen function list
//<dstReg, code>
pair<RegId, string> loadInst_gen(LoadInst *ldInst, RegId dstRegId);
string storeInst_gen(StoreInst *stInst);
pair<RegId, string> allocaInst_gen(AllocaInst *aInst, RegId dstRegId);
string returnInst_gen(ReturnInst *retInst);
pair<RegId, string> callInst_gen(CallInst *retInst, RegId dstRegId);
pair<RegId, string> binaryInst_gen(BinaryInst *bInst, RegId dstRegId);
pair<RegId, string> unaryInst_gen(UnaryInst *bInst, RegId dstRegId);
string uncondBrInst_gen(UncondBrInst *ubInst);
string condBrInst_gen(CondBrInst *ubInst);
//
string storeRegToStack_gen(RegId regId, Instruction *inst) {
string code;
/**
*code in here
*/
return code;
}
// function
void clearFunctionRecord(Function *func) {
localVarStOffset.clear();
paramsStOffset.clear();
retValueStOffset = 0;
bb_labels.clear();
//
stOffsetAcc = 0;
}
string getBBLabel(BasicBlock *bb) {
auto t = bb_labels.find(bb);
string label;
if (t == bb_labels.end()) {
label = ".LBB_" + to_string(label_no++);
bb_labels.emplace(bb, label);
} else {
label = t->second;
}
return label;
}
};
} // namespace sysy

1711
src/include/IR.h Normal file

File diff suppressed because it is too large Load Diff

349
src/include/IRBuilder.h Normal file
View File

@@ -0,0 +1,349 @@
#pragma once
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "IR.h"
/**
* @file IRBuilder.h
*
* @brief 定义IR构建器的头文件
*/
namespace sysy {
/**
* @brief 中间IR的构建器
*
*/
class IRBuilder {
private:
unsigned labelIndex; ///< 基本块标签编号
unsigned tmpIndex; ///< 临时变量编号
BasicBlock *block; ///< 当前基本块
BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
public:
IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: labelIndex(0), tmpIndex(0), block(block), position(position) {}
public:
unsigned getLabelIndex() {
labelIndex += 1;
return labelIndex - 1;
} ///< 获取基本块标签编号
unsigned getTmpIndex() {
tmpIndex += 1;
return tmpIndex - 1;
} ///< 获取临时变量编号
BasicBlock * getBasicBlock() const { return block; } ///< 获取当前基本块
BasicBlock * getBreakBlock() const { return breakBlocks.back(); } ///< 获取break目标块
BasicBlock * popBreakBlock() {
auto result = breakBlocks.back();
breakBlocks.pop_back();
return result;
} ///< 弹出break目标块
BasicBlock * getContinueBlock() const { return continueBlocks.back(); } ///< 获取continue目标块
BasicBlock * popContinueBlock() {
auto result = continueBlocks.back();
continueBlocks.pop_back();
return result;
} ///< 弹出continue目标块
BasicBlock * getTrueBlock() const { return trueBlocks.back(); } ///< 获取true分支基本块
BasicBlock * getFalseBlock() const { return falseBlocks.back(); } ///< 获取false分支基本块
BasicBlock * popTrueBlock() {
auto result = trueBlocks.back();
trueBlocks.pop_back();
return result;
} ///< 弹出true分支基本块
BasicBlock * popFalseBlock() {
auto result = falseBlocks.back();
falseBlocks.pop_back();
return result;
} ///< 弹出false分支基本块
BasicBlock::iterator getPosition() const { return position; } ///< 获取当前基本块指令列表位置的迭代器
void setPosition(BasicBlock *block, BasicBlock::iterator position) {
this->block = block;
this->position = position;
} ///< 设置基本块和基本块指令列表位置的迭代器
void setPosition(BasicBlock::iterator position) {
this->position = position;
} ///< 设置当前基本块指令列表位置的迭代器
void pushBreakBlock(BasicBlock *block) { breakBlocks.push_back(block); } ///< 压入break目标基本块
void pushContinueBlock(BasicBlock *block) { continueBlocks.push_back(block); } ///< 压入continue目标基本块
void pushTrueBlock(BasicBlock *block) { trueBlocks.push_back(block); } ///< 压入true分支基本块
void pushFalseBlock(BasicBlock *block) { falseBlocks.push_back(block); } ///< 压入false分支基本块
public:
Instruction * insertInst(Instruction *inst) {
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 插入指令
UnaryInst * createUnaryInst(Instruction::Kind kind, Type *type, Value *operand, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new UnaryInst(kind, type, operand, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建一元指令
UnaryInst * createNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand, name);
} ///< 创建取反指令
UnaryInst * createNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand, name);
} ///< 创建取非指令
UnaryInst * createFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand, name);
} ///< 创建浮点转整型指令
UnaryInst * createBitFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitFtoI, Type::getIntType(), operand, name);
} ///< 创建按位浮点转整型指令
UnaryInst * createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand, name);
} ///< 创建浮点取反指令
UnaryInst * createFNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
} ///< 创建浮点取非指令
UnaryInst * createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
} ///< 创建整型转浮点指令
UnaryInst * createBitItoFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitItoF, Type::getFloatType(), operand, name);
} ///< 创建按位整型转浮点指令
BinaryInst * createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, Value *rhs, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new BinaryInst(kind, type, lhs, rhs, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建二元指令
BinaryInst * createAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs, name);
} ///< 创建加法指令
BinaryInst * createSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs, name);
} ///< 创建减法指令
BinaryInst * createMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs, name);
} ///< 创建乘法指令
BinaryInst * createDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs, name);
} ///< 创建除法指令
BinaryInst * createRemInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs, name);
} ///< 创建取余指令
BinaryInst * createICmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建相等设置指令
BinaryInst * createICmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建不相等设置指令
BinaryInst * createICmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于设置指令
BinaryInst * createICmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于等于设置指令
BinaryInst * createICmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于设置指令
BinaryInst * createICmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于等于设置指令
BinaryInst * createFAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点加法指令
BinaryInst * createFSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点减法指令
BinaryInst * createFMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点乘法指令
BinaryInst * createFDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点除法指令
BinaryInst * createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相等设置指令
BinaryInst * createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点不相等设置指令
BinaryInst * createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于设置指令
BinaryInst * createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于等于设置指令
BinaryInst * createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点大于设置指令
BinaryInst * createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相大于等于设置指令
BinaryInst * createAndInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAnd, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位且指令
BinaryInst * createOrInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kOr, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位或指令
CallInst * createCallInst(Function *callee, const std::vector<Value *> &args, const std::string &name = "") {
std::string newName;
if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new CallInst(callee, args, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建Call指令
ReturnInst * createReturnInst(Value *value = nullptr, const std::string &name = "") {
auto inst = new ReturnInst(value, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建return指令
UncondBrInst * createUncondBrInst(BasicBlock *thenBlock, const std::vector<Value *> &args) {
auto inst = new UncondBrInst(thenBlock, args, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建无条件指令
CondBrInst * createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs, const std::vector<Value *> &elseArgs) {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, elseArgs, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建条件跳转指令
AllocaInst * createAllocaInst(Type *type, const std::vector<Value *> &dims = {}, const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建分配指令
AllocaInst * createAllocaInstWithoutInsert(Type *type, const std::vector<Value *> &dims = {}, BasicBlock *parent = nullptr,
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, parent, name);
assert(inst);
return inst;
} ///< 创建不插入指令列表的分配指令
LoadInst * createLoadInst(Value *pointer, const std::vector<Value *> &indices = {}, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new LoadInst(pointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建load指令
LaInst * createLaInst(Value *pointer, const std::vector<Value *> &indices = {}, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << "%" << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new LaInst(pointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建la指令
GetSubArrayInst * createGetSubArray(LVal *fatherArray, const std::vector<Value *> &indices, const std::string &name = "") {
assert(fatherArray->getLValNumDims() > indices.size());
std::vector<Value *> subDims;
auto dims = fatherArray->getLValDims();
auto iter = std::next(dims.begin(), indices.size());
while (iter != dims.end()) {
subDims.emplace_back(*iter);
iter++;
}
std::string childArrayName;
std::stringstream ss;
ss << "A"
<< "%" << tmpIndex;
childArrayName = ss.str();
tmpIndex++;
auto fatherArrayValue = dynamic_cast<Value *>(fatherArray);
auto childArray = new AllocaInst(fatherArrayValue->getType(), subDims, block, childArrayName);
auto inst = new GetSubArrayInst(fatherArray, childArray, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建获取部分数组指令
MemsetInst * createMemsetInst(Value *pointer, Value *begin, Value *size, Value *value, const std::string &name = "") {
auto inst = new MemsetInst(pointer, begin, size, value, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建memset指令
StoreInst * createStoreInst(Value *value, Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new StoreInst(value, pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建store指令
PhiInst * createPhiInst(Type *type, Value *lhs, BasicBlock *parent, const std::string &name = "") {
auto predNum = parent->getNumPredecessors();
std::vector<Value *> rhs;
for (size_t i = 0; i < predNum; i++) {
rhs.push_back(lhs);
}
auto inst = new PhiInst(type, lhs, rhs, lhs, parent, name);
assert(inst);
parent->getInstructions().emplace(parent->begin(), inst);
return inst;
} ///< 创建Phi指令
};
} // namespace sysy

View File

@@ -0,0 +1,78 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include "IR.h"
#include "IRBuilder.h"
#include <sstream>
#include <map>
#include <vector>
#include <stack>
class LLVMIRGenerator : public SysYBaseVisitor {
public:
sysy::Module* getIRModule() const { return irModule.get(); }
std::string generateIR(SysYParser::CompUnitContext* unit);
std::string getIR() const { return irStream.str(); }
private:
std::unique_ptr<sysy::Module> irModule; // IR数据结构
std::stringstream irStream; // 文本输出流
sysy::IRBuilder irBuilder; // IR构建器
int tempCounter = 0;
std::string currentVarType;
// std::map<std::string, sysy::Value*> symbolTable;
std::map<std::string, std::pair<std::string, std::string>> symbolTable;
std::map<std::string, std::string> tmpTable;
std::vector<std::string> globalVars;
std::string currentFunction;
std::string currentReturnType;
std::vector<std::string> breakStack;
std::vector<std::string> continueStack;
bool hasReturn = false;
struct LoopLabels {
std::string breakLabel; // break跳转的目标标签
std::string continueLabel; // continue跳转的目标标签
};
std::stack<LoopLabels> loopStack; // 用于管理循环的break和continue标签
std::string getNextTemp();
std::string getLLVMType(const std::string&);
sysy::Type* getSysYType(const std::string&);
bool inFunction = false; // 标识当前是否处于函数内部
// 访问方法
std::any visitCompUnit(SysYParser::CompUnitContext* ctx);
std::any visitConstDecl(SysYParser::ConstDeclContext* ctx);
std::any visitVarDecl(SysYParser::VarDeclContext* ctx);
std::any visitVarDef(SysYParser::VarDefContext* ctx);
std::any visitFuncDef(SysYParser::FuncDefContext* ctx);
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx);
// std::any visitStmt(SysYParser::StmtContext* ctx);
std::any visitLValue(SysYParser::LValueContext* ctx);
std::any visitPrimaryExp(SysYParser::PrimaryExpContext* ctx);
std::any visitPrimExp(SysYParser::PrimExpContext* ctx);
std::any visitParenExp(SysYParser::ParenExpContext* ctx);
std::any visitNumber(SysYParser::NumberContext* ctx);
std::any visitString(SysYParser::StringContext* ctx);
std::any visitCall(SysYParser::CallContext *ctx);
std::any visitUnExp(SysYParser::UnExpContext* ctx);
std::any visitMulExp(SysYParser::MulExpContext* ctx);
std::any visitAddExp(SysYParser::AddExpContext* ctx);
std::any visitRelExp(SysYParser::RelExpContext* ctx);
std::any visitEqExp(SysYParser::EqExpContext* ctx);
std::any visitLAndExp(SysYParser::LAndExpContext* ctx);
std::any visitLOrExp(SysYParser::LOrExpContext* ctx);
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// 统一创建二元操作(同时生成数据结构和文本)
sysy::Value* createBinaryOp(SysYParser::ExpContext* lhs,
SysYParser::ExpContext* rhs,
sysy::Instruction::Kind opKind);
};

340
src/include/SysYFormatter.h Normal file
View File

@@ -0,0 +1,340 @@
#pragma once
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include <ostream>
namespace sysy {
class SysYFormatter : public SysYBaseVisitor {
protected:
std::ostream &os;
int indent = 0;
public:
SysYFormatter(std::ostream &os) : os(os), indent(0) {}
protected:
struct Indentor {
static constexpr int TabSize = 2;
int &indent;
Indentor(int &indent) : indent(indent) { indent += TabSize; }
~Indentor() { indent -= TabSize; }
};
std::ostream &space() { return os << std::string(indent, ' '); }
template <typename T>
std::ostream &interleave(const T &container, const std::string sep = ", ") {
auto b = container.begin(), e = container.end();
(*b)->accept(this);
for (b = std::next(b); b != e; b = std::next(b)) {
os << sep;
(*b)->accept(this);
}
return os;
}
public:
// virtual std::any visitModule(SysYParser::ModuleContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any visitBtype(SysYParser::BtypeContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any visitDecl(SysYParser::DeclContext *ctx) override {
space();
if (ctx->CONST())
os << ctx->CONST()->getText() << ' ';
ctx->btype()->accept(this);
os << ' ';
interleave(ctx->varDef(), ", ") << ';' << '\n';
return 0;
}
virtual std::any visitVarDef(SysYParser::VarDefContext *ctx) override {
ctx->lValue()->accept(this);
if (ctx->initValue()) {
os << ' ' << '=' << ' ';
ctx->initValue()->accept(this);
}
return 0;
}
virtual std::any visitInitValue(SysYParser::InitValueContext *ctx) override {
if (not ctx->exp()) {
os << '{';
auto values = ctx->initValue();
if (values.size())
interleave(values, ", ");
os << '}';
}
return 0;
}
virtual std::any visitFunc(SysYParser::FuncContext *ctx) override {
ctx->funcType()->accept(this);
os << ' ' << ctx->ID()->getText() << '(';
if (ctx->funcFParams())
ctx->funcFParams()->accept(this);
os << ')' << ' ';
ctx->blockStmt()->accept(this);
os << '\n';
return 0;
}
virtual std::any visitFuncType(SysYParser::FuncTypeContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any
visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override {
interleave(ctx->funcFParam(), ", ");
return 0;
}
virtual std::any
visitFuncFParam(SysYParser::FuncFParamContext *ctx) override {
ctx->btype()->accept(this);
os << ' ' << ctx->ID()->getText();
if (not ctx->LBRACKET().empty()) {
os << '[';
auto exp = ctx->exp();
if (not exp.empty()) {
os << '[';
interleave(exp, "][") << ']';
}
}
return 0;
}
virtual std::any visitBlockStmt(SysYParser::BlockStmtContext *ctx) override {
os << '{' << '\n';
{
Indentor indentor(indent);
auto items = ctx->blockItem();
if (not items.empty())
interleave(items, "");
}
space() << ctx->RBRACE()->getText() << '\n';
return 0;
}
// virtual std::any visitBlockItem(SysYParser::BlockItemContext *ctx)
// override {
// return visitChildren(ctx);
// }
// virtual std::any visitStmt(SysYParser::StmtContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any
visitAssignStmt(SysYParser::AssignStmtContext *ctx) override {
space();
ctx->lValue()->accept(this);
os << " = ";
ctx->exp()->accept(this);
os << ';' << '\n';
return 0;
}
virtual std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override {
space();
ctx->exp()->accept(this);
os << ';' << '\n';
return 0;
}
void wrapBlock(SysYParser::StmtContext *stmt) {
bool isBlock = stmt->blockStmt();
if (isBlock) {
stmt->accept(this);
} else {
os << "{\n";
{
Indentor indentor(indent);
stmt->accept(this);
}
space() << "}\n";
}
};
virtual std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override {
space();
os << ctx->IF()->getText() << " (";
ctx->exp()->accept(this);
os << ") ";
auto stmt = ctx->stmt();
auto ifStmt = stmt[0];
wrapBlock(ifStmt);
if (stmt.size() == 2) {
auto elseStmt = stmt[1];
wrapBlock(elseStmt);
}
return 0;
}
virtual std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override {
space();
os << ctx->WHILE()->getText() << " (";
ctx->exp()->accept(this);
os << ") ";
wrapBlock(ctx->stmt());
return 0;
}
virtual std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override {
space() << ctx->BREAK()->getText() << ';' << '\n';
return 0;
}
virtual std::any
visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override {
space() << ctx->CONTINUE()->getText() << ';' << '\n';
return 0;
}
virtual std::any
visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override {
space() << ctx->RETURN()->getText();
if (ctx->exp()) {
os << ' ';
ctx->exp()->accept(this);
}
os << ';' << '\n';
return 0;
}
// virtual std::any visitEmptyStmt(SysYParser::EmptyStmtContext *ctx)
// override {
// return visitChildren(ctx);
// }
virtual std::any
visitRelationExp(SysYParser::RelationExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op =
ctx->LT() ? "<" : (ctx->LE() ? "<=" : (ctx->GT() ? ">" : ">="));
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any
visitMultiplicativeExp(SysYParser::MultiplicativeExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->MUL() ? "*" : (ctx->DIV() ? "/" : "%");
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
// virtual std::any visitLValueExp(SysYParser::LValueExpContext *ctx)
// override {
// return visitChildren(ctx);
// }
// virtual std::any visitNumberExp(SysYParser::NumberExpContext *ctx)
// override {
// return visitChildren(ctx);
// }
virtual std::any visitAndExp(SysYParser::AndExpContext *ctx) override {
ctx->exp(0)->accept(this);
os << " && ";
ctx->exp(1)->accept(this);
return 0;
}
virtual std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override {
std::string op = ctx->ADD() ? "+" : (ctx->SUB() ? "-" : "!");
os << op;
ctx->exp()->accept(this);
return 0;
}
virtual std::any visitParenExp(SysYParser::ParenExpContext *ctx) override {
os << '(';
ctx->exp()->accept(this);
os << ')';
return 0;
}
virtual std::any visitStringExp(SysYParser::StringExpContext *ctx) override {
return visitChildren(ctx);
}
virtual std::any visitOrExp(SysYParser::OrExpContext *ctx) override {
ctx->exp(0)->accept(this);
os << " || ";
ctx->exp(1)->accept(this);
return 0;
}
// virtual std::any visitCallExp(SysYParser::CallExpContext *ctx) override {
// return visitChildren(ctx);
// }
virtual std::any
visitAdditiveExp(SysYParser::AdditiveExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->ADD() ? "+" : "-";
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any visitEqualExp(SysYParser::EqualExpContext *ctx) override {
auto lhs = ctx->exp(0);
auto rhs = ctx->exp(1);
std::string op = ctx->EQ() ? "==" : "!=";
lhs->accept(this);
os << ' ' << op << ' ';
rhs->accept(this);
return 0;
}
virtual std::any visitCall(SysYParser::CallContext *ctx) override {
os << ctx->ID()->getText() << '(';
if (ctx->funcRParams())
ctx->funcRParams()->accept(this);
os << ')';
return 0;
}
virtual std::any visitLValue(SysYParser::LValueContext *ctx) override {
os << ctx->ID()->getText();
auto exp = ctx->exp();
if (not exp.empty()) {
os << '[';
interleave(exp, "][") << ']';
}
return 0;
}
virtual std::any visitNumber(SysYParser::NumberContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any visitString(SysYParser::StringContext *ctx) override {
os << ctx->getText();
return 0;
}
virtual std::any
visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override {
interleave(ctx->exp(), ", ");
return 0;
}
};
} // namespace sysy

View File

View File

@@ -0,0 +1,138 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include <memory>
#include <unordered_map>
#include <forward_list>
namespace sysy {
// @brief 用于存储数组值的树结构
// 多位数组本质上是一维数组的嵌套可以用树来表示。
class ArrayValueTree {
private:
Value *value = nullptr; /// 该节点存储的value
std::vector<std::unique_ptr<ArrayValueTree>> children; /// 子节点列表
public:
ArrayValueTree() = default;
public:
auto getValue() const -> Value * { return value; }
auto getChildren() const
-> const std::vector<std::unique_ptr<ArrayValueTree>> & {
return children;
}
void setValue(Value *newValue) { value = newValue; }
void addChild(ArrayValueTree *newChild) { children.emplace_back(newChild); }
void addChildren(const std::vector<ArrayValueTree *> &newChildren) {
for (const auto &child : newChildren) {
children.emplace_back(child);
}
}
};
class Utils {
public:
// transform a tree of ArrayValueTree to a ValueCounter
static void tree2Array(Type *type, ArrayValueTree *root,
const std::vector<Value *> &dims, unsigned numDims,
ValueCounter &result, IRBuilder *builder);
static void
createExternalFunction(const std::vector<Type *> &paramTypes,
const std::vector<std::string> &paramNames,
const std::vector<std::vector<Value *>> &paramDims,
Type *returnType, const std::string &funcName,
Module *pModule, IRBuilder *pBuilder);
static void initExternalFunction(Module *pModule, IRBuilder *pBuilder);
};
class SysYIRGenerator : public SysYBaseVisitor {
private:
std::unique_ptr<Module> module;
IRBuilder builder;
public:
SysYIRGenerator() = default;
public:
Module *get() const { return module.get(); }
IRBuilder *getBuilder(){ return &builder; }
public:
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
std::any visitGlobalConstDecl(SysYParser::GlobalConstDeclContext *ctx) override;
std::any visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *ctx) override;
// std::any visitDecl(SysYParser::DeclContext *ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
std::any visitBType(SysYParser::BTypeContext *ctx) override;
// std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
// std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
std::any visitScalarInitValue(SysYParser::ScalarInitValueContext *ctx) override;
std::any visitArrayInitValue(SysYParser::ArrayInitValueContext *ctx) override;
std::any visitConstScalarInitValue(SysYParser::ConstScalarInitValueContext *ctx) override;
std::any visitConstArrayInitValue(SysYParser::ConstArrayInitValueContext *ctx) override;
// std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// std::any visitInitVal(SysYParser::InitValContext *ctx) override;
// std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
// std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
// std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override;
// std::any visitBlkStmt(SysYParser::BlkStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// std::any visitExp(SysYParser::ExpContext *ctx) override;
// std::any visitCond(SysYParser::CondContext *ctx) override;
std::any visitLValue(SysYParser::LValueContext *ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
// std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
std::any visitNumber(SysYParser::NumberContext *ctx) override;
// std::any visitString(SysYParser::StringContext *ctx) override;
std::any visitCall(SysYParser::CallContext *ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
// std::any visitUnExp(SysYParser::UnExpContext *ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
// std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
}; // class SysYIRGenerator
} // namespace sysy

63
src/include/range.h Normal file
View File

@@ -0,0 +1,63 @@
#pragma once
#include <iterator>
namespace sysy {
/*!
* \defgroup utility Utilities
* @{
*/
/*!
* \brief `range` is an simple wrapper of an iterator pair [begin, end)
*
* Example usage
*
* ```cpp
* vector<int> v = {1,2,3};
* auto rg = make_range(v);
* for (auto v : rg)
* cout << v << '\n';
* ```
*/
template <typename IterT> struct range {
using iterator = IterT;
using value_type = typename std::iterator_traits<iterator>::value_type;
using reference = typename std::iterator_traits<iterator>::reference;
private:
iterator b;
iterator e;
public:
explicit range(iterator b, iterator e) : b(b), e(e) {}
iterator begin() { return b; }
iterator end() { return e; }
iterator begin() const { return b; }
iterator end() const { return e; }
auto size() const { return std::distance(b, e); }
auto empty() const { return b == e; }
};
//! create `range` object from iterator pair [begin, end)
template <typename IterT> range<IterT> make_range(IterT b, IterT e) {
return range(b, e);
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::iterator> make_range(ContainerT &c) {
return make_range(c.begin(), c.end());
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::const_iterator> make_range(const ContainerT &c) {
return make_range(c.begin(), c.end());
}
/*!
* @}
*/
} // namespace sysy