|
|
|
@ -1,4 +1,3 @@
|
|
|
|
|
#include <cassert>
|
|
|
|
|
#include "IRBuilder.h"
|
|
|
|
|
|
|
|
|
|
namespace SysYF
|
|
|
|
@ -27,6 +26,8 @@ Ptr<BasicBlock> retBB;
|
|
|
|
|
Ptr<Value> retAlloca;
|
|
|
|
|
|
|
|
|
|
Ptr<Value> tmpInst;
|
|
|
|
|
Ptr<ConstantArray> arrayInitializer;
|
|
|
|
|
Ptr<std::vector<Ptr<Constant>>> constArrayInit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// types
|
|
|
|
@ -37,6 +38,70 @@ Ptr<Type> FLOAT_T;
|
|
|
|
|
Ptr<Type> INT32PTR_T;
|
|
|
|
|
Ptr<Type> FLOATPTR_T;
|
|
|
|
|
|
|
|
|
|
void IRBuilder::ArrayInitTraverser(Ptr <SyntaxTree::InitVal> initVal, int depth, int index, Ptr<Type> varType, std::vector<int> arrayDim) {
|
|
|
|
|
if(initVal->isExp) {
|
|
|
|
|
initVal->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
//set constArrayInit[index] = tmpInst
|
|
|
|
|
constArrayInit->at(index) = dynamic_pointer_cast<Constant>(tmpInst);
|
|
|
|
|
} else {
|
|
|
|
|
for (int i = 0; i < initVal->elementList.size(); i++) {
|
|
|
|
|
auto tmpIndex = 1;
|
|
|
|
|
for (int j = depth + 1; j < arrayDim.size(); j++) {
|
|
|
|
|
tmpIndex *= arrayDim[j];
|
|
|
|
|
}
|
|
|
|
|
ArrayInitTraverser(initVal->elementList[i], depth + 1, index + i * tmpIndex, varType, arrayDim);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void IRBuilder::GetArrayInit(Ptr <SyntaxTree::InitVal> initVal, std::vector<int> arrayDim, Ptr <Type> varType, bool global = true) {
|
|
|
|
|
/*
|
|
|
|
|
arrayInitializer.reset();
|
|
|
|
|
// 一维数组
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for(auto initValPtr : initVal->elementList){
|
|
|
|
|
initValPtr->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto arrayLen = arrayDim[0];
|
|
|
|
|
auto otherLen = arrayLen - initVal->elementList.size();
|
|
|
|
|
auto tmpZero = CONST_INT(0);
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
for (auto i = 0u; i < otherLen; i++) {
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto arrayType = varType->get_array_type(varType, arrayLen);
|
|
|
|
|
arrayInitializer = ConstantArray::create(arrayType, varInit);
|
|
|
|
|
*/
|
|
|
|
|
auto arraySize = 1;
|
|
|
|
|
for(auto i : arrayDim){
|
|
|
|
|
arraySize *= i;
|
|
|
|
|
}
|
|
|
|
|
constArrayInit = std::make_shared<std::vector<Ptr<Constant>>>(arraySize);
|
|
|
|
|
ArrayInitTraverser(initVal, 0, 0, varType, arrayDim);
|
|
|
|
|
auto arrayType = varType->get_array_type(varType, arraySize);
|
|
|
|
|
//iterate constArrayInit to get arrayInitializer
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for(auto i : *constArrayInit){
|
|
|
|
|
if (i == nullptr) {
|
|
|
|
|
Ptr<Constant> tmpZero;
|
|
|
|
|
if(varType == INT32_T){
|
|
|
|
|
tmpZero = CONST_INT(0);
|
|
|
|
|
} else{
|
|
|
|
|
tmpZero = CONST_FLOAT(0.0);
|
|
|
|
|
}
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
} else {
|
|
|
|
|
varInit.push_back(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
arrayInitializer = ConstantArray::create(arrayType, varInit);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Type> GetBaseType(SyntaxTree::Type type){
|
|
|
|
|
switch(type){
|
|
|
|
|
case SyntaxTree::Type::INT:
|
|
|
|
@ -62,6 +127,8 @@ Ptr<Type> GetParamType(SyntaxTree::Type type, bool isPtr = false){
|
|
|
|
|
else if(tmpType == FLOAT_T){
|
|
|
|
|
return FLOATPTR_T;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -107,8 +174,7 @@ void IRBuilder::BinaryExprGen(Ptr<Value> lhs, Ptr<Value> rhs, SyntaxTree::BinOp
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SyntaxTree::BinOp::MODULO:
|
|
|
|
|
if (isFloat) { ;// not support
|
|
|
|
|
} else {
|
|
|
|
|
if (!isFloat) {
|
|
|
|
|
tmpInst = CONST_INT(lInt % rInt);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
@ -446,11 +512,23 @@ void IRBuilder::visit(SyntaxTree::FuncParam &node) {
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
// type
|
|
|
|
|
auto varType = GetBaseType(node.btype);
|
|
|
|
|
std::vector<int> arrayDim;
|
|
|
|
|
Ptr<ArrayType> arrayType;
|
|
|
|
|
int arraySize = 1;
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
node.array_length[0]->accept(*this);
|
|
|
|
|
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
arrayType = ArrayType::create(varType, constInt->get_value());
|
|
|
|
|
for (int i = node.array_length.size() - 1; i >= 0; i--) {
|
|
|
|
|
node.array_length[i]->accept(*this);
|
|
|
|
|
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
if(i == node.array_length.size() - 1) {
|
|
|
|
|
arraySize = constInt->get_value();
|
|
|
|
|
arrayDim.push_back(constInt->get_value());
|
|
|
|
|
} else {
|
|
|
|
|
arraySize *= constInt->get_value();
|
|
|
|
|
arrayDim.push_back(constInt->get_value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
arrayType = ArrayType::create(varType, arraySize);
|
|
|
|
|
std::reverse(arrayDim.begin(), arrayDim.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Value> identAlloca;
|
|
|
|
@ -461,25 +539,21 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, varType, false, zeroInit);
|
|
|
|
|
} else {
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, false, zeroInit);
|
|
|
|
|
//
|
|
|
|
|
auto tmpIdent = dynamic_pointer_cast<GlobalVariable>(identAlloca);
|
|
|
|
|
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
|
|
|
|
|
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
|
|
|
|
|
//
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for (const auto &init : node.initializers->elementList) {
|
|
|
|
|
init->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto arrayLen = arrayType->get_num_of_elements();
|
|
|
|
|
auto otherLen = arrayLen - node.initializers->elementList.size();
|
|
|
|
|
auto tmpZero = CONST_INT(0);
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
for (int i = 0; i < otherLen; i++) {
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto arrayInit = ConstantArray::create(varType->get_array_type(varType, arrayLen), varInit);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInit);
|
|
|
|
|
|
|
|
|
|
GetArrayInit(node.initializers, arrayDim, varType);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInitializer);
|
|
|
|
|
//
|
|
|
|
|
auto tmpIdent = dynamic_pointer_cast<GlobalVariable>(identAlloca);
|
|
|
|
|
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
|
|
|
|
|
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
|
|
|
|
|
//
|
|
|
|
|
} else {
|
|
|
|
|
if (node.is_constant) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
@ -501,7 +575,6 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
node.initializers->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
scope.push(node.name, tmpInst);
|
|
|
|
|
//builder->create_store(tmpInst, identAlloca);
|
|
|
|
|
} else {
|
|
|
|
|
if (node.array_length.empty()) {
|
|
|
|
|
identAlloca = builder->create_alloca(varType);
|
|
|
|
@ -513,25 +586,19 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
}
|
|
|
|
|
return ;
|
|
|
|
|
} else {
|
|
|
|
|
std::vector<Ptr<Constant>> varInit;
|
|
|
|
|
for (const auto &init : node.initializers->elementList) {
|
|
|
|
|
init->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto otherLen = arrayType->get_num_of_elements() - node.initializers->elementList.size();
|
|
|
|
|
auto tmpZero = CONST_INT(0);
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
for (int i = 0; i < otherLen; i++) {
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
auto zeroInit = ConstantZero::create(varType, module);
|
|
|
|
|
GetArrayInit(node.initializers, arrayDim, varType);
|
|
|
|
|
//
|
|
|
|
|
identAlloca = builder->create_alloca(arrayType);
|
|
|
|
|
auto tmpIdent = dynamic_pointer_cast<AllocaInst>(identAlloca);
|
|
|
|
|
tmpIdent->set_array(std::make_shared<std::vector<int>>(arrayDim));
|
|
|
|
|
//
|
|
|
|
|
identAlloca = dynamic_pointer_cast<Value>(tmpIdent);
|
|
|
|
|
scope.push(node.name, identAlloca);
|
|
|
|
|
for (int i = 0; i < varInit.size(); i++) {
|
|
|
|
|
auto varInit = constArrayInit.get();
|
|
|
|
|
for (int i = 0u; i < arraySize; i++) {
|
|
|
|
|
auto index = CONST_INT(i);
|
|
|
|
|
auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index});
|
|
|
|
|
builder->create_store(varInit[i], ptr);
|
|
|
|
|
builder->create_store((*varInit)[i], ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -542,7 +609,8 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
auto ident = scope.find(node.name, false);
|
|
|
|
|
if (!node.array_index.empty()) {
|
|
|
|
|
node.array_index[0]->accept(*this);
|
|
|
|
|
|
|
|
|
|
/*node.array_index[0]->accept(*this);
|
|
|
|
|
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
|
|
|
|
|
if(globalIdent != nullptr && globalIdent->is_const() && constIndex != nullptr) {
|
|
|
|
@ -551,6 +619,37 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = builder->create_gep(ident, {CONST_INT(0), tmpInst});
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
int index = 0;
|
|
|
|
|
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
|
|
|
|
|
auto localIdent = dynamic_pointer_cast<AllocaInst>(ident);
|
|
|
|
|
Ptr<std::vector<int>> arrayDimPtr;
|
|
|
|
|
if (globalIdent != nullptr) {
|
|
|
|
|
arrayDimPtr = globalIdent->get_array_dim();
|
|
|
|
|
} else if (localIdent != nullptr) {
|
|
|
|
|
arrayDimPtr = localIdent->get_array_dim();
|
|
|
|
|
}
|
|
|
|
|
bool index_is_constant = true;
|
|
|
|
|
for (int i = 0; i < node.array_index.size(); i++) {
|
|
|
|
|
node.array_index[i]->accept(*this);
|
|
|
|
|
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
if(constIndex == nullptr) {
|
|
|
|
|
index_is_constant = false;
|
|
|
|
|
}
|
|
|
|
|
int tmpIndex = 1;
|
|
|
|
|
for (int j = i + 1; j < node.array_index.size(); j++) {
|
|
|
|
|
tmpIndex *= (*arrayDimPtr)[j];
|
|
|
|
|
}
|
|
|
|
|
index += constIndex->get_value() * tmpIndex;
|
|
|
|
|
}
|
|
|
|
|
if(globalIdent != nullptr && globalIdent->is_const() && index_is_constant) {
|
|
|
|
|
auto arrayInit = dynamic_pointer_cast<ConstantArray>(globalIdent->get_init());
|
|
|
|
|
tmpInst = arrayInit->get_element_value(index);
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = builder->create_gep(ident, {CONST_INT(0), CONST_INT(index)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (ident->get_type()->is_pointer_type() && ident->get_type()->get_pointer_element_type()->is_array_type()) {
|
|
|
|
@ -559,7 +658,6 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
tmpInst = ident;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
@ -599,7 +697,6 @@ void IRBuilder::visit(SyntaxTree::ReturnStmt &node) {
|
|
|
|
|
}
|
|
|
|
|
// every ret stmt only store the value and jump to the retBB
|
|
|
|
|
builder->create_br(retBB);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Finish
|
|
|
|
@ -611,18 +708,15 @@ void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
|
|
|
|
|
stmt->accept(*this);
|
|
|
|
|
}
|
|
|
|
|
scope.exit();
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::EmptyStmt &node) {
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::ExprStmt &node) {
|
|
|
|
|
node.exp->accept(*this);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
@ -636,7 +730,6 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = CONST_INT((constInt->get_value() == 0 || constFloat->get_value() == 0 ) ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -790,19 +883,16 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(afterBB);
|
|
|
|
|
curWhileBlock = tmpWhileBlock;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::BreakStmt &node) {
|
|
|
|
|
builder->create_br(curWhileBlock.afterBB);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::ContinueStmt &node) {
|
|
|
|
|
builder->create_br(curWhileBlock.condBB);
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|