更改前置声明,IR生成更新

This commit is contained in:
rain2133
2025-06-21 16:39:13 +08:00
parent ba5f2a0620
commit 3ed1c7fecd
3 changed files with 602 additions and 261 deletions

View File

@@ -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 &param : 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,