You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1625 lines
72 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "IRBuilder.h"
#include <iostream>
#include <assert.h>
#include <vector>
#define DEBUG
#ifdef DEBUG
#define DBGLOG(text) std::cout << text << std::endl
#define DEBUG_OUTPUT ;
#endif
#ifndef DEBUG
#define DBGLOG(text)
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl
#endif
namespace SysYF
{
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
typedef struct
{
bool is_int;
int ival;
float fval;
} Oprand;
Oprand expr_cal_result; // 便于全局变量中表达式计算值中转
std::vector<Oprand> multi_arr_init;
class GlobalConst
{
public:
GlobalConst() {}
~GlobalConst() = default;
void add_int_const(std::string name, int val)
{
if (iconst_map.find(name) == iconst_map.end())
{ // 新加入的不是数组元素
std::vector<int> temp(1, val);
iconst_map.insert(std::make_pair(name, temp));
}
else // 新加入的是数组元素
iconst_map[name].push_back(val);
}
void add_float_const(std::string name, float val)
{
if (fconst_map.find(name) == fconst_map.end())
{ // 新加入的不是数组元素
std::vector<float> temp(1, val);
fconst_map.insert(std::make_pair(name, temp));
}
else // 新加入的是数组元素
fconst_map[name].push_back(val);
}
bool get_int_const(std::string name, int offset, int &val) // 若非数组则offset=0
{
if (iconst_map.find(name) != iconst_map.end())
{
val = iconst_map[name][offset];
return true;
}
else
return false;
}
bool get_float_const(std::string name, int offset, float &val)
{
if (fconst_map.find(name) != fconst_map.end())
{
val = fconst_map[name][offset];
return true;
}
else
return false;
}
private:
std::map<std::string, std::vector<int>> iconst_map;
std::map<std::string, std::vector<float>> fconst_map;
};
GlobalConst _const_table = GlobalConst();
std::vector<SysYF::Ptr<Type>> FuncParas;
SysYF::Ptr<Type> Para;
std::string name_;
std::vector<std::string> names;
int Ifnum = 0;
int ReturnNum = 0;
Ptr<AllocaInst> retAlloca;
SysYF::Ptr<SysYF::IR::BasicBlock> retbb;
/* enum Condtype
{
equal,
greater,
less,
ge,
le,
notequal
}condtype_; */
/* SysYF::Ptr<SysYF::IR::CmpInst> _cmp; */
// store temporary value
Ptr<Value> tmp_val = nullptr; // 存储需要全局处理的expr node
Ptr<Value> lhs_addr = nullptr;
Ptr<Function> func_parent; // 便于在创建新的bb时获得对应的func_parent
int bb_label_num = 0; // 全局控制bb标签编号
bool func_first_bb; // 处理一个func域里有多个{}只创建一个scope
PtrVec<BasicBlock> break_point;
PtrVec<BasicBlock> continue_point; // 维护两个vector(栈)控制循环break和continue应跳转到的目标地址
// 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;
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)
{
def->accept(*this);
}
}
// You need to fill them
void IRBuilder::visit(SyntaxTree::InitVal &node)
{
/* DBGLOG("Begin of Initval"); */
// 可能有一个或多个value需要初始化elementList方便迭代accept
if (node.isExp)
{
node.expr->accept(*this);
multi_arr_init.push_back(expr_cal_result);
}
else
{
for (auto item : node.elementList)
{
item->accept(*this);
}
}
/* DBGLOG("End of Initval"); */
}
void IRBuilder::visit(SyntaxTree::FuncDef &node)
{
/* DBGLOG("Begin of FuncDef"); */
Ptr<Type> RetType;
switch (node.ret_type)
{
case SysYF::SyntaxTree::Type::VOID:
RetType = VOID_T;
break;
case SysYF::SyntaxTree::Type::INT:
RetType = INT32_T;
break;
case SysYF::SyntaxTree::Type::FLOAT:
RetType = FLOAT_T;
break;
default:
break;
}
node.param_list->accept(*this);
auto FuncTY = FunctionType::create(RetType, FuncParas);
auto Func = Function::create(FuncTY, node.name, module);
func_parent = Func; // 标记当前func_parent便于后续bb调用
scope.push(node.name, Func);
scope.enter();
auto bb = BasicBlock::create(module, node.name + "_entry", Func);
builder->set_insert_point(bb);
func_first_bb = true; // 设置为第一次进入该func的bb{}
ReturnNum = 0;
if (RetType != VOID_T)
{
retAlloca = builder->create_alloca(RetType);
if (RetType == INT32_T)
builder->create_store(CONST_INT(0), retAlloca);
else if (RetType == FLOAT_T)
builder->create_store(CONST_FLOAT(0), retAlloca);
}
std::vector<SysYF::Ptr<Value>> args;
for (auto arg = Func->arg_begin(); arg != Func->arg_end(); arg++)
{
args.push_back(*arg);
}
for (size_t i = 0; i < names.size(); i++)
{
auto pAlloca = builder->create_alloca(FuncParas[i]);
builder->create_store(args[i], pAlloca);
scope.push(names[i], pAlloca);
}
retbb = BasicBlock::create(module, node.name + "_ret", Func);
node.body->accept(*this);
if (!builder->get_insert_block()->get_terminator())
builder->create_br(retbb);
builder->set_insert_point(retbb);
if (RetType == VOID_T)
{
builder->create_void_ret();
}
else
{
auto retLoad = builder->create_load(retAlloca);
builder->create_ret(retLoad);
}
/* builder->create_br(retbb); */
/* scope.exit(); */
/* DBGLOG("End of FuncDef"); */
}
void IRBuilder::visit(SyntaxTree::FuncFParamList &node)
{
FuncParas.clear();
names.clear();
for (auto &p : node.params)
{
p->accept(*this);
FuncParas.push_back(Para);
names.push_back(name_);
}
assert(FuncParas.size() == names.size());
}
void IRBuilder::visit(SyntaxTree::FuncParam &node)
{
name_ = node.name;
if (node.array_index.size())
{
// 数组
if (node.param_type == SysYF::SyntaxTree::Type::INT)
Para = INT32PTR_T;
else if (node.param_type == SysYF::SyntaxTree::Type::FLOAT)
Para = FLOATPTR_T;
}
else
{
// 非数组
if (node.param_type == SysYF::SyntaxTree::Type::INT)
Para = INT32_T;
else if (node.param_type == SysYF::SyntaxTree::Type::FLOAT)
Para = FLOAT_T;
}
}
void IRBuilder::visit(SyntaxTree::VarDef &node)
{
/* DBGLOG("Begin of VarDef"); */
// 变量定义判断是否是全局变量判断是否是const判断是否是数组类型
// 获取变量类型和变量名字,分配变量存储空间,若有需要初始化变量
Ptr<Type> vartype;
if (node.btype == SyntaxTree::Type::INT)
vartype = INT32_T;
else
vartype = FLOAT_T;
// if分级判断逻辑全局or局部->数组or单变量->const of 非const本次实验不涉及局部数组常量)->初始化or未初始化
if (scope.in_global()) // 全局变量
{
if (!node.array_length.empty()) // 数组类型
{
// 目前只考虑一维数组多维数组需要处理vector类型的array_length得到各维度长度
std::vector<int> arr_len;
unsigned total_ = 1;
for (int i = 0; i < node.array_length.size(); i++)
{
node.array_length[i]->accept(*this);
arr_len.push_back(expr_cal_result.ival);
total_ *= expr_cal_result.ival;
}
Ptr<ArrayType> arr_type = ArrayType::create(vartype, total_);
if (node.is_inited)
{
PtrVec<Constant> init_val; // 待push_back,多维转线性排列
int last_dim = arr_len.back();
int line_idx = 0;
for (auto val : node.initializers->elementList) // 每一个val都是一个InitVal可能是expr也可能是elementlist
{
multi_arr_init.clear();
val->accept(*this);
for (int i = 0; i < multi_arr_init.size(); i++)
{
Oprand tmp = multi_arr_init[i];
if (vartype == INT32_T)
{
int temp = (tmp.is_int) ? tmp.ival : int(tmp.fval);
init_val.push_back(std::static_pointer_cast<Constant>(CONST_INT(temp)));
if (node.is_constant)
_const_table.add_int_const(node.name, temp);
}
else if (vartype == FLOAT_T)
{
float temp = (tmp.is_int) ? float(tmp.ival) : tmp.fval;
init_val.push_back(std::static_pointer_cast<Constant>(CONST_FLOAT(temp)));
if (node.is_constant)
_const_table.add_float_const(node.name, temp);
}
}
}
// 全局变量剩余部分初始化为0
for (int i = init_val.size(); i < arr_len; i++)
{
if (vartype == INT32_T)
{
init_val.push_back(std::static_pointer_cast<Constant>(CONST_INT(0)));
if (node.is_constant)
_const_table.add_int_const(node.name, 0);
}
else if (vartype == FLOAT_T)
{
init_val.push_back(std::static_pointer_cast<Constant>(CONST_FLOAT(0)));
if (node.is_constant)
_const_table.add_float_const(node.name, 0.0f);
}
}
auto initializer = ConstantArray::create(arr_type, init_val);
auto Global_array = GlobalVariable::create(node.name, module, arr_type, node.is_constant, std::static_pointer_cast<Constant>(initializer));
scope.push(node.name, Global_array);
}
else // 未显式初始化全为0
{
if (node.is_constant)
{
for (int i = 0; i < arr_len; i++)
{
if (vartype == INT32_T)
_const_table.add_int_const(node.name, 0);
else
_const_table.add_float_const(node.name, 0.0f);
}
}
auto initializer = ConstantZero::create(arr_type, module);
auto Global_array = GlobalVariable::create(node.name, module, arr_type, node.is_constant, std::static_pointer_cast<Constant>(initializer));
scope.push(node.name, Global_array);
}
}
else // 单变量
{
if (node.is_inited)
{ // 只能是Ptr<Expr>类型
node.initializers->expr->accept(*this);
Ptr<Constant> init_val;
if (vartype == INT32_T)
{
int temp = (expr_cal_result.is_int) ? expr_cal_result.ival : int(expr_cal_result.fval);
init_val = std::static_pointer_cast<Constant>(CONST_INT(temp));
if (node.is_constant)
_const_table.add_int_const(node.name, temp);
}
else if (vartype == FLOAT_T)
{
float temp = (expr_cal_result.is_int) ? float(expr_cal_result.ival) : expr_cal_result.fval;
init_val = std::static_pointer_cast<Constant>(CONST_FLOAT(temp));
if (node.is_constant)
_const_table.add_float_const(node.name, temp);
}
auto Global_val = GlobalVariable::create(node.name, module, vartype, node.is_constant, init_val);
scope.push(node.name, Global_val);
}
else
{
if (node.is_constant)
{
if (vartype == INT32_T)
_const_table.add_int_const(node.name, 0);
else
_const_table.add_float_const(node.name, 0.0f);
}
auto init_val = ConstantZero::create(vartype, module);
auto Global_val = GlobalVariable::create(node.name, module, vartype, node.is_constant, std::static_pointer_cast<Constant>(init_val));
scope.push(node.name, Global_val);
}
}
}
else // 局部变量
{
if (!node.array_length.empty()) // 数组类型(不考虑const数组)
{
node.array_length[0]->accept(*this);
int arr_len = expr_cal_result.ival;
/* DBGLOG(arr_len); */
Ptr<ArrayType> arr_type = ArrayType::get(vartype, arr_len);
/* Ptr<PointerType> arr_type = PointerType::get(vartype); */
auto arr_val_alloca = builder->create_alloca(arr_type);
if (node.is_inited) // 若未显式初始化,则初始值未知
{
/* DBGLOG(node.initializers->elementList.size()); */
int arrIdx = 0; // gep类指令计算每个元素地址
for (auto val : node.initializers->elementList)
{
val->expr->accept(*this);
// 此时的类型转换IR指令为显式的
if (tmp_val->get_type() != vartype) // tmp_val为Ptr<Value>类型便于生成类型转换IR
{
if (vartype == INT32_T)
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
else
tmp_val = builder->create_sitofp(tmp_val, FLOAT_T);
}
// 根据初始化值store到对应的gep地址中
auto val_addr = builder->create_gep(arr_val_alloca, {CONST_INT(0), CONST_INT(arrIdx)});
builder->create_store(tmp_val, val_addr);
arrIdx++;
}
}
scope.push(node.name, arr_val_alloca);
}
else // 单变量, tmp_val便于发射类型转换irexpr_cal_result便于维护常量表
{
auto var_alloca = builder->create_alloca(vartype);
if (node.is_inited)
{
node.initializers->expr->accept(*this);
if (tmp_val->get_type() != vartype)
{
if (vartype == INT32_T)
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
else
tmp_val = builder->create_sitofp(tmp_val, FLOAT_T);
}
if (node.is_constant)
{
if (vartype == INT32_T)
{
int temp = (expr_cal_result.is_int) ? expr_cal_result.ival : int(expr_cal_result.fval);
_const_table.add_int_const(node.name, temp);
}
else
{
float temp = (expr_cal_result.is_int) ? float(expr_cal_result.ival) : expr_cal_result.fval;
_const_table.add_float_const(node.name, temp);
}
}
builder->create_store(tmp_val, var_alloca);
}
scope.push(node.name, var_alloca);
}
}
/* DBGLOG("End of VarDef"); */
}
void IRBuilder::visit(SyntaxTree::LVal &node)
{
/* DBGLOG("Begin of LVal"); */
/* DBGLOG(node.name); */
if (scope.in_global()) // 在全局变量初始化时InitVal 中的初始值为 Exp时可以引用左值变量
{
/* DBGLOG("Begin of LVal if"); */
int tmp1;
float tmp2;
int offset = 0;
if (!node.array_index.empty())
{
// 暂时只考虑一维数组
node.array_index[0]->accept(*this);
offset = expr_cal_result.ival;
}
if (_const_table.get_int_const(node.name, offset, tmp1))
{
expr_cal_result.is_int = true;
expr_cal_result.ival = tmp1;
}
else if (_const_table.get_float_const(node.name, offset, tmp2))
{
expr_cal_result.is_int = false;
expr_cal_result.fval = tmp2;
}
}
else // 并非处于全局域左值为被赋值对象store)或赋值对象(load)(函数调用的情形在funcall里处理)
{
/* DBGLOG("Begin of LVal else"); */
auto lval_addr = scope.find(node.name, false);
bool IsArray = false;
if (!node.array_index.empty()) // 数组左值, 需要先发射gep指令再发射load指令
{
/* DBGLOG("array"); */
node.array_index[0]->accept(*this);
assert(lval_addr != nullptr);
/* DBGLOG(node.name);
DBGLOG(lval_addr->get_type()->get_type_id()); */
// DEBUG_OUTPUT;
if (lval_addr->get_type()->get_pointer_element_type()->is_array_type()) // 左值非指针
{
/* DBGLOG("In LVal array"); */ // a[4]
auto lval = builder->create_gep(lval_addr, {CONST_INT(0), tmp_val});
lhs_addr = lval;
tmp_val = builder->create_load(lval);
IsArray = true;
}
else // 左值是指针
{ //(*a)[4]
auto ptr = builder->create_load(lval_addr);
auto lval = builder->create_gep(ptr, {tmp_val}); // 没有CONST_INT(0)基址是ptr
lhs_addr = lval;
tmp_val = builder->create_load(lval);
}
}
else if (lval_addr->get_type()->get_pointer_element_type()->is_pointer_type())
{ //*a
tmp_val = builder->create_load(lval_addr); // load得到的是指针值
lhs_addr = lval_addr;
}
else
{ // a
tmp_val = builder->create_load(lval_addr);
lhs_addr = lval_addr;
}
}
/* DBGLOG("End of LVal"); */
}
void IRBuilder::visit(SyntaxTree::AssignStmt &node)
{
/* DBGLOG("Begin of Assign");
*/
/* DBGLOG(node.target->name); */
node.target->accept(*this);
auto lhs = tmp_val;
auto lhs_addr_ = lhs_addr;
node.value->accept(*this);
auto rhs = tmp_val;
auto lhstype = lhs->get_type(); // 获左值类型
/* DBGLOG(lhstype->get_type_id()); */
auto rhstype = rhs->get_type();
/* DBGLOG(rhstype->get_type_id()); */
// 检查是否需要显式类型转换和符号扩展ir指令
if (rhstype == INT1_T)
{
rhs = builder->create_zext(rhs, INT32_T);
rhstype = INT32_T;
}
if (lhstype != rhstype)
{
if (lhstype == INT32_T)
rhs = builder->create_fptosi(rhs, INT32_T);
else
{
/* DBGLOG("create "); */
rhs = builder->create_sitofp(rhs, FLOAT_T);
}
}
builder->create_store(rhs, lhs_addr_);
/* DBGLOG("End of Assign"); */
}
void IRBuilder::visit(SyntaxTree::Literal &node)
{
/* DBGLOG("Begin of Literal"); */
if (node.literal_type == SyntaxTree::Type::INT)
{
tmp_val = CONST_INT(node.int_const);
expr_cal_result.is_int = true;
expr_cal_result.ival = node.int_const;
}
else if (node.literal_type == SyntaxTree::Type::FLOAT)
{
tmp_val = CONST_FLOAT(node.float_const);
expr_cal_result.is_int = false;
expr_cal_result.fval = node.float_const;
}
else
{
// DBGLOG("error at literal");
}
/* DBGLOG("End of Literal"); */
}
void IRBuilder::visit(SyntaxTree::ReturnStmt &node)
{
/* DBGLOG("Begin of Return"); */
auto RetType = builder->get_insert_block()->get_parent()->get_return_type();
/* auto funName = builder->get_insert_block()->get_parent()->get_name();
char num_[10];
sprintf(num_, "%d", ReturnNum++); */
/* retbb = BasicBlock::create(module, funName + "_ret_" + num_, func_parent);
*/
if (!RetType->is_void_type())
{
node.ret->accept(*this);
auto tmpType = tmp_val->get_type();
/* builder->create_br(retbb);
builder->set_insert_point(retbb); */
if (tmpType != RetType)
{
if (RetType == FLOAT_T)
{
if (tmpType == INT1_T)
// INT1 to INT32
tmp_val = builder->create_zext(tmp_val, INT32_T);
// INT32 to FLOAT
tmp_val = builder->create_sitofp(tmp_val, FLOAT_T);
}
else if (RetType == INT32_T)
{
// INT1 to INT32
if (tmpType == INT1_T)
tmp_val = builder->create_zext(tmp_val, INT32_T);
else if (tmpType == FLOAT_T)
// FLOAT to INT32
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
}
}
builder->create_store(tmp_val, retAlloca);
}
builder->create_br(retbb);
/* DBGLOG("End of Return"); */
}
void IRBuilder::visit(SyntaxTree::BlockStmt &node)
{
if (func_first_bb == true)
func_first_bb = false; // 后续不是firstbb
else
scope.enter();
for (auto stmt : node.body)
{
stmt->accept(*this);
}
scope.exit();
}
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {}
void IRBuilder::visit(SyntaxTree::ExprStmt &node)
{
node.exp->accept(*this);
}
void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node)
{
// 返回icmp或/fcmp与0相比的结果到全局变量tmp_val,发射对应ir指令
node.rhs->accept(*this);
auto rhs = tmp_val;
auto rhstype = rhs->get_type();
if (node.op == SyntaxTree::UnaryCondOp::NOT) // 只有!非号需要处理否则不形成UnaryCondExpr结点
{
if (rhstype->is_integer_type()) // 整型分1bit和32bit
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_eq(CONST_INT(0), zext);
}
else
tmp_val = builder->create_icmp_eq(CONST_INT(0), rhs);
}
else if (rhstype->is_float_type())
tmp_val = builder->create_fcmp_eq(CONST_FLOAT(0), rhs);
else // rhs是指针类型
tmp_val = CONST_INT(true); // true 则为非零值
}
}
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node)
{
Ptr<Value> lhs, rhs;
Ptr<Type> lhstype, rhstype;
if ((node.op != SyntaxTree::BinaryCondOp::LAND) && (node.op != SyntaxTree::BinaryCondOp::LOR))
{
node.lhs->accept(*this);
lhs = tmp_val;
lhstype = lhs->get_type();
node.rhs->accept(*this);
rhs = tmp_val;
rhstype = rhs->get_type();
}
switch (node.op)
{
case SyntaxTree::BinaryCondOp::LT:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_lt(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_lt(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_lt(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_lt(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::LTE:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_le(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_le(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_le(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_le(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::GT:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_gt(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_gt(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_gt(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_gt(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::GTE:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_ge(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_ge(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_ge(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_ge(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::EQ:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_eq(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_eq(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_eq(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_eq(lhs, rhs);
}
break;
case SyntaxTree::BinaryCondOp::NEQ:
if (lhstype->is_float_type() && rhstype->is_float_type())
{
tmp_val = builder->create_fcmp_ne(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_icmp_ne(lhs, rhs);
}
else if (lhstype->is_float_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
rhs = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fcmp_ne(lhs, rhs);
}
else if (rhstype->is_float_type())
{
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
lhs = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fcmp_ne(lhs, rhs);
}
break;
// 非常关键的控制流语句br(逻辑与/或)
case SyntaxTree::BinaryCondOp::LAND:
// lhs和rhs都应该是INT1_T
{
auto parent = func_parent;
char labelname[20];
sprintf(labelname, "true_bb_%d", bb_label_num++); // lhs&&rhs为true进入执行体
auto true_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "false_bb_%d", bb_label_num++); // lhs为false应该就是after cond bb吧也可能进入下一个cond bb
auto false_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "next_bb_%d", bb_label_num++); // rhs判断域
auto next_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "after_bb_%d", bb_label_num++); //
auto after_bb = BasicBlock::create(module, labelname, parent);
auto result = builder->create_alloca(INT1_T);
node.lhs->accept(*this);
lhs = tmp_val;
lhstype = lhs->get_type();
if (Type::is_eq_type(lhstype, INT1_T))
{
builder->create_cond_br(lhs, next_bb, false_bb); // if true直接跳转到nextbb(rhs判断的bb)否则跳转到falsebb
}
else if (Type::is_eq_type(lhstype, INT32_T))
{
tmp_val = builder->create_icmp_ne(lhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(lhs, next_bb, false_bb);
}
else if (Type::is_eq_type(lhstype, FLOAT_T))
{
tmp_val = builder->create_fcmp_ne(lhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, next_bb, false_bb);
}
else // 为无条件跳转
{
builder->create_br(next_bb);
}
builder->set_insert_point(next_bb); // rhs判断域
node.rhs->accept(*this);
rhs = tmp_val;
rhstype = rhs->get_type();
if (Type::is_eq_type(rhstype, INT1_T))
{
builder->create_cond_br(rhs, true_bb, false_bb); // if true直接跳转到truebb否则跳转到falsebb
}
else if (Type::is_eq_type(rhstype, INT32_T))
{
tmp_val = builder->create_icmp_ne(rhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(rhs, true_bb, false_bb);
}
else if (Type::is_eq_type(rhstype, FLOAT_T))
{
tmp_val = builder->create_fcmp_ne(rhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, true_bb, false_bb);
}
else // 为无条件跳转
{
builder->create_br(true_bb);
}
builder->set_insert_point(true_bb); // cond_bb判断域结束进入true_bb执行体内部
builder->create_store(CONST_INT(true), result);
builder->create_br(after_bb);
builder->set_insert_point(false_bb);
builder->create_store(CONST_INT(false), result);
builder->create_br(after_bb);
// true_bb和false_bb IR结束后都要无条件br到after_bb
builder->set_insert_point(after_bb);
tmp_val = builder->create_load(result);
break;
}
case SyntaxTree::BinaryCondOp::LOR:
// lhs和rhs都应该是INT1_T, 与LAND稍有区别使用短路计算
auto parent = func_parent;
char labelname[20];
sprintf(labelname, "ture_bb_%d", bb_label_num++); // lhs&&rhs为true进入执行体
auto true_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "false_bb_%d", bb_label_num++); // lhs为false应该就是after cond bb吧也可能进入下一个cond bb
auto false_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "next_bb_%d", bb_label_num++); // rhs判断域
auto next_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "after_bb_%d", bb_label_num++); //
auto after_bb = BasicBlock::create(module, labelname, parent);
auto result = builder->create_alloca(INT1_T);
node.lhs->accept(*this);
lhs = tmp_val;
lhstype = lhs->get_type();
if (Type::is_eq_type(lhstype, INT1_T))
{
builder->create_cond_br(lhs, true_bb, next_bb); // if true直接跳转到turebb执行体内否则跳转到nextbb(rhs判断域)
}
else if (Type::is_eq_type(lhstype, INT32_T))
{
tmp_val = builder->create_icmp_ne(lhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, true_bb, next_bb);
}
else if (Type::is_eq_type(lhstype, FLOAT_T))
{
tmp_val = builder->create_fcmp_ne(lhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, true_bb, next_bb);
}
else // 为无条件跳转
{
builder->create_br(true_bb);
}
builder->set_insert_point(next_bb); // rhs判断域
node.rhs->accept(*this);
rhs = tmp_val;
rhstype = rhs->get_type();
if (Type::is_eq_type(rhstype, INT1_T))
{
builder->create_cond_br(rhs, true_bb, false_bb); // if true直接跳转到truebb否则跳转到falsebb
}
else if (Type::is_eq_type(rhstype, INT32_T))
{
tmp_val = builder->create_icmp_ne(rhs, CONST_INT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, true_bb, false_bb);
}
else if (Type::is_eq_type(rhstype, FLOAT_T))
{
tmp_val = builder->create_fcmp_ne(rhs, CONST_FLOAT(0)); // 类型为INT32_T而不是INT1_T就不能直接create_cond_br先判断真假
builder->create_cond_br(tmp_val, true_bb, false_bb);
}
else // 为无条件跳转
{
builder->create_br(true_bb);
}
builder->set_insert_point(true_bb); // cond_bb判断域结束进入true_bb执行体内部
builder->create_store(CONST_INT(true), result);
builder->create_br(after_bb);
builder->set_insert_point(false_bb);
builder->create_store(CONST_INT(false), result);
builder->create_br(after_bb);
// true_bb和false_bb IR结束后都要无条件br到after_bb
builder->set_insert_point(after_bb);
tmp_val = builder->create_load(result);
break;
}
}
void IRBuilder::visit(SyntaxTree::BinaryExpr &node)
{
if (scope.in_global()) // 需要计算全局变量声明中某些表达式
{
int lhs_ival, rhs_ival;
float lhs_fval, rhs_fval;
bool lhs_is_int, rhs_is_int;
node.lhs->accept(*this);
if (expr_cal_result.is_int)
lhs_ival = expr_cal_result.ival;
else
lhs_fval = expr_cal_result.fval;
lhs_is_int = expr_cal_result.is_int;
node.rhs->accept(*this);
if (expr_cal_result.is_int)
rhs_ival = expr_cal_result.ival;
else
rhs_fval = expr_cal_result.fval;
rhs_is_int = expr_cal_result.is_int;
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
if (lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = true;
expr_cal_result.ival = lhs_ival + rhs_ival;
}
else if (!lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval + rhs_ival;
}
else if (lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_ival + rhs_fval;
}
else if (!lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval + rhs_fval;
}
break;
case SyntaxTree::BinOp::MINUS:
if (lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = true;
expr_cal_result.ival = lhs_ival - rhs_ival;
}
else if (!lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval - rhs_ival;
}
else if (lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_ival - rhs_fval;
}
else if (!lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval - rhs_fval;
}
break;
case SyntaxTree::BinOp::MULTIPLY:
if (lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = true;
expr_cal_result.ival = lhs_ival * rhs_ival;
}
else if (!lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval * rhs_ival;
}
else if (lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_ival * rhs_fval;
}
else if (!lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval * rhs_fval;
}
break;
case SyntaxTree::BinOp::DIVIDE:
if (lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = true;
expr_cal_result.ival = lhs_ival / rhs_ival;
}
else if (!lhs_is_int && rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval / rhs_ival;
}
else if (lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_ival / rhs_fval;
}
else if (!lhs_is_int && !rhs_is_int)
{
expr_cal_result.is_int = false;
expr_cal_result.fval = lhs_fval / rhs_fval;
}
break;
case SyntaxTree::BinOp::MODULO:
expr_cal_result.is_int = true;
if (lhs_is_int && rhs_is_int)
expr_cal_result.ival = lhs_ival % rhs_ival;
else if (!lhs_is_int && rhs_is_int)
expr_cal_result.fval = int(lhs_fval) % rhs_ival;
else if (lhs_is_int && !rhs_is_int)
expr_cal_result.fval = lhs_ival % int(rhs_fval);
else if (!lhs_is_int && !rhs_is_int)
expr_cal_result.fval = int(lhs_fval) % int(rhs_fval);
break;
}
}
else // 生成相应计算ir指令, 根据最终指令形式分为float、int和指针计算三种
{
node.lhs->accept(*this);
auto lhs = tmp_val;
auto lhstype = lhs->get_type();
node.rhs->accept(*this);
auto rhs = tmp_val;
auto rhstype = rhs->get_type();
switch (node.op)
{
case SyntaxTree::BinOp::PLUS:
if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T))
{ // 目标ir为float加法
if (lhstype->is_integer_type()) // 类型不匹配
{
if (Type::is_eq_type(lhstype, INT1_T))
{
auto zext = builder->create_zext(lhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fadd(itof, rhs);
}
else
{
auto itof = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fadd(itof, rhs);
}
}
else if (rhstype->is_integer_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fadd(lhs, itof);
}
else
{
auto itof = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fadd(lhs, itof);
}
}
else
tmp_val = builder->create_fadd(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{ // 目标ir为32位加法
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_iadd(lhs, rhs);
}
else
{ // 目标ir为指针计算地址计算gep
PtrVec<Value> ptr_idx; // 为适配多维数组或结构体的多个idx寻址,设置为vector类型
if (lhstype->is_pointer_type())
{
ptr_idx.push_back(rhs);
tmp_val = builder->create_gep(lhs, ptr_idx);
}
else if (rhstype->is_pointer_type())
{
ptr_idx.push_back(lhs);
tmp_val = builder->create_gep(rhs, ptr_idx);
}
}
break;
case SyntaxTree::BinOp::MINUS:
if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T))
{ // 目标ir为float减法
if (lhstype->is_integer_type()) // 类型不匹配
{
if (Type::is_eq_type(lhstype, INT1_T))
{
auto zext = builder->create_zext(lhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fsub(itof, rhs);
}
else
{
auto itof = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fsub(itof, rhs);
}
}
else if (rhstype->is_integer_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fsub(lhs, itof);
}
else
{
auto itof = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fsub(lhs, itof);
}
}
else
tmp_val = builder->create_fsub(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{ // 目标ir为32位减法
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_isub(lhs, rhs);
}
else
{ // 目标ir为指针计算地址计算gep 只能lhs为指针类型
PtrVec<Value> ptr_idx; // 为适配多维数组或结构体的多个idx寻址,设置为vector类型
if (lhstype->is_pointer_type())
{
ptr_idx.push_back(rhs);
tmp_val = builder->create_gep(lhs, ptr_idx);
}
}
break;
case SyntaxTree::BinOp::MULTIPLY:
if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T))
{ // 目标ir为float乘法
if (lhstype->is_integer_type()) // 类型不匹配
{
if (Type::is_eq_type(lhstype, INT1_T))
{
auto zext = builder->create_zext(lhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fmul(itof, rhs);
}
else
{
auto itof = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fmul(itof, rhs);
}
}
else if (rhstype->is_integer_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fmul(lhs, itof);
}
else
{
auto itof = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fmul(lhs, itof);
}
}
else
tmp_val = builder->create_fmul(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{ // 目标ir为32位乘法
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_imul(lhs, rhs);
}
break;
case SyntaxTree::BinOp::DIVIDE:
if (Type::is_eq_type(lhstype, FLOAT_T) || Type::is_eq_type(rhstype, FLOAT_T))
{ // 目标ir为float除法
if (lhstype->is_integer_type()) // 类型不匹配
{
if (Type::is_eq_type(lhstype, INT1_T))
{
auto zext = builder->create_zext(lhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fdiv(itof, rhs);
}
else
{
auto itof = builder->create_sitofp(lhs, FLOAT_T);
tmp_val = builder->create_fdiv(itof, rhs);
}
}
else if (rhstype->is_integer_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
auto itof = builder->create_sitofp(zext, FLOAT_T);
tmp_val = builder->create_fdiv(lhs, itof);
}
else
{
auto itof = builder->create_sitofp(rhs, FLOAT_T);
tmp_val = builder->create_fdiv(lhs, itof);
}
}
else
tmp_val = builder->create_fdiv(lhs, rhs);
}
else if (lhstype->is_integer_type() && rhstype->is_integer_type())
{ // 目标ir为32位除法
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_isdiv(lhs, rhs);
}
break;
case SyntaxTree::BinOp::MODULO: // 取模运算只能是int类型不能通过ir将float类型转换这是不合法的
if (lhstype->is_integer_type() && rhstype->is_integer_type())
{ // 目标ir为32位取模
if (Type::is_eq_type(lhstype, INT1_T))
lhs = builder->create_zext(lhs, INT32_T);
if (Type::is_eq_type(rhstype, INT1_T))
rhs = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_isrem(lhs, rhs);
}
break;
}
}
}
void IRBuilder::visit(SyntaxTree::UnaryExpr &node)
{
if (scope.in_global()) // 需要计算全局变量声明中某些表达式
{ // 只有minus需要修改值否则值和类型都不用修改
node.rhs->accept(*this);
if (expr_cal_result.is_int)
{
if (node.op == SyntaxTree::UnaryOp::MINUS)
expr_cal_result.ival = -expr_cal_result.ival;
else if (node.op == SyntaxTree::UnaryOp::MINUS)
expr_cal_result.fval = -expr_cal_result.fval;
}
}
else // 需要更新tmp_val
{
node.rhs->accept(*this);
auto rhs = tmp_val;
auto rhstype = rhs->get_type();
switch (node.op)
{
case SyntaxTree::UnaryOp::PLUS:
break;
case SyntaxTree::UnaryOp::MINUS:
if (rhstype->is_integer_type())
{
if (Type::is_eq_type(rhstype, INT1_T))
{
auto zext = builder->create_zext(rhs, INT32_T);
tmp_val = builder->create_isub(CONST_INT(0), zext);
}
else
tmp_val = builder->create_isub(CONST_INT(0), rhs);
}
else if (rhstype->is_float_type())
tmp_val = builder->create_fsub(CONST_FLOAT(0), rhs);
break;
}
}
}
void IRBuilder::visit(SyntaxTree::FuncCallStmt &node)
{
auto Func = dynamic_pointer_cast<Function>(scope.find(node.name, true));
auto RetType = Func->get_return_type();
PtrVec<Value> param;
param.clear();
auto FuncPara = Func->get_args();
int idx = 0;
// DBGLOG("begin the funccall");
for (auto funp : FuncPara)
{
node.params[idx]->accept(*this);
auto tmpType = tmp_val->get_type();
auto ParaType = funp->get_type();
if (ParaType == tmpType)
param.push_back(tmp_val);
else if (ParaType == INT32_T)
{
switch (tmpType->get_type_id())
{
// INT1 to INT32
case SysYF::IR::Type::TypeID::IntegerTyID:
tmp_val = builder->create_zext(tmp_val, INT32_T);
param.push_back(tmp_val);
break;
// FLOAT to INT32
case SysYF::IR::Type::TypeID::FloatTyID:
tmp_val = builder->create_fptosi(tmp_val, INT32_T);
param.push_back(tmp_val);
break;
// other
default:
// DBGLOG("Error type to INT32_T");
// DBGLOG(tmpType->get_type_id());
break;
}
}
else if (ParaType == FLOAT_T)
{
switch (tmpType->get_type_id())
{
// INT1/32 to FLOAT
case SysYF::IR::Type::TypeID::IntegerTyID:
if (tmpType == INT1_T)
tmp_val = builder->create_zext(tmp_val, INT32_T);
tmp_val = builder->create_sitofp(tmp_val, FLOAT_T);
param.push_back(tmp_val);
break;
// other
default:
// DBGLOG("Error type to FLOAT_T");
// DBGLOG(tmpType->get_type_id());
break;
}
}
else if (ParaType->is_pointer_type())
{
if (tmpType->is_array_type())
{
// DBGLOG(tmpType->get_type_id());
// DBGLOG("debug 1");
auto Element_pointer = builder->create_gep(lhs_addr, {CONST_INT(0), CONST_INT(0)});
// DBGLOG("debug 2");
param.push_back(Element_pointer);
}
else
{
// DBGLOG("ParaType == pointer");
// DBGLOG(tmpType->get_type_id());
}
}
else
{
// DBGLOG("Error ParaType");
// DBGLOG(ParaType->get_type_id());
// other
}
idx++;
}
if (RetType == VOID_T)
{
builder->create_call(Func, param);
}
else
{
tmp_val = builder->create_call(Func, param);
}
// DBGLOG("end the funccall");
}
void IRBuilder::visit(SyntaxTree::IfStmt &node)
{
/* DBGLOG("begin the IF"); */
SysYF::Ptr<SysYF::IR::BasicBlock> bbTrue, bbAfter, bbFalse, bbCond;
auto ParentFunc = builder->get_insert_block()->get_parent();
char num[10];
// itoa(Ifnum, num, 10);
/* DBGLOG("before the sprintf"); */
sprintf(num, "%d", Ifnum++);
/* DBGLOG("after the sprintf"); */
/* std::string s = "if_cond_";
bbCond = BasicBlock::create(module, s + num, ParentFunc); */
std::string s = "if_true_";
bbTrue = BasicBlock::create(module, s + num, ParentFunc);
if (node.else_statement)
{
s = "if_false_";
bbFalse = BasicBlock::create(module, s + num, ParentFunc);
}
s = "after_if_";
bbAfter = BasicBlock::create(module, s + num, ParentFunc);
/* DBGLOG("before visit cond"); */
/* builder->create_br(bbCond); */
/* builder->set_insert_point(bbCond); */
node.cond_exp->accept(*this);
/* DBGLOG("after visit cond"); */
SysYF::Ptr<Value> _cmp;
auto condType = tmp_val->get_type();
if (condType == INT1_T)
_cmp = tmp_val;
else if (condType == INT32_T)
_cmp = builder->create_icmp_ne(tmp_val, CONST_INT(0));
else if (condType == FLOAT_T)
_cmp = builder->create_fcmp_ne(tmp_val, CONST_FLOAT(0));
else
{
}
/* DBGLOG("after Init cmp"); */
if (!_cmp)
builder->create_br(bbTrue);
else if (node.else_statement)
builder->create_cond_br(_cmp, bbTrue, bbFalse);
else
builder->create_cond_br(_cmp, bbTrue, bbAfter);
builder->set_insert_point(bbTrue);
/* DBGLOG("before visit if_stmt"); */
node.if_statement->accept(*this);
/* DBGLOG("after visit if_stmt"); */
if (!builder->get_insert_block()->get_terminator())
builder->create_br(bbAfter);
if (node.else_statement)
{
builder->set_insert_point(bbFalse);
/* DBGLOG("before visit else"); */
node.else_statement->accept(*this);
if (!builder->get_insert_block()->get_terminator())
builder->create_br(bbAfter);
}
builder->set_insert_point(bbAfter);
/* DBGLOG("end the IF"); */
}
void IRBuilder::visit(SyntaxTree::WhileStmt &node)
{
// 类比condexpr和ifstmt需要创建bb label并控制跳转
char labelname[20];
auto parent = func_parent;
sprintf(labelname, "cond_bb_%d", bb_label_num++);
auto cond_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "true_bb_%d", bb_label_num++);
auto true_bb = BasicBlock::create(module, labelname, parent);
sprintf(labelname, "after_bb_%d", bb_label_num++);
auto after_bb = BasicBlock::create(module, labelname, parent);
break_point.push_back(after_bb); // break后直接跳转至afterbb循环语句后紧接的bb
continue_point.push_back(cond_bb); // continue后跳转至条件判断域condbb
builder->create_br(cond_bb); // 进入AST的whilrnode后先无条件进行一次条件判断
builder->set_insert_point(cond_bb);
node.cond_exp->accept(*this);
auto cond_judge = tmp_val;
auto cond_type = cond_judge->get_type();
// 只有当cond是INT1_T类型时才能直接生成cond_br, 否则要先判断cond是否为零值
if (Type::is_eq_type(cond_type, INT1_T))
{
builder->create_cond_br(cond_judge, true_bb, after_bb);
}
else if (Type::is_eq_type(cond_type, INT32_T))
{
cond_judge = builder->create_icmp_ne(cond_judge, CONST_INT(0));
builder->create_cond_br(cond_judge, true_bb, after_bb);
}
else if (Type::is_eq_type(cond_type, FLOAT_T))
{
cond_judge = builder->create_fcmp_ne(cond_judge, CONST_FLOAT(0));
builder->create_cond_br(cond_judge, true_bb, after_bb);
}
else // 说明能无条件跳转, while(1)
{
builder->create_br(true_bb);
}
builder->set_insert_point(true_bb); // 进入循环执行体内部生成IR
node.statement->accept(*this); // 访问循环体内部stmt, 自会生成IR
if (!(builder->get_insert_block()->get_terminator())) // ret与br都是Terminator Instructions也就是终止指令, 若没有则补充(while语句里没有)
builder->create_br(cond_bb);
builder->set_insert_point(after_bb);
// 离开前别忘了维护break和continue栈
break_point.pop_back();
continue_point.pop_back();
}
void IRBuilder::visit(SyntaxTree::BreakStmt &node)
{ // 控制跳转目的地址
char labelname[20];
auto parent = func_parent;
sprintf(labelname, "break_dest_%d", bb_label_num++);
auto break_dest_bb = BasicBlock::create(module, labelname, parent);
builder->create_br(break_point.back()); // 还不需要pop, while语句中会pop
builder->set_insert_point(break_dest_bb);
}
void IRBuilder::visit(SyntaxTree::ContinueStmt &node)
{ // 控制跳转目的地址
char labelname[20];
auto parent = func_parent;
sprintf(labelname, "cond_dest_%d", bb_label_num++);
auto cond_dest_bb = BasicBlock::create(module, labelname, parent);
builder->create_br(continue_point.back()); // 还不需要pop, while语句中会pop
builder->set_insert_point(cond_dest_bb);
}
}
}