llh21 11 months ago
parent c47d67263f
commit 8b2dd60153

@ -1,81 +1,904 @@
#include "IRBuilder.h"
using namespace std;
namespace SysYF
{
namespace IR
{
namespace IR
{
#define CONST_INT(num) ConstantInt::create(num, module)
#define CONST_FLOAT(num) ConstantFloat::create(num, module)
// You can define global variables here
// to store state
// You can define global variables here
// to store state
enum
{
INT = 0,
VOID,
STRING,
BOOL,
FLOAT
};
// store temporary value
Ptr<Value> tmp_val = nullptr;
std::vector<BasicBlock *> tmp_condbb_while;
std::vector<BasicBlock *> tmp_falsebb_while;
std::vector<BasicBlock *> tmp_truebb;
std::vector<BasicBlock *> tmp_falsebb;
std::map<SyntaxTree::Type, Ptr<Type>> type_map; // 把类型转换成类型指针
// store temporary value
Ptr<Value> tmp_val = nullptr;
vector<Ptr<Value>> init_list;
// types
Ptr<Type> VOID_T;
Ptr<Type> INT1_T;
Ptr<Type> INT32_T;
Ptr<Type> FLOAT_T;
Ptr<Type> INT32PTR_T;
Ptr<Type> FLOATPTR_T;
// types
Ptr<Type> VOID_T;
Ptr<Type> INT1_T;
Ptr<Type> INT32_T;
Ptr<Type> FLOAT_T;
Ptr<Type> INT32PTR_T;
Ptr<Type> FLOATPTR_T;
#define LVal_to_RVal(lval) \
if(lval->get_type()==INT32PTR_T || lval->get_type()==FLOATPTR_T){\
lval=builder->create_load(lval);\
}
void IRBuilder::visit(SyntaxTree::Assembly &node) {
void IRBuilder::visit(SyntaxTree::Assembly &node)
{
VOID_T = Type::get_void_type(module);
INT1_T = Type::get_int1_type(module);
INT32_T = Type::get_int32_type(module);
FLOAT_T = Type::get_float_type(module);
INT32PTR_T = Type::get_int32_ptr_type(module);
FLOATPTR_T = Type::get_float_ptr_type(module);
for (const auto &def : node.global_defs) {
// type mapping
type_map[SyntaxTree::Type::VOID] = VOID_T;
type_map[SyntaxTree::Type::BOOL] = INT1_T;
type_map[SyntaxTree::Type::INT] = INT32_T;
type_map[SyntaxTree::Type::FLOAT] = FLOAT_T;
for (const auto &def : node.global_defs)
{
def->accept(*this);
}
}
}
// You need to fill them
// You need to fill them
void IRBuilder::visit(SyntaxTree::InitVal &node) {}
void IRBuilder::visit(SyntaxTree::InitVal &node)
{
if (!node.isExp) // is not exp, values are in node.elementList
{
for (const auto &element : node.elementList)
{
element->accept(*this); // 这里是嵌套定义读取的是elementList里面的element肯能会在下一次进入的时候赋值给元素
}
}
else // is exp, values are in node.expr
{
node.expr->accept(*this); // 有可能是计算表达式,也有可能是赋值语句
LVal_to_RVal(tmp_val);
init_list.push_back(tmp_val); // 把tmp_val放到init_list里面
}
} // init values
void IRBuilder::visit(SyntaxTree::FuncDef &node) {}
void IRBuilder::visit(SyntaxTree::FuncDef &node) // 考虑一下什么时候要用scope.enter()和scope.exit()
{
auto return_type = type_map[node.ret_type];
auto func_name = node.name;
// deal with param_list
PtrVec<Type> params;
for (const auto &param : node.param_list->params)
{
if (param->array_index.empty()) // not array
{
params.push_back(type_map[param->param_type]);
}
else
{
params.push_back(type_map[param->param_type]->get_pointer_element_type()); // 这里是指针
}
}
// build function
auto Func_Type = FunctionType::create(return_type, params);
auto func = Function::create(Func_Type, func_name, module);
scope.push(func_name, func);
// deal with block
auto block = BasicBlock::create(module, "entry", func);
builder->set_insert_point(block);
scope.enter();
// read param_list
node.param_list->accept(*this);
// read body
bool is_return = false;
for (const auto &stmt : node.body->body)
{
stmt->accept(*this);
if (dynamic_cast<SyntaxTree::ReturnStmt *>(stmt.get()))
{
is_return = true;
break; // 如果有return语句就不用再往下读了
}
}
scope.exit();
// 处理一些不写返回值的情况(不会有代码不写返回值吧,不会吧不会吧)
if (!is_return)
{
switch (node.ret_type)
{
case SyntaxTree::Type::VOID:
builder->create_void_ret();
case SyntaxTree::Type::INT:
builder->create_ret(CONST_INT(0));
case SyntaxTree::Type::FLOAT:
builder->create_ret(CONST_FLOAT(0));
default:
break;
}
}
}
void IRBuilder::visit(SyntaxTree::FuncFParamList &node) {}
void IRBuilder::visit(SyntaxTree::FuncFParamList &node)
{
auto func_arg_list = module->get_functions().back()->arg_begin(); // 取出堆栈中最后一个函数的参数列表,并且指向第一个参数
for (const auto &param : node.params)
{
param->accept(*this); // 获取数据
// 处理获取的数据
if ((*func_arg_list)->get_type()->is_pointer_type()) // 如果是指针类型,传址调用
{
scope.push(param->name, *func_arg_list); // 这里是指针
}
else // 传值调用,要分配空间
{
auto alloca = builder->create_alloca((*func_arg_list)->get_type());
builder->create_store(*func_arg_list, alloca);
scope.push(param->name, alloca);
}
func_arg_list++;
}
}
void IRBuilder::visit(SyntaxTree::FuncParam &node) {}
void IRBuilder::visit(SyntaxTree::FuncParam &node)
{
auto param_name = node.name;
auto param_type = node.param_type;
auto param_value = node.array_index;
// deal with array_index
if (!node.array_index.empty()) // array
{
for (const auto &exp : param_value)
{
exp->accept(*this);
}
}
}
void IRBuilder::visit(SyntaxTree::VarDef &node) {}
void IRBuilder::visit(SyntaxTree::VarDef &node)
{
bool is_const = node.is_constant;
auto var_name = node.name;
auto var_type = type_map[node.btype];
auto is_initialized = node.is_inited;
auto length = node.array_length;
auto init_val = node.initializers;
// deal with array_length
if (length.empty()) // 说明不是数组
{
if (scope.in_global()) // 如果是全局变量
{
auto global_var = GlobalVariable::create(var_name, module, var_type, is_const, ConstantZero::create(var_type, module));
if (is_initialized)
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
builder->create_store(tmp_val, global_var);
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
scope.push(var_name, global_var);
}
else // 如果是局部变量
{
auto var = builder->create_alloca(var_type);
if (is_initialized)
{
init_val->accept(*this);
LVal_to_RVal(tmp_val);
builder->create_store(tmp_val , var);
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
scope.push(var_name, var);
}
}
else // 数组
{
auto arrayType = ArrayType::get(var_type, length.size());
void IRBuilder::visit(SyntaxTree::LVal &node) {}
if (scope.in_global()) // 如果是全局变量
{
auto global_array = GlobalVariable::create(var_name, module, arrayType, is_const, ConstantZero::create(var_type, module));
void IRBuilder::visit(SyntaxTree::AssignStmt &node) {}
if (is_initialized)
{
init_list.clear(); // 清空init_list
init_val->accept(*this); // 把init_val里面的值放到init_list里面
while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
}
// initilize
for (auto i = 0; i < static_cast<int>(init_list.size()); i++)
{
auto GEP = builder->create_gep(global_array, {CONST_INT(0), CONST_INT(i)});
builder->create_store(init_list[i], GEP);
}
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
void IRBuilder::visit(SyntaxTree::Literal &node) {}
scope.push(var_name, global_array);
}
else
{
auto array = builder->create_alloca(arrayType);
void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {}
if (is_initialized)
{
init_list.clear(); // 清空init_list
init_val->accept(*this); // 把init_val里面的值放到init_list里面
while (init_list.size() < length.size()) // 如果init_list的长度小于length的长度就把init_list其他的值补上0
{
init_list.push_back(ConstantZero::create(type_map[node.btype], module));
}
// initilize
for (int i = 0; i < static_cast<int>(init_list.size()); i++)
{
auto GEP = builder->create_gep(array, {CONST_INT(0), CONST_INT(i)});
builder->create_store(init_list[i], GEP);
}
}
else if (is_const) // 说明是const但是没有初始化
cout << "const variable must be initialized" << endl;
void IRBuilder::visit(SyntaxTree::BlockStmt &node) {}
scope.push(var_name, array);
}
}
}
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {}
void IRBuilder::visit(SyntaxTree::LVal &node)
{
auto name = node.name;
auto index = node.array_index;
auto lval = scope.find(name, false);
if (lval)
{
if (!index.empty())
{
for (const auto &exp : index)
{
exp->accept(*this);
auto tmp = tmp_val;
auto GEP = builder->create_gep(lval, {tmp});
lval = GEP;
}
}
else
{ // 从符号表中取出的是字面值
tmp_val = lval;
}
}
else
{
std::cout << "LVal pointer or literal not found" << std::endl;
}
} // lval: Identifier|Identifier LeftBracket exp RightBracket
void IRBuilder::visit(SyntaxTree::ExprStmt &node) {}
void IRBuilder::visit(SyntaxTree::AssignStmt &node)
{
node.target->accept(*this);
auto target = builder->create_load(tmp_val);//?
auto name = target->get_name();
node.value->accept(*this);//?
LVal_to_RVal(tmp_val);
auto value = tmp_val;
void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {}
builder->create_store(value, target);
}
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {}
void IRBuilder::visit(SyntaxTree::Literal &node)
{
auto type = node.literal_type;
switch (type)
{
case SyntaxTree::Type::INT:
tmp_val = CONST_INT(node.int_const);
case SyntaxTree::Type::FLOAT:
tmp_val = CONST_FLOAT(node.float_const);
default:
break;
}
} // literal: IntegerLiteral|FloatLiteral
void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {}
void IRBuilder::visit(SyntaxTree::ReturnStmt &node)
{
auto return_value = node.ret;
if (return_value != nullptr)
{
return_value->accept(*this);
LVal_to_RVal(tmp_val);
auto value_type = tmp_val->get_type();
auto ret_type = module->get_functions().back()->get_return_type();
// 类型检查
if(ret_type == INT32_T)
{
if(value_type == FLOAT_T)
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
else if(value_type == INT1_T)
tmp_val = builder->create_zext(tmp_val, INT32_T);
}
auto value = tmp_val;
builder->create_ret(value);
}
else
{
builder->create_void_ret();
}
}
void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {}
void IRBuilder::visit(SyntaxTree::BlockStmt &node)
{
scope.enter();
for (const auto &stmt : node.body)
{
stmt->accept(*this);
if (dynamic_cast<SyntaxTree::BreakStmt *>(stmt.get()) != nullptr || dynamic_cast<SyntaxTree::ContinueStmt *>(stmt.get()) != nullptr || dynamic_cast<SyntaxTree::ReturnStmt *>(stmt.get()) != nullptr)
{ // break,continue,return后面的语句不再编译
break;
}
}
scope.exit();
}
void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {}
void IRBuilder::visit(SyntaxTree::EmptyStmt &node)
{
node.accept(*this);
}
void IRBuilder::visit(SyntaxTree::IfStmt &node) {}
void IRBuilder::visit(SyntaxTree::ExprStmt &node)
{
node.exp->accept(*this);
}
void IRBuilder::visit(SyntaxTree::WhileStmt &node) {}
void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node)
{
node.rhs->accept(*this);
LVal_to_RVal(tmp_val);
auto rhs = tmp_val;
// 整数
if (rhs->get_type() == INT32_T)
{
auto UnaryCondExpr = builder->create_icmp_eq(rhs, CONST_INT(0));
scope.push("CondExpr", UnaryCondExpr);
}
else
{
auto UnaryCondExpr = builder->create_fcmp_eq(rhs, CONST_FLOAT(0));
scope.push("CondExpr", UnaryCondExpr);
}
}
void IRBuilder::visit(SyntaxTree::BreakStmt &node) {}
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node)
{
node.rhs->accept(*this);
LVal_to_RVal(tmp_val);
auto rhs = tmp_val;
auto rhs_type = rhs->get_type();
node.lhs->accept(*this);
LVal_to_RVal(tmp_val);
auto lhs = tmp_val;
auto lhs_type = lhs->get_type();
void IRBuilder::visit(SyntaxTree::ContinueStmt &node) {}
if (node.op == SyntaxTree::BinaryCondOp::LAND)
{
auto falseBB = scope.find("falseBB", 0);
auto trueBB = BasicBlock::create(module,
"trueBB_lhs", module->get_functions().back());
}
if (lhs_type == INT1_T)
{
builder->create_cond_br(lhs, trueBB, dynamic_pointer_cast<SysYF::IR::BasicBlock>(falseBB));
}
else if (lhs_type == INT32_T)
{
auto lhs_cond = builder->create_icmp_eq(lhs, CONST_INT(0));
builder->create_cond_br(lhs_cond, trueBB, dynamic_pointer_cast<SysYF::IR::BasicBlock>(falseBB));
}
else if (lhs_type == FLOAT_T)
{
auto lhs_cond = builder->create_fcmp_eq(lhs, CONST_FLOAT(0));
builder->create_cond_br(lhs_cond, trueBB, dynamic_pointer_cast<SysYF::IR::BasicBlock>(falseBB));
}
builder->set_insert_point(trueBB);
node.rhs->accept(*this);
}
else if (node.op == SyntaxTree::BinaryCondOp::LOR)
{
auto trueBB = scope.find("trueBB", 0);
auto falseBB = BasicBlock::create(module,
"falseBB_lhs", module->get_functions().back());
if (lhs_type == INT1_T)
{
builder->create_cond_br(lhs, dynamic_pointer_cast<SysYF::IR::BasicBlock>(trueBB), falseBB);
}
else if (lhs_type == INT32_T)
{
auto lhs_cond = builder->create_icmp_eq(lhs, CONST_INT(0));
builder->create_cond_br(lhs_cond, dynamic_pointer_cast<SysYF::IR::BasicBlock>(trueBB), falseBB);
}
else if (lhs_type == FLOAT_T)
{
auto lhs_cond = builder->create_fcmp_eq(lhs, CONST_FLOAT(0));
builder->create_cond_br(lhs_cond, dynamic_pointer_cast<SysYF::IR::BasicBlock>(trueBB), falseBB);
}
builder->set_insert_point(falseBB);
node.rhs->accept(*this);
}
else
{
auto expr_type = FLOAT_T;
if (lhs_type == INT1_T && rhs_type == INT32_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, INT32_T));
}
else if (lhs_type == INT1_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, FLOAT_T));
}
else if (lhs_type == INT32_T && rhs_type == INT1_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, INT32_T));
}
else if (lhs_type == FLOAT_T && rhs_type == INT1_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, FLOAT_T));
}
else if (lhs_type == FLOAT_T && rhs_type == INT32_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(rhs, FLOAT_T));
}
else if (lhs_type == INT32_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(lhs, FLOAT_T));
}
else if (lhs_type == INT1_T && rhs_type == INT1_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(lhs, INT32_T));
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_zext(rhs, INT32_T));
}
// 整数
if (rhs->get_type() == INT32_T)
{
switch (node.op)
{
case SysYF::SyntaxTree::BinaryCondOp::LT:
{
tmp_val = builder->create_icmp_lt(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::LTE:
{
tmp_val = builder->create_icmp_le(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::GT:
{
tmp_val = builder->create_icmp_gt(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::GTE:
{
tmp_val = builder->create_icmp_ge(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::EQ:
{
tmp_val = builder->create_icmp_eq(lhs, rhs);
}
default:
break;
}
}
else
{
switch (node.op)
{
case SysYF::SyntaxTree::BinaryCondOp::LT:
{
tmp_val = builder->create_fcmp_lt(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::LTE:
{
tmp_val = builder->create_fcmp_le(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::GT:
{
tmp_val = builder->create_fcmp_gt(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::GTE:
{
tmp_val = builder->create_fcmp_ge(lhs, rhs);
break;
}
case SysYF::SyntaxTree::BinaryCondOp::EQ:
{
tmp_val = builder->create_fcmp_eq(lhs, rhs);
}
default:
break;
}
}
scope.push("CondExpr", tmp_val);
}
}
void IRBuilder::visit(SyntaxTree::BinaryExpr &node)
{
// 整数
node.rhs->accept(*this);
LVal_to_RVal(tmp_val);
auto rhs = tmp_val;
auto rhs_type = rhs->get_type();
node.lhs->accept(*this);
LVal_to_RVal(tmp_val);
auto lhs = tmp_val;
auto lhs_type = lhs->get_type();
if (lhs_type == FLOAT_T && rhs_type == INT32_T)
{
rhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(rhs, FLOAT_T));
}
else if (lhs_type == INT32_T && rhs_type == FLOAT_T)
{
lhs = dynamic_pointer_cast<SysYF::IR::LoadInst>(builder->create_sitofp(lhs, FLOAT_T));
}
auto expr_type = lhs->get_type();
// 计算出可以直接计算的值
if ((dynamic_pointer_cast<ConstantFloat>(lhs) || dynamic_pointer_cast<ConstantFloat>(lhs)) && (dynamic_pointer_cast<ConstantFloat>(rhs) || dynamic_pointer_cast<ConstantFloat>(rhs)))
{ // 简单字面量计算
int lhs_int;
int rhs_int;
float lhs_float;
float rhs_float;
if (expr_type == INT32_T)
{
lhs_int = dynamic_pointer_cast<ConstantInt>(lhs)->get_value();
rhs_int = dynamic_pointer_cast<ConstantInt>(rhs)->get_value();
}
else
{
lhs_float = dynamic_pointer_cast<ConstantFloat>(lhs)->get_value();
rhs_float = dynamic_pointer_cast<ConstantFloat>(rhs)->get_value();
}
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
if (expr_type == INT32_T)
{
tmp_val = CONST_INT(lhs_int + rhs_int);
}
else
{
tmp_val = CONST_FLOAT(lhs_float + rhs_float);
}
break;
case SyntaxTree::BinOp::MINUS:
if (expr_type == INT32_T)
{
tmp_val = CONST_INT(lhs_int - rhs_int);
}
else
{
tmp_val = CONST_FLOAT(lhs_float - rhs_float);
}
break;
case SyntaxTree::BinOp::MULTIPLY:
if (expr_type == INT32_T)
{
tmp_val = CONST_INT(lhs_int * rhs_int);
}
else
{
tmp_val = CONST_FLOAT(lhs_float * rhs_float);
}
break;
case SyntaxTree::BinOp::DIVIDE:
if (expr_type == INT32_T)
{
tmp_val = CONST_INT(lhs_int / rhs_int);
}
else
{
tmp_val = CONST_FLOAT(lhs_float / rhs_float);
}
break;
case SyntaxTree::BinOp::MODULO:
if (expr_type == INT32_T)
{
tmp_val = CONST_INT(lhs_int % rhs_int);
}
else
{
tmp_val = CONST_INT(static_cast<int>(lhs_float) % static_cast<int>(rhs_float));
}
break;
}
return;
}
if (lhs_type == INT32_T)
{
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
{
builder->create_iadd(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MINUS:
{
builder->create_isub(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MULTIPLY:
{
builder->create_imul(lhs, rhs);
break;
}
case SyntaxTree::BinOp::DIVIDE:
{
builder->create_isdiv(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MODULO:
{
builder->create_isrem(lhs, rhs);
break;
}
}
}
else if (lhs_type == FLOAT_T)
{
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
{
builder->create_fadd(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MINUS:
{
builder->create_fsub(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MULTIPLY:
{
builder->create_fmul(lhs, rhs);
break;
}
case SyntaxTree::BinOp::DIVIDE:
{
builder->create_fdiv(lhs, rhs);
break;
}
case SyntaxTree::BinOp::MODULO:
{
// builder->create_isrem(static_pointer_cast<ConstantInt>(lhs), static_pointer_cast<ConstantInt>(rhs));
break;
}
}
}
}
void IRBuilder::visit(SyntaxTree::UnaryExpr &node)
{
// 整数
node.rhs->accept(*this);
LVal_to_RVal(tmp_val);
auto rhs = tmp_val;
auto rhs_type = rhs->get_type();
// 直接计算的
if (dynamic_pointer_cast<ConstantInt>(rhs) || dynamic_pointer_cast<ConstantFloat>(rhs))
{
int rhs_int;
float rhs_float;
if (rhs_type == INT32_T)
{
rhs_int = dynamic_pointer_cast<ConstantInt>(rhs)->get_value();
}
else
{
rhs_float = dynamic_pointer_cast<ConstantFloat>(rhs)->get_value();
}
switch (node.op)
{
case SyntaxTree::UnaryOp::PLUS:
if (rhs_type == INT32_T)
{
tmp_val = CONST_INT(rhs_int);
}
else
{
tmp_val = CONST_FLOAT(rhs_float);
}
break;
case SyntaxTree::UnaryOp::MINUS:
if (rhs_type == INT32_T)
{
tmp_val = CONST_INT(-rhs_int);
}
else
{
tmp_val = CONST_FLOAT(-rhs_float);
}
break;
}
return;
}
if (rhs_type == INT32_T)
{
switch (node.op)
{
case SyntaxTree::UnaryOp::PLUS:
{
builder->create_iadd(rhs, CONST_INT(0));
break;
}
case SyntaxTree::UnaryOp::MINUS:
{
builder->create_isub(CONST_INT(0), rhs);
break;
}
}
}
else if (rhs_type == FLOAT_T)
{
switch (node.op)
{
case SyntaxTree::UnaryOp::PLUS:
{
builder->create_fadd(rhs, CONST_FLOAT(0));
break;
}
case SyntaxTree::UnaryOp::MINUS:
{
builder->create_fsub(CONST_FLOAT(0), rhs);
break;
}
}
}
}
void IRBuilder::visit(SyntaxTree::FuncCallStmt &node)
{
auto func = scope.find(node.name, true);
if (func)
{
PtrVec<Value> args{};
auto arg_func = dynamic_pointer_cast<SysYF::IR::Function>(func)->arg_begin();
for (auto &arg : node.params)
{
auto arg_func_type = (*arg_func)->get_type();
arg->accept(*this);
LVal_to_RVal(tmp_val);
auto value = tmp_val;
// 数组
if (arg_func_type == INT32PTR_T || arg_func_type == FLOATPTR_T)
{
// if(value->get_type() == INT32PTR_T || value->get_type() == FLOATPTR_T){
// tmp_val = value;
// }
// else{
// tmp_val = builder->create_alloca(arg_func_type);
// builder->create_store(value, tmp_val);
// }
}
else
{
if (value->get_type() == INT32_T && arg_func_type == FLOAT_T)
{
tmp_val = builder->create_sitofp(value, FLOAT_T);
}
else if (value->get_type() == FLOAT_T && arg_func_type == INT32_T)
{
tmp_val = builder->create_fptosi(value, INT32_T);
}
}
args.push_back(tmp_val);
}
builder->create_call(func, args);
}
}
void IRBuilder::visit(SyntaxTree::IfStmt &node)
{
scope.enter();
auto trueBB = BasicBlock::create(module, "trueBB_if",
module->get_functions().back());
auto nextBB = BasicBlock::create(module, "nextBB_if",
module->get_functions().back());
scope.push("trueBB", trueBB);
scope.push("falseBB", nextBB);
node.cond_exp->accept(*this);
LVal_to_RVal(tmp_val);
auto cond = tmp_val;
builder->create_cond_br(cond, trueBB, nextBB);
builder->set_insert_point(trueBB);
node.if_statement->accept(*this);
builder->set_insert_point(nextBB);
if (node.else_statement)
{
node.else_statement->accept(*this);
}
scope.exit();
}
void IRBuilder::visit(SyntaxTree::WhileStmt &node)
{
// auto func_name = scope.find("func", 0);
scope.enter();
auto condBB = BasicBlock::create(module, "condBB_while",
module->get_functions().back());
auto trueBB = BasicBlock::create(module, "trueBB_while",
module->get_functions().back());
auto falseBB = BasicBlock::create(module, "falseBB_while",
module->get_functions().back());
scope.push("condBB", condBB);
scope.push("trueBB", trueBB);
scope.push("falseBB", falseBB);
builder->create_br(condBB);
node.cond_exp->accept(*this);
LVal_to_RVal(tmp_val);
auto cond = tmp_val;
builder->create_cond_br(cond, trueBB, falseBB);
auto cond_val = tmp_val;
scope.exit();
}
void IRBuilder::visit(SyntaxTree::BreakStmt &node)
{
node.accept(*this);
auto falseBB = scope.find("falseBB", 0);
builder->create_br(dynamic_pointer_cast<SysYF::IR::BasicBlock>(falseBB));
}
void IRBuilder::visit(SyntaxTree::ContinueStmt &node)
{
node.accept(*this);
auto condBB = scope.find("condBB", 0);
builder->create_br(dynamic_pointer_cast<SysYF::IR::BasicBlock>(condBB));
}
}
}
Loading…
Cancel
Save