Files
mysysy/src/SysYIRGenerator.cpp
rain2133 87d38be255 [midend]更新遍静态ID定义方法,
注册遍模板函数重构(针对遍的不同构造方法),
修复phi指令更新引起的旧代码错误,
将CFG优化适配到现有终端框架中,
独立CFG优化方法使得其他优化遍能独立调用,
usedelete方法回调取消删除功能。
IRGenerator代码风格修改。
2025-07-23 17:19:11 +08:00

1412 lines
52 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SysYIRGenerator.cpp
// TODO类型转换及其检查
// TODOsysy库函数处理
// TODO数组处理
// TODO对while、continue、break的测试
#include "IR.h"
#include <any>
#include <memory>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include "SysYIRGenerator.h"
using namespace std;
namespace sysy {
Type* SysYIRGenerator::buildArrayType(Type* baseType, const std::vector<Value*>& dims){
Type* currentType = baseType;
// 从最内层维度开始构建 ArrayType
// 例如对于 int arr[2][3],先处理 [3],再处理 [2]
// 注意SysY 的 dims 是从最外层到最内层,所以我们需要反向迭代
// 或者调整逻辑,使得从内到外构建 ArrayType
// 假设 dims 列表是 [dim1, dim2, dim3...] (例如 [2, 3] for int[2][3])
// 我们需要从最内层维度开始向外构建 ArrayType
for (int i = dims.size() - 1; i >= 0; --i) {
// 维度大小必须是常量,否则无法构建 ArrayType
ConstantInteger* constDim = dynamic_cast<ConstantInteger*>(dims[i]);
if (constDim == nullptr) {
// 如果维度不是常量,可能需要特殊处理,例如将其视为指针
// 对于函数参数 int arr[] 这种,第一个维度可以为未知
// 在这里,我们假设所有声明的数组维度都是常量
assert(false && "Array dimension must be a constant integer!");
return nullptr;
}
unsigned dimSize = constDim->getInt();
currentType = Type::getArrayType(currentType, dimSize);
}
return currentType;
}
Value* SysYIRGenerator::getGEPAddressInst(Value* basePointer, const std::vector<Value*>& indices) {
// 检查 basePointer 是否为指针类型
if (!basePointer->getType()->isPointer()) {
assert(false && "GEP base pointer must be a pointer type!");
}
// 获取基指针所指向的实际类型 (例如 int* 指向 int, int[2][3]* 指向 int[2][3])
Type* currentElementType = basePointer->getType()->as<PointerType>()->getBaseType();
std::vector<Value*> actualGEPIndices;
// GEP 指令的第一个索引通常是0用于“跳过”基指针指向的聚合类型本身直接指向其第一个元素。
// 例如,对于 AllocaInst 返回的 `int[2][3]*`,第一个 `0` 索引表示从数组的开始而不是指针本身开始索引。
actualGEPIndices.push_back(ConstantInteger::get(0));
// 将用户提供的索引添加到 GEP 操作数中
for (Value* index : indices) {
actualGEPIndices.push_back(index);
}
// 根据索引链计算最终的元素类型
Type* finalTargetType = currentElementType;
// 遍历用户提供的索引不包括我们添加的第一个0逐步确定 GEP 的最终结果类型
// 每个索引都“深入”一个维度
for (int i = 0; i < indices.size(); ++i) { // 这里遍历的是用户提供的索引
if (finalTargetType && finalTargetType->isArray()) {
finalTargetType = finalTargetType->as<ArrayType>()->getElementType();
} else {
// 如果索引链还在继续,但当前类型已经不是数组或聚合类型,这通常是一个错误
// 或者表示访问的是标量后续索引无效。此时finalTargetType 已经是最终的标量类型,不能再深入。
// 例如,对 int arr[5]; 访问 arr[i][j] (j 是多余的),这里会停止类型推断。
break;
}
}
// GEP 的结果总是指针类型,指向最终计算出的元素
Type* gepResultType = Type::getPointerType(finalTargetType);
// 创建 GEP 指令。假设 builder.createGetElementPtrInst 的签名为
// (Type* resultType, Value* basePointer, const std::vector<Value*>& indices)
return builder.createGetElementPtrInst(basePointer, actualGEPIndices);
}
/*
* @brief: visit compUnit
* @details:
* compUnit: (globalDecl | funcDef)+;
*/
std::any SysYIRGenerator::visitCompUnit(SysYParser::CompUnitContext *ctx) {
// create the IR module
auto pModule = new Module();
assert(pModule);
module.reset(pModule);
// SymbolTable::ModuleScope scope(symbols_table);
Utils::initExternalFunction(pModule, &builder);
pModule->enterNewScope();
visitChildren(ctx);
pModule->leaveScope();
return pModule;
}
std::any SysYIRGenerator::visitGlobalConstDecl(SysYParser::GlobalConstDeclContext *ctx){
auto constDecl = ctx->constDecl();
Type* type = std::any_cast<Type *>(visitBType(constDecl->bType()));
for (const auto &constDef : constDecl->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 std::any();
}
std::any SysYIRGenerator::visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *ctx) {
auto varDecl = ctx->varDecl();
Type* type = std::any_cast<Type *>(visitBType(varDecl->bType()));
for (const auto &varDef : varDecl->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)));
}
}
ValueCounter values = {};
if (varDef->initVal() != nullptr) {
ArrayValueTree* root = std::any_cast<ArrayValueTree *>(varDef->initVal()->accept(this));
Utils::tree2Array(type, root, dims, dims.size(), values, &builder);
delete root;
}
// 创建全局变量,并更新符号表
module->createGlobalValue(name, Type::getPointerType(type), dims, values);
}
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)));
}
}
Type* variableType = type;
if (!dims.empty()) { // 如果有维度,说明是数组
variableType = buildArrayType(type, dims); // 构建完整的 ArrayType
}
// 对于数组alloca 的类型将是指针指向数组类型,例如 `int[2][3]*`
// 对于标量alloca 的类型将是指针指向标量类型,例如 `int*`
AllocaInst* alloca =
builder.createAllocaInst(Type::getPointerType(type), dims, name);
if (varDef->initVal() != nullptr) {
ValueCounter values;
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 { // 数组变量初始化
const std::vector<sysy::Value *> &counterValues = values.getValues();
int numElements = 1;
std::vector<int> dimSizes;
for (Value *dimVal : dims) {
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(dimVal)) {
int dimSize = constInt->getInt();
numElements *= dimSize;
dimSizes.push_back(dimSize);
}
// TODO else 错误处理:数组维度必须是常量(对于静态分配)
}
unsigned int elementSizeInBytes = type->getSize();
unsigned int totalSizeInBytes = numElements * elementSizeInBytes;
bool allValuesAreZero = false;
if (counterValues.empty()) {
allValuesAreZero = true;
}
else {
allValuesAreZero = true;
for (Value *val : counterValues){
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(val)){
if (constInt->getInt() != 0){
allValuesAreZero = false;
break;
}
}
else{
allValuesAreZero = false;
break;
}
}
}
if (allValuesAreZero) {
builder.createMemsetInst(
alloca,
ConstantInteger::get(0),
ConstantInteger::get(totalSizeInBytes),
ConstantInteger::get(0));
}
else {
for (int k = 0; k < counterValues.size(); ++k) {
std::vector<Value *> currentIndices;
int tempLinearIndex = k;
// 将线性索引转换为多维索引
for (int dimIdx = dimSizes.size() - 1; dimIdx >= 0; --dimIdx)
{
currentIndices.insert(currentIndices.begin(),
ConstantInteger::get(static_cast<int>(tempLinearIndex % dimSizes[dimIdx])));
tempLinearIndex /= dimSizes[dimIdx];
}
// 计算元素的地址
Value* elementAddress = getGEPAddressInst(alloca, currentIndices);
// 生成 store 指令 (假设 createStoreInst 接受 Value* value, Value* pointer)
builder.createStoreInst(counterValues[k], elementAddress);
}
}
}
}
else { // 如果没有显式初始化值,默认对数组进行零初始化
if (!dims.empty()) { // 只有数组才需要默认的零初始化
int numElements = 1;
for (Value *dimVal : dims) {
if (ConstantInteger *constInt = dynamic_cast<ConstantInteger *>(dimVal)) {
numElements *= constInt->getInt();
}
}
unsigned int elementSizeInBytes = type->getSize();
unsigned int totalSizeInBytes = numElements * elementSizeInBytes;
builder.createMemsetInst(
alloca,
ConstantInteger::get(0),
ConstantInteger::get(totalSizeInBytes),
ConstantInteger::get(0)
);
}
}
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) {
Value* value = std::any_cast<Value *>(visitExp(ctx->exp()));
ArrayValueTree* result = new ArrayValueTree();
result->setValue(value);
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) {
Value* value = std::any_cast<Value *>(visitConstExp(ctx->constExp()));
ArrayValueTree* result = new ArrayValueTree();
result->setValue(value);
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->LBRACK().empty()) {
dims.push_back(ConstantInteger::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()));
Type* funcType = Type::getFunctionType(returnType, paramTypes);
Function* function = module->createFunction(name, funcType);
BasicBlock* entry = function->getEntryBlock();
builder.setPosition(entry, entry->end());
for (int 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);
}
// 在处理函数体之前,创建一个新的基本块作为函数体的实际入口
// 这样 entryBB 就可以在完成初始化后跳转到这里
BasicBlock* funcBodyEntry = function->addBasicBlock("funcBodyEntry");
// 从 entryBB 无条件跳转到 funcBodyEntry
builder.createUncondBrInst(funcBodyEntry, {});
builder.setPosition(funcBodyEntry,funcBodyEntry->end()); // 将插入点设置到 funcBodyEntry
for (auto item : ctx->blockStmt()->blockItem()) {
visitBlockItem(item);
}
// 如果函数没有显式的返回语句,且返回类型不是 void则需要添加一个默认的返回值
ReturnInst* retinst = nullptr;
retinst = dynamic_cast<ReturnInst*>(builder.getBasicBlock()->terminator()->get());
if (!retinst) {
if (returnType->isVoid()) {
builder.createReturnInst();
} else if (returnType->isInt()) {
builder.createReturnInst(ConstantInteger::get(0)); // 默认返回 0
} else if (returnType->isFloat()) {
builder.createReturnInst(ConstantFloating::get(0.0f)); // 默认返回 0.0f
} else {
assert(false && "Function with no explicit return and non-void type should return a value.");
}
}
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)));
}
auto variable = module->getVariable(name); // 获取 AllocaInst 或 GlobalValue
Value* value = std::any_cast<Value *>(visitExp(ctx->exp())); // 右值
if (variable == nullptr) {
throw std::runtime_error("Variable " + name + " not found in assignment.");
}
// 计算最终赋值目标元素的类型
// variable 本身应该是一个指针类型 (例如 int* 或 int[2][3]*)
if (!variable->getType()->isPointer()) {
assert(false && "Variable to be assigned must be a pointer type!");
return std::any();
}
Type* targetElementType = variable->getType()->as<PointerType>()->getBaseType(); // 从基指针指向的类型开始
// 模拟 GEP 路径,根据 dims 确定最终元素的类型
for (int i = 0; i < dims.size(); ++i) {
if (targetElementType && targetElementType->isArray()) {
targetElementType = targetElementType->as<ArrayType>()->getElementType();
} else {
break; // 如果不是数组类型但还有索引,或者索引超出维度,则停止推断
}
}
// 左值右值类型不同处理:根据最终元素类型进行转换
if (targetElementType != value->getType()) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr) {
if (targetElementType == Type::getFloatType()) {
value = ConstantFloating::get(static_cast<float>(constValue->getInt()));
} else { // 假设如果不是浮点型,就是整型
value = ConstantInteger::get(static_cast<int>(constValue->getFloat()));
}
} else {
if (targetElementType == Type::getFloatType()) {
value = builder.createIToFInst(value);
} else { // 假设如果不是浮点型,就是整型
value = builder.createFtoIInst(value);
}
}
}
// 计算目标地址:如果 dims 为空,就是变量本身地址;否则通过 GEP 计算
Value* targetAddress = variable;
if (!dims.empty()) {
targetAddress = getGEPAddressInst(variable, dims);
}
builder.createStoreInst(value, targetAddress);
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 << "if_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 << "if_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();
}
builder.createUncondBrInst(exitBlock, {});
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
labelstring << "if_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 << "if_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 << "if_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) {
// while structure:
// curblock -> headBlock -> bodyBlock -> exitBlock
BasicBlock* curBlock = builder.getBasicBlock();
Function* function = builder.getBasicBlock()->getParent();
std::stringstream labelstring;
labelstring << "while_head.L" << builder.getLabelIndex();
BasicBlock *headBlock = function->addBasicBlock(labelstring.str());
labelstring.str("");
builder.createUncondBrInst(headBlock, {});
BasicBlock::conectBlocks(curBlock, headBlock);
builder.setPosition(headBlock, headBlock->end());
BasicBlock* bodyBlock = new BasicBlock(function);
BasicBlock* exitBlock = new BasicBlock(function);
builder.pushTrueBlock(bodyBlock);
builder.pushFalseBlock(exitBlock);
// 访问条件表达式
visitCond(ctx->cond());
builder.popTrueBlock();
builder.popFalseBlock();
labelstring << "while_body.L" << builder.getLabelIndex();
bodyBlock->setName(labelstring.str());
labelstring.str("");
function->addBasicBlock(bodyBlock);
builder.setPosition(bodyBlock, bodyBlock->end());
builder.pushBreakBlock(exitBlock);
builder.pushContinueBlock(headBlock);
auto block = dynamic_cast<SysYParser::BlockStmtContext *>(ctx->stmt());
if( block != nullptr) {
visitBlockStmt(block);
} else {
module->enterNewScope();
ctx->stmt()->accept(this);
module->leaveScope();
}
builder.createUncondBrInst(headBlock, {});
BasicBlock::conectBlocks(builder.getBasicBlock(), exitBlock);
builder.popBreakBlock();
builder.popContinueBlock();
labelstring << "while_exit.L" << builder.getLabelIndex();
exitBlock->setName(labelstring.str());
labelstring.str("");
function->addBasicBlock(exitBlock);
builder.setPosition(exitBlock, exitBlock->end());
return std::any();
}
std::any SysYIRGenerator::visitBreakStmt(SysYParser::BreakStmtContext *ctx) {
BasicBlock* breakBlock = builder.getBreakBlock();
builder.createUncondBrInst(breakBlock, {});
BasicBlock::conectBlocks(builder.getBasicBlock(), breakBlock);
return std::any();
}
std::any SysYIRGenerator::visitContinueStmt(SysYParser::ContinueStmtContext *ctx) {
BasicBlock* continueBlock = builder.getContinueBlock();
builder.createUncondBrInst(continueBlock, {});
BasicBlock::conectBlocks(builder.getBasicBlock(), continueBlock);
return std::any();
}
std::any SysYIRGenerator::visitReturnStmt(SysYParser::ReturnStmtContext *ctx) {
Value* returnValue = nullptr;
if (ctx->exp() != nullptr) {
returnValue = std::any_cast<Value *>(visitExp(ctx->exp()));
}
Type* funcType = builder.getBasicBlock()->getParent()->getReturnType();
if (funcType!= returnValue->getType() && returnValue != nullptr) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(returnValue);
if (constValue != nullptr) {
if (funcType == Type::getFloatType()) {
returnValue = ConstantInteger::get(static_cast<float>(constValue->getInt()));
} else {
returnValue = ConstantFloating::get(static_cast<int>(constValue->getFloat()));
}
} else {
if (funcType == Type::getFloatType()) {
returnValue = builder.createIToFInst(returnValue);
} else {
returnValue = builder.createFtoIInst(returnValue);
}
}
}
builder.createReturnInst(returnValue);
return std::any();
}
// SysYIRGenerator.cpp (修改部分)
std::any SysYIRGenerator::visitLValue(SysYParser::LValueContext *ctx) {
std::string name = ctx->Ident()->getText();
User* variable = module->getVariable(name);
Value* value = nullptr;
if (variable == nullptr) {
throw std::runtime_error("Variable " + name + " not found.");
}
std::vector<Value *> dims;
for (const auto &exp : ctx->exp()) {
dims.push_back(std::any_cast<Value *>(visitExp(exp)));
}
// 1. 获取变量的声明维度数量
unsigned declaredNumDims = 0;
if (AllocaInst* alloc = dynamic_cast<AllocaInst*>(variable)) {
declaredNumDims = alloc->getNumDims();
} else if (GlobalValue* glob = dynamic_cast<GlobalValue*>(variable)) {
declaredNumDims = glob->getNumDims();
} else if (ConstantVariable* constV = dynamic_cast<ConstantVariable*>(variable)) {
declaredNumDims = constV->getNumDims();
}
// 2. 处理常量变量 (ConstantVariable) 且所有索引都是常量的情况
ConstantVariable* constVar = dynamic_cast<ConstantVariable *>(variable);
if (constVar != nullptr) {
bool allIndicesConstant = true;
for (const auto &dim : dims) {
if (dynamic_cast<ConstantValue *>(dim) == nullptr) {
allIndicesConstant = false;
break;
}
}
if (allIndicesConstant) {
// 如果是常量变量且所有索引都是常量,直接通过 getByIndices 获取编译时值
// 这个方法会根据索引深度返回最终的标量值或指向子数组的指针 (作为 ConstantValue/Variable)
return constVar->getByIndices(dims);
}
}
// 3. 处理可变变量 (AllocaInst/GlobalValue) 或带非常量索引的常量变量
// 这里区分标量访问和数组元素/子数组访问
// 检查是否是访问标量变量本身没有索引且声明维度为0
if (dims.empty() && declaredNumDims == 0) {
// 对于标量变量,直接加载其值。
// variable 本身就是指向标量的指针 (e.g., int* %a)
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable)) {
value = builder.createLoadInst(variable);
} else {
// 如果走到这里且不是AllocaInst/GlobalValue但dims为空且declaredNumDims为0
// 且又不是ConstantVariable (前面已处理),则可能是错误情况。
assert(false && "Unhandled scalar variable type in LValue access.");
return static_cast<Value*>(nullptr);
}
} else {
// 访问数组元素或子数组(有索引,或变量本身是数组/多维指针)
Value* targetAddress = nullptr;
// GEP 的基指针就是变量本身(它是一个指向内存的指针)
if (dynamic_cast<AllocaInst*>(variable) || dynamic_cast<GlobalValue*>(variable) || (constVar != nullptr)) {
// 允许对 ConstantVariable (如果它代表全局数组常量) 进行 GEP
targetAddress = getGEPAddressInst(variable, dims);
} else {
// 其他情况(例如尝试对非指针类型或不支持的 LValue 进行 GEP应报错
assert(false && "LValue variable type not supported for GEP or dynamic load.");
return static_cast<Value*>(nullptr);
}
// 现在 targetAddress 持有元素或子数组的地址。
// 需要判断是加载值,还是返回子数组的地址。
// 如果提供的索引数量少于声明的维度数量,则表示访问的是子数组,返回其地址
if (dims.size() < declaredNumDims) {
value = targetAddress;
} else {
// 否则,表示访问的是最终的标量元素,加载其值
// 假设 createLoadInst 接受 Value* pointer
value = builder.createLoadInst(targetAddress);
}
}
return value;
}
std::any SysYIRGenerator::visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) {
if (ctx->exp() != nullptr)
return visitExp(ctx->exp());
if (ctx->lValue() != nullptr)
return visitLValue(ctx->lValue());
if (ctx->number() != nullptr)
return visitNumber(ctx->number());
if (ctx->string() != nullptr) {
cout << "String literal not supported in SysYIRGenerator." << endl;
}
return visitNumber(ctx->number());
}
std::any SysYIRGenerator::visitNumber(SysYParser::NumberContext *ctx) {
if (ctx->ILITERAL() != nullptr) {
int value = std::stol(ctx->ILITERAL()->getText(), nullptr, 0);
return static_cast<Value *>(ConstantInteger::get(value));
} else if (ctx->FLITERAL() != nullptr) {
float value = std::stof(ctx->FLITERAL()->getText());
return static_cast<Value *>(ConstantFloating::get(value));
}
throw std::runtime_error("Unknown number type.");
return std::any(); // 不会到达这里
}
std::any SysYIRGenerator::visitCall(SysYParser::CallContext *ctx) {
std::string funcName = ctx->Ident()->getText();
Function *function = module->getFunction(funcName);
if (function == nullptr) {
function = module->getExternalFunction(funcName);
if (function == nullptr) {
std::cout << "The function " << funcName << " no defined." << std::endl;
assert(function);
}
}
std::vector<Value *> args = {};
if (funcName == "starttime" || funcName == "stoptime") {
// 如果是starttime或stoptime函数
// TODO: 这里需要处理starttime和stoptime函数的参数
// args.emplace_back()
} else {
if (ctx->funcRParams() != nullptr) {
args = std::any_cast<std::vector<Value *>>(visitFuncRParams(ctx->funcRParams()));
}
auto params = function->getEntryBlock()->getArguments();
for (int i = 0; i < args.size(); i++) {
// 参数类型转换
if (params[i]->getType() != args[i]->getType() &&
(params[i]->getNumDims() != 0 ||
params[i]->getType()->as<PointerType>()->getBaseType() != args[i]->getType())) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(args[i]);
if (constValue != nullptr) {
if (params[i]->getType() == Type::getPointerType(Type::getFloatType())) {
args[i] = ConstantInteger::get(static_cast<float>(constValue->getInt()));
} else {
args[i] = ConstantFloating::get(static_cast<int>(constValue->getFloat()));
}
} else {
if (params[i]->getType() == Type::getPointerType(Type::getFloatType())) {
args[i] = builder.createIToFInst(args[i]);
} else {
args[i] = builder.createFtoIInst(args[i]);
}
}
}
}
}
return static_cast<Value *>(builder.createCallInst(function, args));
}
std::any SysYIRGenerator::visitUnaryExp(SysYParser::UnaryExpContext *ctx) {
if (ctx->primaryExp() != nullptr)
return visitPrimaryExp(ctx->primaryExp());
if (ctx->call() != nullptr)
return visitCall(ctx->call());
Value* value = std::any_cast<Value *>(visitUnaryExp(ctx->unaryExp()));
Value* result = value;
if (ctx->unaryOp()->SUB() != nullptr) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr) {
if (constValue->isFloat()) {
result = ConstantFloating::get(-constValue->getFloat());
} else {
result = ConstantInteger::get(-constValue->getInt());
}
} else if (value != nullptr) {
if (value->getType() == Type::getIntType()) {
result = builder.createNegInst(value);
} else {
result = builder.createFNegInst(value);
}
} else {
std::cout << "UnExp: value is nullptr." << std::endl;
assert(false);
}
} else if (ctx->unaryOp()->NOT() != nullptr) {
auto constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr) {
if (constValue->isFloat()) {
result =
ConstantFloating::get(1 - (constValue->getFloat() != 0.0F ? 1 : 0));
} else {
result = ConstantInteger::get(1 - (constValue->getInt() != 0 ? 1 : 0));
}
} else if (value != nullptr) {
if (value->getType() == Type::getIntType()) {
result = builder.createNotInst(value);
} else {
result = builder.createFNotInst(value);
}
} else {
std::cout << "UnExp: value is nullptr." << std::endl;
assert(false);
}
}
return result;
}
std::any SysYIRGenerator::visitFuncRParams(SysYParser::FuncRParamsContext *ctx) {
std::vector<Value *> params;
for (const auto &exp : ctx->exp())
params.push_back(std::any_cast<Value *>(visitExp(exp)));
return params;
}
std::any SysYIRGenerator::visitMulExp(SysYParser::MulExpContext *ctx) {
Value * result = std::any_cast<Value *>(visitUnaryExp(ctx->unaryExp(0)));
for (int i = 1; i < ctx->unaryExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
Value* operand = std::any_cast<Value *>(visitUnaryExp(ctx->unaryExp(i)));
Type* resultType = result->getType();
Type* operandType = operand->getType();
Type* floatType = Type::getFloatType();
if (resultType == floatType || operandType == floatType) {
// 如果有一个操作数是浮点数,则将两个操作数都转换为浮点数
if (operandType != floatType) {
ConstantValue * constValue = dynamic_cast<ConstantValue *>(operand);
if (constValue != nullptr)
operand = ConstantFloating::get(static_cast<float>(constValue->getInt()));
else
operand = builder.createIToFInst(operand);
} else if (resultType != floatType) {
ConstantValue* constResult = dynamic_cast<ConstantValue *>(result);
if (constResult != nullptr)
result = ConstantFloating::get(static_cast<float>(constResult->getInt()));
else
result = builder.createIToFInst(result);
}
ConstantValue* constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue* constOperand = dynamic_cast<ConstantValue *>(operand);
if (opType == SysYParser::MUL) {
if ((constOperand != nullptr) && (constResult != nullptr)) {
result = ConstantFloating::get(constResult->getFloat() *
constOperand->getFloat());
} else {
result = builder.createFMulInst(result, operand);
}
} else if (opType == SysYParser::DIV) {
if ((constOperand != nullptr) && (constResult != nullptr)) {
result = ConstantFloating::get(constResult->getFloat() /
constOperand->getFloat());
} else {
result = builder.createFDivInst(result, operand);
}
} else {
// float类型的取模操作不允许
std::cout << "MulExp: float type mod operation is not allowed." << std::endl;
assert(false);
}
} else {
ConstantValue * constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue * constOperand = dynamic_cast<ConstantValue *>(operand);
if (opType == SysYParser::MUL) {
if ((constOperand != nullptr) && (constResult != nullptr))
result = ConstantInteger::get(constResult->getInt() * constOperand->getInt());
else
result = builder.createMulInst(result, operand);
} else if (opType == SysYParser::DIV) {
if ((constOperand != nullptr) && (constResult != nullptr))
result = ConstantInteger::get(constResult->getInt() / constOperand->getInt());
else
result = builder.createDivInst(result, operand);
} else {
if ((constOperand != nullptr) && (constResult != nullptr))
result = ConstantInteger::get(constResult->getInt() % constOperand->getInt());
else
result = builder.createRemInst(result, operand);
}
}
}
return result;
}
std::any SysYIRGenerator::visitAddExp(SysYParser::AddExpContext *ctx) {
Value* result = std::any_cast<Value *>(visitMulExp(ctx->mulExp(0)));
for (int i = 1; i < ctx->mulExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
Value* operand = std::any_cast<Value *>(visitMulExp(ctx->mulExp(i)));
Type* resultType = result->getType();
Type* operandType = operand->getType();
Type* floatType = Type::getFloatType();
if (resultType == floatType || operandType == floatType) {
// 类型转换
if (operandType != floatType) {
ConstantValue * constOperand = dynamic_cast<ConstantValue *>(operand);
if (constOperand != nullptr)
operand = ConstantFloating::get(static_cast<float>(constOperand->getInt()));
else
operand = builder.createIToFInst(operand);
} else if (resultType != floatType) {
ConstantValue * constResult = dynamic_cast<ConstantValue *>(result);
if (constResult != nullptr)
result = ConstantFloating::get(static_cast<float>(constResult->getInt()));
else
result = builder.createIToFInst(result);
}
ConstantValue * constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue * constOperand = dynamic_cast<ConstantValue *>(operand);
if (opType == SysYParser::ADD) {
if ((constResult != nullptr) && (constOperand != nullptr))
result = ConstantFloating::get(constResult->getFloat() + constOperand->getFloat());
else
result = builder.createFAddInst(result, operand);
} else {
if ((constResult != nullptr) && (constOperand != nullptr))
result = ConstantFloating::get(constResult->getFloat() - constOperand->getFloat());
else
result = builder.createFSubInst(result, operand);
}
} else {
ConstantValue * constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue * constOperand = dynamic_cast<ConstantValue *>(operand);
if (opType == SysYParser::ADD) {
if ((constResult != nullptr) && (constOperand != nullptr))
result = ConstantInteger::get(constResult->getInt() + constOperand->getInt());
else
result = builder.createAddInst(result, operand);
} else {
if ((constResult != nullptr) && (constOperand != nullptr))
result = ConstantInteger::get(constResult->getInt() - constOperand->getInt());
else
result = builder.createSubInst(result, operand);
}
}
}
return result;
}
std::any SysYIRGenerator::visitRelExp(SysYParser::RelExpContext *ctx) {
Value* result = std::any_cast<Value *>(visitAddExp(ctx->addExp(0)));
for (int i = 1; i < ctx->addExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
Value* operand = std::any_cast<Value *>(visitAddExp(ctx->addExp(i)));
Type* resultType = result->getType();
Type* operandType = operand->getType();
ConstantValue* constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue* constOperand = dynamic_cast<ConstantValue *>(operand);
// 常量比较
if ((constResult != nullptr) && (constOperand != nullptr)) {
auto operand1 = constResult->isFloat() ? constResult->getFloat()
: constResult->getInt();
auto operand2 = constOperand->isFloat() ? constOperand->getFloat()
: constOperand->getInt();
if (opType == SysYParser::LT) result = ConstantInteger::get(operand1 < operand2 ? 1 : 0);
else if (opType == SysYParser::GT) result = ConstantInteger::get(operand1 > operand2 ? 1 : 0);
else if (opType == SysYParser::LE) result = ConstantInteger::get(operand1 <= operand2 ? 1 : 0);
else if (opType == SysYParser::GE) result = ConstantInteger::get(operand1 >= operand2 ? 1 : 0);
else assert(false);
} else {
Type* resultType = result->getType();
Type* operandType = operand->getType();
Type* floatType = Type::getFloatType();
// 浮点数处理
if (resultType == floatType || operandType == floatType) {
if (resultType != floatType) {
if (constResult != nullptr)
result = ConstantFloating::get(static_cast<float>(constResult->getInt()));
else
result = builder.createIToFInst(result);
}
if (operandType != floatType) {
if (constOperand != nullptr)
operand = ConstantFloating::get(static_cast<float>(constOperand->getInt()));
else
operand = builder.createIToFInst(operand);
}
if (opType == SysYParser::LT) result = builder.createFCmpLTInst(result, operand);
else if (opType == SysYParser::GT) result = builder.createFCmpGTInst(result, operand);
else if (opType == SysYParser::LE) result = builder.createFCmpLEInst(result, operand);
else if (opType == SysYParser::GE) result = builder.createFCmpGEInst(result, operand);
else assert(false);
} else {
// 整数处理
if (opType == SysYParser::LT) result = builder.createICmpLTInst(result, operand);
else if (opType == SysYParser::GT) result = builder.createICmpGTInst(result, operand);
else if (opType == SysYParser::LE) result = builder.createICmpLEInst(result, operand);
else if (opType == SysYParser::GE) result = builder.createICmpGEInst(result, operand);
else assert(false);
}
}
}
return result;
}
std::any SysYIRGenerator::visitEqExp(SysYParser::EqExpContext *ctx) {
Value * result = std::any_cast<Value *>(visitRelExp(ctx->relExp(0)));
for (int i = 1; i < ctx->relExp().size(); i++) {
auto opNode = dynamic_cast<antlr4::tree::TerminalNode*>(ctx->children[2*i-1]);
int opType = opNode->getSymbol()->getType();
Value * operand = std::any_cast<Value *>(visitRelExp(ctx->relExp(i)));
ConstantValue* constResult = dynamic_cast<ConstantValue *>(result);
ConstantValue* constOperand = dynamic_cast<ConstantValue *>(operand);
if ((constResult != nullptr) && (constOperand != nullptr)) {
auto operand1 = constResult->isFloat() ? constResult->getFloat()
: constResult->getInt();
auto operand2 = constOperand->isFloat() ? constOperand->getFloat()
: constOperand->getInt();
if (opType == SysYParser::EQ) result = ConstantInteger::get(operand1 == operand2 ? 1 : 0);
else if (opType == SysYParser::NE) result = ConstantInteger::get(operand1 != operand2 ? 1 : 0);
else assert(false);
} else {
Type* resultType = result->getType();
Type* operandType = operand->getType();
Type* floatType = Type::getFloatType();
if (resultType == floatType || operandType == floatType) {
if (resultType != floatType) {
if (constResult != nullptr)
result = ConstantFloating::get(static_cast<float>(constResult->getInt()));
else
result = builder.createIToFInst(result);
}
if (operandType != floatType) {
if (constOperand != nullptr)
operand = ConstantFloating::get(static_cast<float>(constOperand->getInt()));
else
operand = builder.createIToFInst(operand);
}
if (opType == SysYParser::EQ) result = builder.createFCmpEQInst(result, operand);
else if (opType == SysYParser::NE) result = builder.createFCmpNEInst(result, operand);
else assert(false);
} else {
if (opType == SysYParser::EQ) result = builder.createICmpEQInst(result, operand);
else if (opType == SysYParser::NE) result = builder.createICmpNEInst(result, operand);
else assert(false);
}
}
}
if (ctx->relExp().size() == 1) {
ConstantValue * constResult = dynamic_cast<ConstantValue *>(result);
// 如果只有一个关系表达式则将结果转换为0或1
if (constResult != nullptr) {
if (constResult->isFloat())
result = ConstantInteger::get(constResult->getFloat() != 0.0F ? 1 : 0);
else
result = ConstantInteger::get(constResult->getInt() != 0 ? 1 : 0);
}
}
return result;
}
std::any SysYIRGenerator::visitLAndExp(SysYParser::LAndExpContext *ctx){
std::stringstream labelstring;
BasicBlock *curBlock = builder.getBasicBlock();
Function *function = builder.getBasicBlock()->getParent();
BasicBlock *trueBlock = builder.getTrueBlock();
BasicBlock *falseBlock = builder.getFalseBlock();
auto conds = ctx->eqExp();
for (int i = 0; i < conds.size() - 1; i++) {
labelstring << "AND.L" << builder.getLabelIndex();
BasicBlock *newtrueBlock = function->addBasicBlock(labelstring.str());
labelstring.str("");
auto cond = std::any_cast<Value *>(visitEqExp(ctx->eqExp(i)));
builder.createCondBrInst(cond, newtrueBlock, falseBlock, {}, {});
BasicBlock::conectBlocks(curBlock, newtrueBlock);
BasicBlock::conectBlocks(curBlock, falseBlock);
curBlock = newtrueBlock;
builder.setPosition(curBlock, curBlock->end());
}
auto cond = std::any_cast<Value *>(visitEqExp(conds.back()));
builder.createCondBrInst(cond, trueBlock, falseBlock, {}, {});
BasicBlock::conectBlocks(curBlock, trueBlock);
BasicBlock::conectBlocks(curBlock, falseBlock);
return std::any();
}
auto SysYIRGenerator::visitLOrExp(SysYParser::LOrExpContext *ctx) -> std::any {
std::stringstream labelstring;
BasicBlock *curBlock = builder.getBasicBlock();
Function *function = curBlock->getParent();
auto conds = ctx->lAndExp();
for (int i = 0; i < conds.size() - 1; i++) {
labelstring << "OR.L" << builder.getLabelIndex();
BasicBlock *newFalseBlock = function->addBasicBlock(labelstring.str());
labelstring.str("");
builder.pushFalseBlock(newFalseBlock);
visitLAndExp(ctx->lAndExp(i));
builder.popFalseBlock();
builder.setPosition(newFalseBlock, newFalseBlock->end());
}
visitLAndExp(conds.back());
return std::any();
}
void Utils::tree2Array(Type *type, ArrayValueTree *root,
const std::vector<Value *> &dims, unsigned numDims,
ValueCounter &result, IRBuilder *builder) {
Value* value = root->getValue();
auto &children = root->getChildren();
// 类型转换
if (value != nullptr) {
if (type == value->getType()) {
result.push_back(value);
} else {
if (type == Type::getFloatType()) {
ConstantValue* constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr)
result.push_back(ConstantFloating::get(static_cast<float>(constValue->getInt())));
else
result.push_back(builder->createIToFInst(value));
} else {
ConstantValue* constValue = dynamic_cast<ConstantValue *>(value);
if (constValue != nullptr)
result.push_back(ConstantInteger::get(static_cast<int>(constValue->getFloat())));
else
result.push_back(builder->createFtoIInst(value));
}
}
return;
}
auto beforeSize = result.size();
for (const auto &child : children) {
int begin = result.size();
int newNumDims = 0;
for (unsigned i = 0; i < numDims - 1; i++) {
auto dim = dynamic_cast<ConstantValue *>(*(dims.rbegin() + i))->getInt();
if (begin % dim == 0) {
newNumDims += 1;
begin /= dim;
} else {
break;
}
}
tree2Array(type, child.get(), dims, newNumDims, result, builder);
}
auto afterSize = result.size();
int blockSize = 1;
for (unsigned i = 0; i < numDims; i++) {
blockSize *= dynamic_cast<ConstantValue *>(*(dims.rbegin() + i))->getInt();
}
int num = blockSize - afterSize + beforeSize;
if (num > 0) {
if (type == Type::getFloatType())
result.push_back(ConstantFloating::get(0.0F), num);
else
result.push_back(ConstantInteger::get(0), num);
}
}
void Utils::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) {
auto funcType = Type::getFunctionType(returnType, paramTypes);
auto function = pModule->createExternalFunction(funcName, funcType);
auto entry = function->getEntryBlock();
pBuilder->setPosition(entry, entry->end());
for (int i = 0; i < paramTypes.size(); ++i) {
auto alloca = pBuilder->createAllocaInst(
Type::getPointerType(paramTypes[i]), paramDims[i], paramNames[i]);
entry->insertArgument(alloca);
// pModule->addVariable(paramNames[i], alloca);
}
}
void Utils::initExternalFunction(Module *pModule, IRBuilder *pBuilder) {
std::vector<Type *> paramTypes;
std::vector<std::string> paramNames;
std::vector<std::vector<Value *>> paramDims;
Type *returnType;
std::string funcName;
returnType = Type::getIntType();
funcName = "getint";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
funcName = "getch";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.push_back(Type::getIntType());
paramNames.emplace_back("x");
paramDims.push_back(std::vector<Value *>{ConstantInteger::get(-1)});
funcName = "getarray";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
returnType = Type::getFloatType();
paramTypes.clear();
paramNames.clear();
paramDims.clear();
funcName = "getfloat";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
returnType = Type::getIntType();
paramTypes.push_back(Type::getFloatType());
paramNames.emplace_back("x");
paramDims.push_back(std::vector<Value *>{ConstantInteger::get(-1)});
funcName = "getfarray";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
returnType = Type::getVoidType();
paramTypes.clear();
paramTypes.push_back(Type::getIntType());
paramDims.clear();
paramDims.emplace_back();
funcName = "putint";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
funcName = "putch";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.clear();
paramTypes.push_back(Type::getIntType());
paramTypes.push_back(Type::getIntType());
paramDims.clear();
paramDims.emplace_back();
paramDims.push_back(std::vector<Value *>{ConstantInteger::get(-1)});
paramNames.clear();
paramNames.emplace_back("n");
paramNames.emplace_back("a");
funcName = "putarray";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.clear();
paramTypes.push_back(Type::getFloatType());
paramDims.clear();
paramDims.emplace_back();
paramNames.clear();
paramNames.emplace_back("a");
funcName = "putfloat";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.clear();
paramTypes.push_back(Type::getIntType());
paramTypes.push_back(Type::getFloatType());
paramDims.clear();
paramDims.emplace_back();
paramDims.push_back(std::vector<Value *>{ConstantInteger::get(-1)});
paramNames.clear();
paramNames.emplace_back("n");
paramNames.emplace_back("a");
funcName = "putfarray";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.clear();
paramTypes.push_back(Type::getIntType());
paramDims.clear();
paramDims.emplace_back();
paramNames.clear();
paramNames.emplace_back("__LINE__");
funcName = "starttime";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
paramTypes.clear();
paramTypes.push_back(Type::getIntType());
paramDims.clear();
paramDims.emplace_back();
paramNames.clear();
paramNames.emplace_back("__LINE__");
funcName = "stoptime";
Utils::createExternalFunction(paramTypes, paramNames, paramDims, returnType,
funcName, pModule, pBuilder);
}
} // namespace sysy