更改前置声明,IR生成更新
This commit is contained in:
@@ -83,6 +83,354 @@ std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *c
|
||||
return std::any();
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitConstDecl(SysYParser::ConstDeclContext *ctx){
|
||||
Type* type = std::any_cast<Type *>(visitBType(ctx->bType()));
|
||||
for (const auto constDef : ctx->constDef()) {
|
||||
std::vector<Value *> dims = {};
|
||||
std::string name = constDef->Ident()->getText();
|
||||
auto constExps = constDef->constExp();
|
||||
if (!constExps.empty()) {
|
||||
for (const auto constExp : constExps) {
|
||||
dims.push_back(std::any_cast<Value *>(visitConstExp(constExp)));
|
||||
}
|
||||
}
|
||||
|
||||
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(constDef->constInitVal()->accept(this));
|
||||
ValueCounter values;
|
||||
Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
|
||||
delete root;
|
||||
|
||||
module->createConstVar(name, Type::getPointerType(type), values, dims);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitVarDecl(SysYParser::VarDeclContext *ctx) {
|
||||
Type* type = std::any_cast<Type *>(visitBType(ctx->bType()));
|
||||
for (const auto varDef : ctx->varDef()) {
|
||||
std::vector<Value *> dims = {};
|
||||
std::string name = varDef->Ident()->getText();
|
||||
auto constExps = varDef->constExp();
|
||||
if (!constExps.empty()) {
|
||||
for (const auto &constExp : constExps) {
|
||||
dims.push_back(std::any_cast<Value *>(visitConstExp(constExp)));
|
||||
}
|
||||
}
|
||||
|
||||
AllocaInst* alloca =
|
||||
builder.createAllocaInst(Type::getPointerType(type), dims, name);
|
||||
|
||||
if (varDef->initVal() != nullptr) {
|
||||
ValueCounter values;
|
||||
// 这里的varDef->initVal()可能是ScalarInitValue或ArrayInitValue
|
||||
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this));
|
||||
Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
|
||||
delete root;
|
||||
if (dims.empty()) {
|
||||
builder.createStoreInst(values.getValue(0), alloca);
|
||||
} else {
|
||||
// 对于多维数组,使用memset初始化
|
||||
// 计算每个维度的大小
|
||||
// 这里的values.getNumbers()返回的是每个维度的大小
|
||||
// 这里的values.getValues()返回的是每个维度对应的值
|
||||
// 例如:对于一个二维数组,values.getNumbers()可能是[3, 4],表示3行4列
|
||||
// values.getValues()可能是[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
// 对于每个维度,使用memset将对应的值填充到数组中
|
||||
// 这里的alloca是一个指向数组的指针
|
||||
std::vector<unsigned int> & counterNumbers = values.getNumbers();
|
||||
std::vector<sysy::Value *> & counterValues = values.getValues();
|
||||
unsigned begin = 0;
|
||||
for (size_t i = 0; i < counterNumbers.size(); i++) {
|
||||
|
||||
builder.createMemsetInst(
|
||||
alloca, ConstantValue::get(static_cast<int>(begin)),
|
||||
ConstantValue::get(static_cast<int>(counterNumbers[i])),
|
||||
counterValues[i]);
|
||||
begin += counterNumbers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
module->addVariable(name, alloca);
|
||||
}
|
||||
return std::any();
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitBType(SysYParser::BTypeContext *ctx) {
|
||||
return ctx->INT() != nullptr ? Type::getIntType() : Type::getFloatType();
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitScalarInitValue(SysYParser::ScalarInitValueContext *ctx) {
|
||||
AllocaInst* alloca = std::any_cast<Value *>(visitExp(ctx->exp()));
|
||||
ArrayValueTree* result = new ArrayValueTree();
|
||||
result->setValue(alloca);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitArrayInitValue(SysYParser::ArrayInitValueContext *ctx) {
|
||||
std::vector<ArrayValueTree *> children;
|
||||
for (const auto &initVal : ctx->initVal())
|
||||
children.push_back(std::any_cast<ArrayValueTree *>(initVal->accept(this)));
|
||||
ArrayValueTree* result = new ArrayValueTree();
|
||||
result->addChildren(children);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitConstScalarInitValue(SysYParser::ConstScalarInitValueContext *ctx) {
|
||||
AllocaInst* alloca = std::any_cast<Value *>(visitConstExp(ctx->constExp()));
|
||||
ArrayValueTree* result = new ArrayValueTree();
|
||||
result->setValue(alloca);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitConstArrayInitValue(SysYParser::ConstArrayInitValueContext *ctx) {
|
||||
std::vector<ArrayValueTree *> children;
|
||||
for (const auto &constInitVal : ctx->constInitVal())
|
||||
children.push_back(std::any_cast<ArrayValueTree *>(constInitVal->accept(this)));
|
||||
ArrayValueTree* result = new ArrayValueTree();
|
||||
result->addChildren(children);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitFuncType(SysYParser::FuncTypeContext *ctx) {
|
||||
if (ctx->INT() != nullptr)
|
||||
return Type::getIntType();
|
||||
if (ctx->FLOAT() != nullptr)
|
||||
return Type::getFloatType();
|
||||
return Type::getVoidType();
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitFuncDef(SysYParser::FuncDefContext *ctx){
|
||||
// 更新作用域
|
||||
module->enterNewScope();
|
||||
|
||||
auto name = ctx->Ident()->getText();
|
||||
std::vector<Type *> paramTypes;
|
||||
std::vector<std::string> paramNames;
|
||||
std::vector<std::vector<Value *>> paramDims;
|
||||
|
||||
if (ctx->funcFParams() != nullptr) {
|
||||
auto params = ctx->funcFParams()->funcFParam();
|
||||
for (const auto ¶m : params) {
|
||||
paramTypes.push_back(std::any_cast<Type *>(visitBType(param->bType())));
|
||||
paramNames.push_back(param->Ident()->getText());
|
||||
std::vector<Value *> dims = {};
|
||||
if (param->exp() != nullptr) {
|
||||
dims.push_back(ConstantValue::get(-1)); // 第一个维度不确定
|
||||
for (const auto &exp : param->exp()) {
|
||||
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
|
||||
}
|
||||
}
|
||||
paramDims.emplace_back(dims);
|
||||
}
|
||||
}
|
||||
|
||||
Type *returnType = std::any_cast<Type *>(visitFuncType(ctx->funcType()));
|
||||
FunctionType* funcType = Type::getFunctionType(returnType, paramTypes);
|
||||
Function* function = module->createFunction(name, funcType);
|
||||
BasicBlock* entry = function->getEntryBlock();
|
||||
builder.setPosition(entry, entry->end());
|
||||
|
||||
for (size_t i = 0; i < paramTypes.size(); ++i) {
|
||||
AllocaInst* alloca = builder.createAllocaInst(Type::getPointerType(paramTypes[i]),
|
||||
paramDims[i], paramNames[i]);
|
||||
entry->insertArgument(alloca);
|
||||
module->addVariable(paramNames[i], alloca);
|
||||
}
|
||||
|
||||
for (auto item : ctx->blockStmt()->blockItem()) {
|
||||
visitBlockItem(item);
|
||||
}
|
||||
|
||||
module->leaveScope();
|
||||
|
||||
return std::any;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitBlockStmt(SysYParser::BlockStmtContext *ctx) {
|
||||
module->enterNewScope();
|
||||
for (auto item : ctx->blockItem())
|
||||
visitBlockItem(item);
|
||||
module->leaveScope();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitAssignStmt(SysYParser::AssignStmtContext *ctx) {
|
||||
auto lVal = ctx->lValue();
|
||||
std::string name = lVal->Ident()->getText();
|
||||
std::vector<Value *> dims;
|
||||
for (const auto &exp : lVal->exp()) {
|
||||
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
|
||||
}
|
||||
|
||||
User* variable = module->getVariable(name);
|
||||
Value* value = std::any_cast<Value *>(visitExp(ctx->exp()));
|
||||
PointerType* variableType =dynamic_cast<PointerType *>(variable->getType())->getBaseType();
|
||||
|
||||
// 左值右值类型不同处理
|
||||
if (variableType != value->getType()) {
|
||||
ConstantValue * constValue = dynamic_cast<ConstantValue *>(value);
|
||||
if (constValue != nullptr) {
|
||||
if (variableType == Type::getFloatType()) {
|
||||
value = ConstantValue::get(static_cast<float>(constValue->getInt()));
|
||||
} else {
|
||||
value = ConstantValue::get(static_cast<int>(constValue->getFloat()));
|
||||
}
|
||||
} else {
|
||||
if (variableType == Type::getFloatType()) {
|
||||
value = builder.createIToFInst(value);
|
||||
} else {
|
||||
value = builder.createFtoIInst(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.createStoreInst(value, variable, dims, variable->getName());
|
||||
|
||||
return std::any();
|
||||
}
|
||||
|
||||
|
||||
std::any SysYIRGenerator::visitIfStmt(SysYParser::IfStmtContext *ctx) {
|
||||
// labels string stream
|
||||
|
||||
std::stringstream labelstring;
|
||||
Function * function = builder.getBasicBlock()->getParent();
|
||||
|
||||
BasicBlock* thenBlock = new BasicBlock(function);
|
||||
BasicBlock* exitBlock = new BasicBlock(function);
|
||||
|
||||
if (ctx->stmt().size() > 1) {
|
||||
BasicBlock* elseBlock = new BasicBlock(function);
|
||||
|
||||
builder.pushTrueBlock(thenBlock);
|
||||
builder.pushFalseBlock(elseBlock);
|
||||
// 访问条件表达式
|
||||
visitCond(ctx->cond());
|
||||
builder.popTrueBlock();
|
||||
builder.popFalseBlock();
|
||||
|
||||
labelstring << "then.L" << builder.getLabelIndex();
|
||||
thenBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(thenBlock);
|
||||
builder.setPosition(thenBlock, thenBlock->end());
|
||||
|
||||
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
||||
// 如果是块语句,直接访问
|
||||
// 否则访问语句
|
||||
if (block != nullptr) {
|
||||
visitBlockStmt(block);
|
||||
} else {
|
||||
module->enterNewScope();
|
||||
ctx->stmt(0)->accept(this);
|
||||
module->leaveScope();
|
||||
}
|
||||
builder.createUncondBrInst(exitBlock, {});
|
||||
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
|
||||
|
||||
labelstring << "else.L" << builder.getLabelIndex();
|
||||
elseBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(elseBlock);
|
||||
builder.setPosition(elseBlock, elseBlock->end());
|
||||
|
||||
block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(1));
|
||||
if (block != nullptr) {
|
||||
visitBlockStmt(block);
|
||||
} else {
|
||||
module->enterNewScope();
|
||||
ctx->stmt(1)->accept(this);
|
||||
module->leaveScope();
|
||||
}
|
||||
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
|
||||
|
||||
labelstring << "exit.L" << builder.getLabelIndex();
|
||||
exitBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(exitBlock);
|
||||
builder.setPosition(exitBlock, exitBlock->end());
|
||||
|
||||
} else {
|
||||
builder.pushTrueBlock(thenBlock);
|
||||
builder.pushFalseBlock(exitBlock);
|
||||
visitCond(ctx->cond());
|
||||
builder.popTrueBlock();
|
||||
builder.popFalseBlock();
|
||||
|
||||
labelstring << "then.L" << builder.getLabelIndex();
|
||||
thenBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(thenBlock);
|
||||
builder.setPosition(thenBlock, thenBlock->end());
|
||||
|
||||
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt(0));
|
||||
if (block != nullptr) {
|
||||
visitBlockStmt(block);
|
||||
} else {
|
||||
module->enterNewScope();
|
||||
ctx->stmt(0)->accept(this);
|
||||
module->leaveScope();
|
||||
}
|
||||
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
|
||||
|
||||
labelstring << "exit.L" << builder.getLabelIndex();
|
||||
exitBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(exitBlock);
|
||||
builder.setPosition(exitBlock, exitBlock->end());
|
||||
}
|
||||
return std::any();
|
||||
}
|
||||
|
||||
std::any SysYIRGenerator::visitWhileStmt(SysYParser::WhileStmtContext *ctx) {
|
||||
|
||||
BasicBlock* curBlock = builder.getBasicBlock();
|
||||
Function* function = builder.getBasicBlock()->getParent();
|
||||
|
||||
std::stringstream labelstring;
|
||||
labelstring << "head.L" << builder.getLabelIndex();
|
||||
BasicBlock *headBlock = function->addBasicBlock(labelstring.str());
|
||||
labelstring.str("");
|
||||
|
||||
BasicBlock::conectBlocks(curBlock, headBlock);
|
||||
builder.setPosition(headBlock, headBlock->end())
|
||||
|
||||
function->addBasicBlock(condBlock);
|
||||
builder.setPosition(condBlock, condBlock->end());
|
||||
|
||||
builder.pushTrueBlock(bodyBlock);
|
||||
builder.pushFalseBlock(exitBlock);
|
||||
|
||||
visitCond(ctx->cond());
|
||||
|
||||
builder.popTrueBlock();
|
||||
builder.popFalseBlock();
|
||||
|
||||
labelstring << "body.L" << builder.getLabelIndex();
|
||||
bodyBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
function->addBasicBlock(bodyBlock);
|
||||
builder.setPosition(bodyBlock, bodyBlock->end());
|
||||
|
||||
module->enterNewScope();
|
||||
for (auto item : ctx->blockStmt()->blockItem()) {
|
||||
visitBlockItem(item);
|
||||
}
|
||||
module->leaveScope();
|
||||
|
||||
builder.createUncondBrInst(condBlock, {});
|
||||
|
||||
BasicBlock::conectBlocks(builder.getBasicBlock(), condBlock);
|
||||
|
||||
labelstring << "exit.L" << builder.getLabelIndex();
|
||||
exitBlock->setName(labelstring.str());
|
||||
labelstring.str("");
|
||||
|
||||
function->addBasicBlock(exitBlock);
|
||||
|
||||
builder.setPosition(exitBlock, exitBlock->end());
|
||||
|
||||
return std::any();
|
||||
}
|
||||
|
||||
void Utils::tree2Array(Type *type, ArrayValueTree *root,
|
||||
const std::vector<Value *> &dims, unsigned numDims,
|
||||
|
||||
Reference in New Issue
Block a user