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

@ -7,10 +7,13 @@ ExeGen_ptn = '"clang" "{}" "-o" "{}" "{}" "../../lib/lib.c"'
Exe_ptn = '"{}"'
def eval(EXE_PATH, TEST_BASE_PATH, optimization):
cnt = 0
passed = 0
print('===========TEST START===========')
print('now in {}'.format(TEST_BASE_PATH))
dir_succ = True
for case in testcases:
cnt += 1
print('Case %s:' % case, end='')
TEST_PATH = TEST_BASE_PATH + case
SY_PATH = TEST_BASE_PATH + case + '.sy'
@ -49,6 +52,7 @@ def eval(EXE_PATH, TEST_BASE_PATH, optimization):
case_succ = False
i = i + 1
if case_succ:
passed += 1
print('\t\033[32mPass\033[0m')
else:
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))
else:
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============')
@ -81,7 +85,7 @@ if __name__ == "__main__":
]
# 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:
testcases = {} # { name: need_input }
EXE_PATH = os.path.abspath('../../build/SysYFCompiler')

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

@ -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;
}

Loading…
Cancel
Save