Modified something

main
Odeinjul 11 months ago
parent 98168c0dcc
commit 6102b29494
No known key found for this signature in database
GPG Key ID: E384228B2B38FFBB

@ -75,6 +75,7 @@ private:
class IRBuilder: public SyntaxTree::Visitor class IRBuilder: public SyntaxTree::Visitor
{ {
private: private:
void TypeConvert(Ptr<Value> origin, Ptr<Type> expected);
virtual void visit(SyntaxTree::InitVal &) override final; virtual void visit(SyntaxTree::InitVal &) override final;
virtual void visit(SyntaxTree::Assembly &) override final; virtual void visit(SyntaxTree::Assembly &) override final;
virtual void visit(SyntaxTree::FuncDef &) override final; virtual void visit(SyntaxTree::FuncDef &) override final;

@ -13,12 +13,32 @@ namespace IR
// to store state // to store state
// store temporary value // store temporary value
std::vector<Ptr<Type>> funcFParam;
struct WhileBlock {
BasicBlock *condBB;
BasicBlock *innerBB;
BasicBlock *exitBB;
};
auto curWhileBlock = WhileBlock{nullptr, nullptr, nullptr};
struct CondBlock {
BasicBlock *trueBB;
BasicBlock *falseBB;
};
auto curCondStruct = CondBlock{nullptr, nullptr};
Ptr<BasicBlock> retBB;
Ptr<Value> retAlloca;
Ptr<Value> tmpInst;
int tmpConstVal = 0; int tmpConstVal = 0;
Ptr<Value> tmpVal = nullptr; Ptr<Value> tmpVal = nullptr;
std::vector<Ptr<Type>> funcFParam;
std::vector<Ptr<Value>> arrayInitializer; std::vector<Ptr<Value>> arrayInitializer;
std::string curFuncName = ""; std::string curFuncName = "";
Ptr<SysYF::IR::Instruction> tmpInst;
bool isFloat = false; bool isFloat = false;
bool isAddr = false; bool isAddr = false;
Ptr<BasicBlock> curCondBB; Ptr<BasicBlock> curCondBB;
@ -32,12 +52,12 @@ Ptr<Type> FLOAT_T;
Ptr<Type> INT32PTR_T; Ptr<Type> INT32PTR_T;
Ptr<Type> FLOATPTR_T; Ptr<Type> FLOATPTR_T;
Ptr<Type> GetType(SyntaxTree::Type type){ Ptr<Type> GetBaseType(SyntaxTree::Type type){
switch(type){ switch(type){
case SyntaxTree::Type::INT: case SyntaxTree::Type::INT:
return INT32_T; return INT32_T;
case SyntaxTree::Type::FLOAT: case SyntaxTree::Type::FLOAT:
return INT1_T; return FLOAT_T;
case SyntaxTree::Type::VOID: case SyntaxTree::Type::VOID:
return VOID_T; return VOID_T;
default: default:
@ -45,6 +65,62 @@ Ptr<Type> GetType(SyntaxTree::Type type){
} }
} }
Ptr<Type> GetParamType(SyntaxTree::Type type, bool isPtr = false){
auto tmpType = GetBaseType(type);
if(!isPtr || tmpType == nullptr || tmpType == VOID_T){
return tmpType;
}
else {
if(tmpType == INT32_T){
return INT32PTR_T;
}
else if(tmpType == FLOAT_T){
return FLOATPTR_T;
}
}
}
void IRBuilder::TypeConvert(Ptr<Value> origin, Ptr<Type> expected) {
if (dynamic_pointer_cast<Constant>(origin) == nullptr) {
auto type = origin->get_type();
if (type == expected) {
return;
}
if (type->is_pointer_type()) {
type = type->get_pointer_element_type();
origin = builder->create_load(origin);
}
if (type == INT32_T && expected == FLOAT_T) {
origin = builder->create_sitofp(origin, expected);
return;
}
if (type == FLOAT_T && expected == INT32_T) {
origin = builder->create_fptosi(origin, expected);
return;
}
} else {
auto tmpInt = dynamic_pointer_cast<ConstantInt>(origin);
auto tmpFloat = dynamic_pointer_cast<ConstantFloat>(origin);
if (tmpInt != nullptr) {
if (expected == FLOAT_T)
tmpInst = CONST_FLOAT(tmpInt->get_value());
else if (expected == INT1_T)
tmpInst = CONST_INT(tmpInt->get_value() != 0);
}
if (tmpFloat != nullptr) {
if (expected == INT32_T)
tmpInst =
CONST_INT(static_cast<int>(tmpInt->get_value()));
else if (expected == INT1_T)
tmpInst = CONST_INT(tmpFloat->get_value() != 0);
}
return;
}
}
void IRBuilder::visit(SyntaxTree::Assembly &node) { void IRBuilder::visit(SyntaxTree::Assembly &node) {
VOID_T = Type::get_void_type(module); VOID_T = Type::get_void_type(module);
@ -54,53 +130,86 @@ void IRBuilder::visit(SyntaxTree::Assembly &node) {
INT32PTR_T = Type::get_int32_ptr_type(module); INT32PTR_T = Type::get_int32_ptr_type(module);
FLOATPTR_T = Type::get_float_ptr_type(module); FLOATPTR_T = Type::get_float_ptr_type(module);
for (const auto &def : node.global_defs) { for (const auto &def : node.global_defs) {
//std::cout << "4" << std::endl;
def->accept(*this); def->accept(*this);
} }
} }
// You need to fill them // You need to fill them
// TODO
void IRBuilder::visit(SyntaxTree::InitVal &node) { void IRBuilder::visit(SyntaxTree::InitVal &node) {
node.expr->accept(*this);
} }
// FINISH
void IRBuilder::visit(SyntaxTree::FuncDef &node) { void IRBuilder::visit(SyntaxTree::FuncDef &node) {
auto funcRetType = GetParamType(node.ret_type);
node.param_list->accept(*this); node.param_list->accept(*this);
auto funcType = FunctionType::create(GetType(node.ret_type), funcFParam); auto funcType = FunctionType::create(funcRetType, funcFParam);
auto createFunc = Function::create(funcType, node.name, module); auto func = Function::create(funcType, node.name, module);
scope.push(node.name, func);
scope.enter();
auto entryBlock = BasicBlock::create(module, "funcEntry", func);
retBB = BasicBlock::create(module, "ret", func);
builder->set_insert_point(entryBlock);
auto para = node.param_list->params.begin();
for (auto arg = func->arg_begin(); arg != func->arg_end() ; arg++) {
auto name = (*para)->name;
auto val = (*arg);
auto argAlloca = builder->create_alloca(val->get_type());
builder->create_store(val, argAlloca);
scope.push(name, argAlloca);
para++;
}
if (funcRetType == VOID_T) {
;
} else {
retAlloca = builder->create_alloca(funcRetType);
}
node.body->accept(*this); node.body->accept(*this);
if (builder->get_insert_block()->get_terminator() == nullptr) {
if (funcRetType == INT32_T) {
builder->create_store(CONST_INT(0), retAlloca);
} else if (funcRetType == FLOAT_T) {
builder->create_store(CONST_FLOAT(0), retAlloca);
}
builder->create_br(retBB);
}
builder->set_insert_point(retBB);
if (funcRetType == VOID_T) {
builder->create_void_ret();
} else {
auto ret_val = builder->create_load(retAlloca);
builder->create_ret(ret_val);
}
scope.exit();
} }
// FINISH
void IRBuilder::visit(SyntaxTree::FuncFParamList &node) { void IRBuilder::visit(SyntaxTree::FuncFParamList &node) {
funcFParam.clear(); funcFParam.clear();
for (const auto &para : node.params) { for (const auto &para : node.params) {
para->accept(*this); para->accept(*this);
} }
} }
// FINISH
void IRBuilder::visit(SyntaxTree::FuncParam &node) { void IRBuilder::visit(SyntaxTree::FuncParam &node) {
switch(node.param_type) { auto tmpType = GetParamType(node.param_type, node.array_index[0] != nullptr);
case SyntaxTree::Type::INT: funcFParam.push_back(tmpType);
if (!node.array_index.empty()) {
// TODO high dim array
funcFParam.push_back(INT32PTR_T);
} else {
funcFParam.push_back(INT32_T);
}
break;
case SyntaxTree::Type::FLOAT:
if (!node.array_index.empty()) {
// TODO high dim array (not now)
funcFParam.push_back(FLOATPTR_T);
} else {
funcFParam.push_back(FLOAT_T);
}
break;
default:
funcFParam.push_back(INT32_T);
break;
}
} }
// TODO
void IRBuilder::visit(SyntaxTree::VarDef &node) { void IRBuilder::visit(SyntaxTree::VarDef &node) {
// TODO high dim array (not now) // TODO high dim array (not now)
int arrayLength; int arrayLength;
@ -233,43 +342,42 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
} }
// TODO
void IRBuilder::visit(SyntaxTree::LVal &node) { void IRBuilder::visit(SyntaxTree::LVal &node) {
auto ident = scope.find(node.name, false); auto ident = scope.find(node.name, false);
if (!node.array_index.empty()) { if (!node.array_index.empty()) {
//TODO: high dim array (not now) //TODO
node.array_index[0]->accept(*this);
auto index = tmpInst;
tmpInst = builder->create_gep(ident, {CONST_INT(0), index});
} }
else { else {
tmpInst = dynamic_pointer_cast<Instruction>(ident); if (ident->get_type()->is_pointer_type() && ident->get_type()->get_pointer_element_type()->is_array_type()) {
tmpInst = builder->create_gep(ident, {CONST_INT(0), CONST_INT(0)});
} else {
tmpInst = ident;
}
} }
isAddr = true; isAddr = true;
} }
// FINISH
void IRBuilder::visit(SyntaxTree::AssignStmt &node) { void IRBuilder::visit(SyntaxTree::AssignStmt &node) {
node.target->accept(*this); node.target->accept(*this);
auto target = tmpInst; auto target = tmpInst;
node.value->accept(*this); node.value->accept(*this);
Ptr<Value> value; auto value = tmpInst;
if (isAddr) { TypeConvert(value, target->get_type());
value = builder->create_load(tmpInst); value = tmpInst;
isAddr = false;
}
else
value = dynamic_pointer_cast<Value>(tmpInst);
builder->create_store(value, target); builder->create_store(value, target);
} }
//FINISH
void IRBuilder::visit(SyntaxTree::Literal &node) { void IRBuilder::visit(SyntaxTree::Literal &node) {
switch(node.literal_type) { switch(node.literal_type) {
case SyntaxTree::Type::INT: case SyntaxTree::Type::INT:
tmpVal = CONST_INT(node.int_const); tmpVal = CONST_INT(node.int_const);
isFloat = false;
break; break;
case SyntaxTree::Type::FLOAT: case SyntaxTree::Type::FLOAT:
tmpVal = CONST_FLOAT(node.float_const); tmpVal = CONST_FLOAT(node.float_const);
isFloat = true;
break; break;
default: default:
tmpVal = CONST_INT(0); tmpVal = CONST_INT(0);
@ -277,44 +385,60 @@ void IRBuilder::visit(SyntaxTree::Literal &node) {
} }
} }
// Finish
void IRBuilder::visit(SyntaxTree::ReturnStmt &node) { void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
if (node.ret) {
node.ret->accept(*this); node.ret->accept(*this);
builder->create_ret(tmpVal); auto expectRetType =
builder->get_insert_block()->get_parent()->get_return_type();
TypeConvert(tmpInst, expectRetType);
auto retValue = tmpInst;
builder->create_store(retValue, retAlloca);
}
// every ret stmt only store the value and jump to the retBB
builder->create_br(retBB);
return ;
} }
// Finish
void IRBuilder::visit(SyntaxTree::BlockStmt &node) { void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
scope.enter(); scope.enter();
for (const auto &stmt : node.body) { for (const auto &stmt : node.body) {
stmt->accept(*this); stmt->accept(*this);
if (builder->get_insert_block()->get_terminator() != nullptr)
break;
} }
scope.exit(); scope.exit();
return ; return ;
} }
// FINISH
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) { void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {
return ; return ;
} }
// FINISH
void IRBuilder::visit(SyntaxTree::ExprStmt &node) { void IRBuilder::visit(SyntaxTree::ExprStmt &node) {
node.exp->accept(*this); node.exp->accept(*this);
return ; return ;
} }
// FINISH
void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) { void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
node.rhs->accept(*this); node.rhs->accept(*this);
switch (node.op) { TypeConvert(tmpInst, INT32_T);
case SyntaxTree::UnaryCondOp::NOT: auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
if (isFloat) { auto constFloat = dynamic_pointer_cast<ConstantInt>(tmpInst);
tmpInst = builder->create_fcmp_eq(tmpInst, CONST_FLOAT(0.0)); if (constInt == nullptr && constFloat == nullptr) {
}
else {
tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0)); tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0));
} else {
tmpInst = CONST_INT((constInt->get_value() == 0 || constFloat->get_value() == 0 ) ? 1 : 0);
} }
default: return ;
break;
}
} }
// TODO
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) { void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {
auto curFunc = builder->get_insert_block()->get_parent(); auto curFunc = builder->get_insert_block()->get_parent();
auto trueBB = BasicBlock::create(module, "trueBB_and", curFunc); auto trueBB = BasicBlock::create(module, "trueBB_and", curFunc);
@ -412,6 +536,7 @@ void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {
} }
} }
// TODO
void IRBuilder::visit(SyntaxTree::BinaryExpr &node) { void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {
node.lhs->accept(*this); node.lhs->accept(*this);
auto lhs = tmpInst; auto lhs = tmpInst;
@ -465,6 +590,7 @@ void IRBuilder::visit(SyntaxTree::BinaryExpr &node) {
} }
// TODO
void IRBuilder::visit(SyntaxTree::UnaryExpr &node) { void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {
node.rhs->accept(*this); node.rhs->accept(*this);
switch (node.op) { switch (node.op) {
@ -482,6 +608,7 @@ void IRBuilder::visit(SyntaxTree::UnaryExpr &node) {
} }
} }
// TODO
void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) { void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
auto curFunc = builder->get_insert_block()->get_parent(); auto curFunc = builder->get_insert_block()->get_parent();
std::vector<Ptr<Value>> funcRParam; std::vector<Ptr<Value>> funcRParam;
@ -492,6 +619,7 @@ void IRBuilder::visit(SyntaxTree::FuncCallStmt &node) {
builder->create_call(curFunc, funcRParam); builder->create_call(curFunc, funcRParam);
} }
// TODO
void IRBuilder::visit(SyntaxTree::IfStmt &node) { void IRBuilder::visit(SyntaxTree::IfStmt &node) {
auto curFunc = builder->get_insert_block()->get_parent(); auto curFunc = builder->get_insert_block()->get_parent();
node.cond_exp->accept(*this); node.cond_exp->accept(*this);
@ -505,6 +633,7 @@ void IRBuilder::visit(SyntaxTree::IfStmt &node) {
node.else_statement->accept(*this); node.else_statement->accept(*this);
} }
// TODO
void IRBuilder::visit(SyntaxTree::WhileStmt &node) { void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
auto curFunc = builder->get_insert_block()->get_parent(); auto curFunc = builder->get_insert_block()->get_parent();
auto condBB = BasicBlock::create(module, "condBB_while", curFunc); auto condBB = BasicBlock::create(module, "condBB_while", curFunc);
@ -530,11 +659,13 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
return ; return ;
} }
// TODO
void IRBuilder::visit(SyntaxTree::BreakStmt &node) { void IRBuilder::visit(SyntaxTree::BreakStmt &node) {
builder->create_br(curAfterBB); builder->create_br(curAfterBB);
return ; return ;
} }
// TODO
void IRBuilder::visit(SyntaxTree::ContinueStmt &node) { void IRBuilder::visit(SyntaxTree::ContinueStmt &node) {
builder->create_br(curCondBB); builder->create_br(curCondBB);
return ; return ;

@ -44,8 +44,10 @@ int main(int argc, char *argv[])
} }
} }
auto root = driver.parse(filename); auto root = driver.parse(filename);
std::cout << "AST start." << std::endl;
if (print_ast) if (print_ast)
root->accept(printer); root->accept(printer);
std::cout << "IR start." << std::endl;
if (print_ir) { if (print_ir) {
root->accept(*builder); root->accept(*builder);
auto m = builder->getModule(); auto m = builder->getModule();

Loading…
Cancel
Save