Merge branch 'array_add'
This commit is contained in:
217
src/include/Backend.h
Normal file
217
src/include/Backend.h
Normal 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
1711
src/include/IR.h
Normal file
File diff suppressed because it is too large
Load Diff
349
src/include/IRBuilder.h
Normal file
349
src/include/IRBuilder.h
Normal 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
|
||||
78
src/include/LLVMIRGenerator.h
Normal file
78
src/include/LLVMIRGenerator.h
Normal 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
340
src/include/SysYFormatter.h
Normal 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
|
||||
0
src/include/SysYIRAnalyser.h
Normal file
0
src/include/SysYIRAnalyser.h
Normal file
138
src/include/SysYIRGenerator.h
Normal file
138
src/include/SysYIRGenerator.h
Normal 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 *> ¶mTypes,
|
||||
const std::vector<std::string> ¶mNames,
|
||||
const std::vector<std::vector<Value *>> ¶mDims,
|
||||
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
63
src/include/range.h
Normal 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
|
||||
Reference in New Issue
Block a user