|
|
|
@ -15,6 +15,12 @@ namespace IR
|
|
|
|
|
|
|
|
|
|
std::vector<Ptr<Type>> funcFParam;
|
|
|
|
|
|
|
|
|
|
struct CondBlock {
|
|
|
|
|
Ptr<BasicBlock> trueBB;
|
|
|
|
|
Ptr<BasicBlock> falseBB;
|
|
|
|
|
};
|
|
|
|
|
auto curCondBlock = CondBlock{nullptr, nullptr};
|
|
|
|
|
|
|
|
|
|
struct WhileBlock {
|
|
|
|
|
Ptr<BasicBlock> condBB;
|
|
|
|
|
Ptr<BasicBlock> bodyBB;
|
|
|
|
@ -27,7 +33,7 @@ Ptr<Value> retAlloca;
|
|
|
|
|
|
|
|
|
|
Ptr<Value> tmpInst;
|
|
|
|
|
Ptr<ConstantArray> arrayInitializer;
|
|
|
|
|
Ptr<std::vector<Ptr<Constant>>> constArrayInit;
|
|
|
|
|
Ptr<std::vector<Ptr<Value>>> constArrayInit;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// types
|
|
|
|
@ -39,47 +45,35 @@ 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) {
|
|
|
|
|
auto tmpIndex = index;
|
|
|
|
|
if(initVal->isExp) {
|
|
|
|
|
initVal->expr->accept(*this);
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
//set constArrayInit[index] = tmpInst
|
|
|
|
|
constArrayInit->at(index) = dynamic_pointer_cast<Constant>(tmpInst);
|
|
|
|
|
constArrayInit->at(index) = tmpInst;
|
|
|
|
|
} else {
|
|
|
|
|
auto tmp = 1;
|
|
|
|
|
for (int j = depth + 1; j < arrayDim.size(); j++) {
|
|
|
|
|
tmp *= arrayDim[j];
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < initVal->elementList.size(); i++) {
|
|
|
|
|
auto tmpIndex = 1;
|
|
|
|
|
for (int j = depth + 1; j < arrayDim.size(); j++) {
|
|
|
|
|
tmpIndex *= arrayDim[j];
|
|
|
|
|
if(initVal->elementList[i]->isExp) {
|
|
|
|
|
ArrayInitTraverser(initVal->elementList[i], depth + 1, tmpIndex, varType, arrayDim);
|
|
|
|
|
tmpIndex += 1;
|
|
|
|
|
} else {
|
|
|
|
|
auto sub = tmpIndex - index;
|
|
|
|
|
tmpIndex = tmpIndex - (sub % tmp) + ((sub % tmp) ? tmp : 0);
|
|
|
|
|
//std ::cout << depth << ", " << tmpIndex << std::endl;
|
|
|
|
|
ArrayInitTraverser(initVal->elementList[i], depth + 1, tmpIndex, varType, arrayDim);
|
|
|
|
|
tmpIndex += tmp;
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
constArrayInit = std::make_shared<std::vector<Ptr<Value>>>(arraySize);
|
|
|
|
|
ArrayInitTraverser(initVal, 0, 0, varType, arrayDim);
|
|
|
|
|
auto arrayType = varType->get_array_type(varType, arraySize);
|
|
|
|
|
//iterate constArrayInit to get arrayInitializer
|
|
|
|
@ -92,14 +86,19 @@ void IRBuilder::GetArrayInit(Ptr <SyntaxTree::InitVal> initVal, std::vector<int>
|
|
|
|
|
} else{
|
|
|
|
|
tmpZero = CONST_FLOAT(0.0);
|
|
|
|
|
}
|
|
|
|
|
TypeConvert(tmpZero, varType);
|
|
|
|
|
tmpInst = tmpZero;
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
} else {
|
|
|
|
|
varInit.push_back(i);
|
|
|
|
|
tmpInst = i;
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
varInit.push_back(dynamic_pointer_cast<Constant>(tmpInst));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
arrayInitializer = ConstantArray::create(arrayType, varInit);
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
if (global) {
|
|
|
|
|
arrayInitializer = ConstantArray::create(arrayType, varInit);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ptr<Type> GetBaseType(SyntaxTree::Type type){
|
|
|
|
@ -434,8 +433,6 @@ void IRBuilder::visit(SyntaxTree::Assembly &node) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// You need to fill them
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::InitVal &node) {
|
|
|
|
|
node.expr->accept(*this);
|
|
|
|
@ -443,7 +440,7 @@ void IRBuilder::visit(SyntaxTree::InitVal &node) {
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::FuncDef &node) {
|
|
|
|
|
|
|
|
|
|
//std::cout <<node.name<<std::endl;
|
|
|
|
|
auto funcRetType = GetParamType(node.ret_type);
|
|
|
|
|
node.param_list->accept(*this);
|
|
|
|
|
auto funcType = FunctionType::create(funcRetType, funcFParam);
|
|
|
|
@ -530,7 +527,7 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
arrayType = ArrayType::create(varType, arraySize);
|
|
|
|
|
std::reverse(arrayDim.begin(), arrayDim.end());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//std::cout << node.name << ", "<< arraySize << std::endl;
|
|
|
|
|
Ptr<Value> identAlloca;
|
|
|
|
|
if (scope.in_global()) {
|
|
|
|
|
if (!node.is_inited || (!node.array_length.empty() && node.initializers->elementList.empty())) {
|
|
|
|
@ -547,7 +544,7 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (!node.array_length.empty()) {
|
|
|
|
|
GetArrayInit(node.initializers, arrayDim, varType);
|
|
|
|
|
GetArrayInit(node.initializers, arrayDim, varType, true);
|
|
|
|
|
identAlloca = GlobalVariable::create(node.name, module, arrayType, node.is_constant, arrayInitializer);
|
|
|
|
|
//
|
|
|
|
|
auto tmpIdent = dynamic_pointer_cast<GlobalVariable>(identAlloca);
|
|
|
|
@ -586,31 +583,51 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
}
|
|
|
|
|
return ;
|
|
|
|
|
} else {
|
|
|
|
|
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);
|
|
|
|
|
auto varInit = constArrayInit.get();
|
|
|
|
|
std::cout << arraySize << std::endl;
|
|
|
|
|
Ptr<Constant> tmpZero;
|
|
|
|
|
if (varType->is_integer_type()) {
|
|
|
|
|
tmpZero = CONST_INT(0);
|
|
|
|
|
if(node.is_inited) {
|
|
|
|
|
GetArrayInit(node.initializers, arrayDim, varType, false);
|
|
|
|
|
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);
|
|
|
|
|
Ptr<Constant> tmpZero;
|
|
|
|
|
if (varType->is_integer_type()) {
|
|
|
|
|
tmpZero = CONST_INT(0);
|
|
|
|
|
} else {
|
|
|
|
|
tmpZero = CONST_FLOAT(0.0);
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0u; i < arraySize; i++) {
|
|
|
|
|
auto index = CONST_INT(i);
|
|
|
|
|
auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index});
|
|
|
|
|
if ((*constArrayInit)[i] == nullptr) {
|
|
|
|
|
builder->create_store(tmpZero, ptr);
|
|
|
|
|
} else {
|
|
|
|
|
//std :: cout << i << std::endl;
|
|
|
|
|
tmpInst = (*constArrayInit)[i];
|
|
|
|
|
TypeConvert(tmpInst, varType);
|
|
|
|
|
builder->create_store(tmpInst, ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
tmpZero = CONST_FLOAT(0.0);
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0u; i < arraySize; i++) {
|
|
|
|
|
auto index = CONST_INT(i);
|
|
|
|
|
auto ptr = builder->create_gep(identAlloca, {CONST_INT(0), index});
|
|
|
|
|
if ((*varInit)[i] == nullptr) {
|
|
|
|
|
builder->create_store(tmpZero, ptr);
|
|
|
|
|
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);
|
|
|
|
|
Ptr<Constant> tmpZero;
|
|
|
|
|
if (varType->is_integer_type()) {
|
|
|
|
|
tmpZero = CONST_INT(0);
|
|
|
|
|
} else {
|
|
|
|
|
builder->create_store((*varInit)[i], ptr);
|
|
|
|
|
tmpZero = CONST_FLOAT(0.0);
|
|
|
|
|
}
|
|
|
|
|
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(tmpZero, ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -618,9 +635,9 @@ void IRBuilder::visit(SyntaxTree::VarDef &node) {
|
|
|
|
|
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
//std::cout << node.name << std::endl;
|
|
|
|
|
auto ident = scope.find(node.name, false);
|
|
|
|
|
if (!node.array_index.empty()) {
|
|
|
|
|
|
|
|
|
|
/*node.array_index[0]->accept(*this);
|
|
|
|
|
auto constIndex = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
auto globalIdent = dynamic_pointer_cast<GlobalVariable>(ident);
|
|
|
|
@ -631,7 +648,6 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
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;
|
|
|
|
@ -641,26 +657,39 @@ void IRBuilder::visit(SyntaxTree::LVal &node) {
|
|
|
|
|
arrayDimPtr = localIdent->get_array_dim();
|
|
|
|
|
}
|
|
|
|
|
bool index_is_constant = true;
|
|
|
|
|
Ptr<Value> index = CONST_INT(0);
|
|
|
|
|
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(dynamic_pointer_cast<ConstantInt>(tmpInst) != nullptr) {
|
|
|
|
|
//std::cout << dynamic_pointer_cast<ConstantInt>(tmpInst)->get_value() * tmpIndex <<std::endl;
|
|
|
|
|
BinaryExprGen(index, CONST_INT(dynamic_pointer_cast<ConstantInt>(tmpInst)->get_value() * tmpIndex), SyntaxTree::BinOp::PLUS);
|
|
|
|
|
} else {
|
|
|
|
|
index_is_constant = false;
|
|
|
|
|
BinaryExprGen(tmpInst, CONST_INT(tmpIndex), SyntaxTree::BinOp::MULTIPLY);
|
|
|
|
|
BinaryExprGen(index, tmpInst, SyntaxTree::BinOp::PLUS);
|
|
|
|
|
}
|
|
|
|
|
index = tmpInst;
|
|
|
|
|
}
|
|
|
|
|
if(globalIdent != nullptr && globalIdent->is_const() && index_is_constant) {
|
|
|
|
|
auto arrayInit = dynamic_pointer_cast<ConstantArray>(globalIdent->get_init());
|
|
|
|
|
tmpInst = arrayInit->get_element_value(index);
|
|
|
|
|
tmpInst = arrayInit->get_element_value(dynamic_pointer_cast<ConstantInt>(index)->get_value());
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = builder->create_gep(ident, {CONST_INT(0), CONST_INT(index)});
|
|
|
|
|
if(globalIdent != nullptr) {
|
|
|
|
|
tmpInst = builder->create_gep(ident, {CONST_INT(0), index});
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if(localIdent->get_type()->is_pointer_type() && localIdent->get_type()->get_pointer_element_type()->is_pointer_type()) {
|
|
|
|
|
auto trash = builder->create_load(localIdent);
|
|
|
|
|
tmpInst = builder->create_gep(trash, {index});
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = builder->create_gep(ident, {CONST_INT(0), index});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (ident->get_type()->is_pointer_type() && ident->get_type()->get_pointer_element_type()->is_array_type()) {
|
|
|
|
@ -715,8 +744,9 @@ void IRBuilder::visit(SyntaxTree::BlockStmt &node) {
|
|
|
|
|
scope.enter();
|
|
|
|
|
auto i = 0;
|
|
|
|
|
for (const auto &stmt : node.body) {
|
|
|
|
|
//std::cout << stmt->loc <<std::endl;
|
|
|
|
|
stmt->accept(*this);
|
|
|
|
|
//std::cout << i << std::endl;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
scope.exit();
|
|
|
|
|
}
|
|
|
|
@ -737,7 +767,10 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
|
|
|
|
|
auto constInt = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
auto constFloat = dynamic_pointer_cast<ConstantInt>(tmpInst);
|
|
|
|
|
if (constInt == nullptr && constFloat == nullptr) {
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
tmpInst = builder->create_zext(tmpInst, INT32_T);
|
|
|
|
|
tmpInst = builder->create_icmp_eq(tmpInst, CONST_INT(0));
|
|
|
|
|
tmpInst = builder->create_zext(tmpInst, INT32_T);
|
|
|
|
|
} else {
|
|
|
|
|
tmpInst = CONST_INT((constInt->get_value() == 0 || constFloat->get_value() == 0 ) ? 1 : 0);
|
|
|
|
|
}
|
|
|
|
@ -747,42 +780,56 @@ void IRBuilder::visit(SyntaxTree::UnaryCondExpr &node) {
|
|
|
|
|
// FINISH
|
|
|
|
|
void IRBuilder::visit(SyntaxTree::BinaryCondExpr &node) {
|
|
|
|
|
auto curFunc = builder->get_insert_block()->get_parent();
|
|
|
|
|
Ptr<BasicBlock> trueBB;
|
|
|
|
|
Ptr<BasicBlock> falseBB;
|
|
|
|
|
Ptr<Value> tmpLhs;
|
|
|
|
|
Ptr<BasicBlock> lhsTrueBB, lhsFalseBB, trueBB, falseBB;
|
|
|
|
|
trueBB = curCondBlock.trueBB;
|
|
|
|
|
falseBB = curCondBlock.falseBB;
|
|
|
|
|
Ptr<Instruction> cond;
|
|
|
|
|
auto tmpCondBlock = curCondBlock;
|
|
|
|
|
switch (node.op) {
|
|
|
|
|
case SyntaxTree::BinaryCondOp::LAND:
|
|
|
|
|
trueBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
falseBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
lhsTrueBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
lhsFalseBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
curCondBlock = CondBlock{lhsTrueBB, lhsFalseBB};
|
|
|
|
|
node.lhs->accept(*this);
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
tmpLhs = tmpInst;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, trueBB, falseBB);
|
|
|
|
|
builder->create_cond_br(tmpInst, lhsTrueBB, lhsFalseBB);
|
|
|
|
|
|
|
|
|
|
// True - continue
|
|
|
|
|
builder->set_insert_point(trueBB);
|
|
|
|
|
builder->set_insert_point(lhsTrueBB);
|
|
|
|
|
curCondBlock = CondBlock{trueBB, falseBB};
|
|
|
|
|
node.rhs->accept(*this);
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, trueBB, falseBB);
|
|
|
|
|
|
|
|
|
|
// False
|
|
|
|
|
builder->set_insert_point(falseBB);
|
|
|
|
|
builder->set_insert_point(lhsFalseBB);
|
|
|
|
|
tmpInst = tmpLhs;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
|
|
|
|
|
builder->create_br(falseBB);
|
|
|
|
|
break;
|
|
|
|
|
case SyntaxTree::BinaryCondOp::LOR:
|
|
|
|
|
trueBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
falseBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
lhsTrueBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
lhsFalseBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
curCondBlock = CondBlock{lhsTrueBB, lhsFalseBB};
|
|
|
|
|
node.lhs->accept(*this);
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
tmpLhs = tmpInst;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, trueBB, falseBB);
|
|
|
|
|
builder->create_cond_br(tmpInst, lhsTrueBB, lhsFalseBB);
|
|
|
|
|
|
|
|
|
|
// False - continue
|
|
|
|
|
builder->set_insert_point(falseBB);
|
|
|
|
|
builder->set_insert_point(lhsFalseBB);
|
|
|
|
|
curCondBlock = CondBlock{trueBB, falseBB};
|
|
|
|
|
node.rhs->accept(*this);
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, trueBB, falseBB);
|
|
|
|
|
|
|
|
|
|
// True
|
|
|
|
|
builder->set_insert_point(trueBB);
|
|
|
|
|
builder->set_insert_point(lhsTrueBB);
|
|
|
|
|
tmpInst = tmpLhs;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_br(trueBB);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
node.lhs->accept(*this);
|
|
|
|
@ -851,9 +898,10 @@ void IRBuilder::visit(SyntaxTree::IfStmt &node) {
|
|
|
|
|
auto trueBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
auto falseBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
auto afterBB = node.else_statement == nullptr ? falseBB : BasicBlock::create(module, "", curFunc);
|
|
|
|
|
|
|
|
|
|
auto tmpCondBlock = curCondBlock;
|
|
|
|
|
curCondBlock = CondBlock{trueBB, falseBB};
|
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
|
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, trueBB, falseBB);
|
|
|
|
|
|
|
|
|
@ -880,18 +928,18 @@ void IRBuilder::visit(SyntaxTree::WhileStmt &node) {
|
|
|
|
|
auto afterBB = BasicBlock::create(module, "", curFunc);
|
|
|
|
|
auto tmpWhileBlock = curWhileBlock;
|
|
|
|
|
curWhileBlock = WhileBlock{condBB, bodyBB, afterBB};
|
|
|
|
|
|
|
|
|
|
builder->create_br(condBB);
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(condBB);
|
|
|
|
|
auto tmpCondBlock = curCondBlock;
|
|
|
|
|
curCondBlock = CondBlock{bodyBB, afterBB};
|
|
|
|
|
node.cond_exp->accept(*this);
|
|
|
|
|
curCondBlock = tmpCondBlock;
|
|
|
|
|
TypeConvert(tmpInst, INT1_T);
|
|
|
|
|
builder->create_cond_br(tmpInst, bodyBB, afterBB);
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(bodyBB);
|
|
|
|
|
node.statement->accept(*this);
|
|
|
|
|
builder->create_br(condBB);
|
|
|
|
|
|
|
|
|
|
builder->set_insert_point(afterBB);
|
|
|
|
|
curWhileBlock = tmpWhileBlock;
|
|
|
|
|
}
|
|
|
|
|