main
Odeinjul 11 months ago
parent 83af6e842e
commit 82919f4ede
No known key found for this signature in database
GPG Key ID: E384228B2B38FFBB

@ -3,13 +3,13 @@ int bubblesort(int arr[])
{ {
int i; int i;
int j; int j;
i =0; i =0;
while(i < n-1){ while(i < n-1){
// Last i elements are already in place // Last i elements are already in place
j = 0; j = 0;
while(j < n-i-1){ while(j < n-i-1){
if (arr[j] > arr[j+1]) { if (arr[j] > arr[j+1]) {
// swap(&arr[j], &arr[j+1]); // swap(&arr[j], &arr[j+1]);
int tmp; int tmp;
tmp = arr[j+1]; tmp = arr[j+1];
arr[j+1] = arr[j]; arr[j+1] = arr[j];

@ -7,10 +7,13 @@ ExeGen_ptn = '"clang" "{}" "-o" "{}" "{}" "../../lib/lib.c"'
Exe_ptn = '"{}"' Exe_ptn = '"{}"'
def eval(EXE_PATH, TEST_BASE_PATH, optimization): def eval(EXE_PATH, TEST_BASE_PATH, optimization):
cnt = 0
passed = 0
print('===========TEST START===========') print('===========TEST START===========')
print('now in {}'.format(TEST_BASE_PATH)) print('now in {}'.format(TEST_BASE_PATH))
dir_succ = True dir_succ = True
for case in testcases: for case in testcases:
cnt += 1
print('Case %s:' % case, end='') print('Case %s:' % case, end='')
TEST_PATH = TEST_BASE_PATH + case TEST_PATH = TEST_BASE_PATH + case
SY_PATH = TEST_BASE_PATH + case + '.sy' SY_PATH = TEST_BASE_PATH + case + '.sy'
@ -49,6 +52,7 @@ def eval(EXE_PATH, TEST_BASE_PATH, optimization):
case_succ = False case_succ = False
i = i + 1 i = i + 1
if case_succ: if case_succ:
passed += 1
print('\t\033[32mPass\033[0m') print('\t\033[32mPass\033[0m')
else: else:
print('\t\033[31mWrong Answer\033[0m') print('\t\033[31mWrong Answer\033[0m')
@ -68,7 +72,7 @@ def eval(EXE_PATH, TEST_BASE_PATH, optimization):
print('\t\033[32mSuccess\033[0m in dir {}'.format(TEST_BASE_PATH)) print('\t\033[32mSuccess\033[0m in dir {}'.format(TEST_BASE_PATH))
else: else:
print('\t\033[31mFail\033[0m in dir {}'.format(TEST_BASE_PATH)) print('\t\033[31mFail\033[0m in dir {}'.format(TEST_BASE_PATH))
print(f'\t\033[32mPassed: {passed}, Total: {cnt} \033[0m')
print('============TEST END============') print('============TEST END============')
@ -81,7 +85,7 @@ if __name__ == "__main__":
] ]
# you can only modify this to add your testcase # you can only modify this to add your testcase
optimization = "-O0" # -O0 -O1 -O2 -O3 -O4(currently = -O3) -Ofast optimization = "-O3" # -O0 -O1 -O2 -O3 -O4(currently = -O3) -Ofast
for TEST_BASE_PATH in TEST_DIRS: for TEST_BASE_PATH in TEST_DIRS:
testcases = {} # { name: need_input } testcases = {} # { name: need_input }
EXE_PATH = os.path.abspath('../../build/SysYFCompiler') EXE_PATH = os.path.abspath('../../build/SysYFCompiler')

@ -78,7 +78,7 @@ make
当需要对 sy 文件测试时,可以这样使用: 当需要对 sy 文件测试时,可以这样使用:
```sh ```sh
SysYFCompiler test.sy -emit-ir -o test.ll SysYFCompiler test.c -emit-ir -o test.ll
``` ```
得到对应的ll文件。 得到对应的ll文件。

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

Loading…
Cancel
Save