functional all pass
This commit is contained in:
parent
0bc5ea8f10
commit
57094c9afe
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,4 +2,5 @@ build/
|
|||||||
.antlr/
|
.antlr/
|
||||||
*.log
|
*.log
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.o
|
*.o
|
||||||
|
testcases/
|
||||||
@ -219,7 +219,7 @@ public:
|
|||||||
if (pointed_type->type_tag == Type::TypeTag::IntegerType) {
|
if (pointed_type->type_tag == Type::TypeTag::IntegerType) {
|
||||||
return pointed_type;
|
return pointed_type;
|
||||||
}
|
}
|
||||||
else if (Type::isType<ArrayType>(pointed_type)){
|
else if (Type::isType<ArrayType>(pointed_type)) {
|
||||||
for (int i = 1; i < indices.size(); ++i) {
|
for (int i = 1; i < indices.size(); ++i) {
|
||||||
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -167,8 +167,13 @@ public:
|
|||||||
bool is_const;
|
bool is_const;
|
||||||
GlobalVar(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const)
|
GlobalVar(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const)
|
||||||
: Value(name, PointerType::make_shared(type)), init_value(init_value), is_const(is_const) {}
|
: Value(name, PointerType::make_shared(type)), init_value(init_value), is_const(is_const) {}
|
||||||
static std::shared_ptr<GlobalVar> make_shared(const std::string &name, TypePtr_t type, ConstantPtr_t init_value, bool is_const) {
|
static std::shared_ptr<GlobalVar> make_shared(
|
||||||
return std::make_shared<GlobalVar>(name, type ,init_value, is_const);
|
const std::string &name,
|
||||||
|
TypePtr_t type,
|
||||||
|
ConstantPtr_t init_value,
|
||||||
|
bool is_const
|
||||||
|
) {
|
||||||
|
return std::make_shared<GlobalVar>(name, type, init_value, is_const);
|
||||||
}
|
}
|
||||||
virtual std::string to_IR_string() override {
|
virtual std::string to_IR_string() override {
|
||||||
std::string str = type->to_IR_string() + " @" + name;
|
std::string str = type->to_IR_string() + " @" + name;
|
||||||
|
|||||||
@ -41,7 +41,11 @@ std::shared_ptr<InstStore> build_InstStore(
|
|||||||
std::shared_ptr<BasicBlock> parent_bb
|
std::shared_ptr<BasicBlock> parent_bb
|
||||||
);
|
);
|
||||||
|
|
||||||
std::shared_ptr<InstAlloca> build_InstAlloca(const std::string &str, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb);
|
std::shared_ptr<InstAlloca> build_InstAlloca(
|
||||||
|
const std::string &str,
|
||||||
|
TypePtr_t type,
|
||||||
|
std::shared_ptr<BasicBlock> parent_bb
|
||||||
|
);
|
||||||
|
|
||||||
std::shared_ptr<InstBinary> build_InstBinary(
|
std::shared_ptr<InstBinary> build_InstBinary(
|
||||||
InstTag inst_tag,
|
InstTag inst_tag,
|
||||||
|
|||||||
@ -193,6 +193,7 @@ class BatTest:
|
|||||||
self.diffout_template = f"{compiler.target_dir}/{{testcase}}/{self.label}.diff"
|
self.diffout_template = f"{compiler.target_dir}/{{testcase}}/{self.label}.diff"
|
||||||
|
|
||||||
def bat_case(self, testcase, compile=False):
|
def bat_case(self, testcase, compile=False):
|
||||||
|
Print_C.print_subheader(f"Diff test {self.label} on {testcase}")
|
||||||
if compile:
|
if compile:
|
||||||
self.compiler.clean_case(testcase)
|
self.compiler.clean_case(testcase)
|
||||||
self.compiler_rf.clean_case(testcase)
|
self.compiler_rf.clean_case(testcase)
|
||||||
@ -212,6 +213,7 @@ class BatTest:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def bat_all_tests(self, compile=False):
|
def bat_all_tests(self, compile=False):
|
||||||
|
|
||||||
for testcase in self.testcases:
|
for testcase in self.testcases:
|
||||||
if not self.bat_case(testcase, compile): break
|
if not self.bat_case(testcase, compile): break
|
||||||
|
|
||||||
@ -254,7 +256,7 @@ if __name__ == "__main__":
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
print(args)
|
print(args)
|
||||||
testcases = case_collector(args.case_selector, args.case_prefix)
|
testcases = case_collector(args.case_selector, args.case_prefix)
|
||||||
target_dir = os.path.join(BUILD_DIR, args.case_prefix)
|
target_dir = os.path.join(BUILD_DIR, args.case_prefix.replace("../", "").replace("./", ""))
|
||||||
if args.clean:
|
if args.clean:
|
||||||
os.system(f"rm -rfI {target_dir}")
|
os.system(f"rm -rfI {target_dir}")
|
||||||
if not os.path.exists(target_dir):
|
if not os.path.exists(target_dir):
|
||||||
|
|||||||
@ -95,7 +95,7 @@ Visitor::Visitor(SysyLexer &) {
|
|||||||
_func_tab.push_name("putch", func_putch);
|
_func_tab.push_name("putch", func_putch);
|
||||||
|
|
||||||
auto func_putarray = std::make_shared<Function>("putarray", TypeHelper::TYPE_VOID);
|
auto func_putarray = std::make_shared<Function>("putarray", TypeHelper::TYPE_VOID);
|
||||||
func_putarray->fparam_list = {fparam_ptr_i32, fparam_i32};
|
func_putarray->fparam_list = {fparam_i32, fparam_ptr_i32};
|
||||||
_func_tab.push_name("putarray", func_putarray);
|
_func_tab.push_name("putarray", func_putarray);
|
||||||
|
|
||||||
// auto func_putf = std::make_shared<Function>("putf", TypeHelper::TYPE_VOID);
|
// auto func_putf = std::make_shared<Function>("putf", TypeHelper::TYPE_VOID);
|
||||||
@ -152,7 +152,7 @@ std::any Visitor::visitConstDef(SysyParser::ConstDefContext *ctx) {
|
|||||||
if (_scope_tab.get_level()) {
|
if (_scope_tab.get_level()) {
|
||||||
// local const array
|
// local const array
|
||||||
// Keep a pointer to the base address, alloca_ = &array, *alloca_ = &array[0]
|
// Keep a pointer to the base address, alloca_ = &array, *alloca_ = &array[0]
|
||||||
auto alloca_ = build_InstAlloca(const_name , array_type, _state.current_bb);
|
auto alloca_ = build_InstAlloca(const_name, array_type, _state.current_bb);
|
||||||
_scope_tab.push_name(const_name, alloca_);
|
_scope_tab.push_name(const_name, alloca_);
|
||||||
// first dim base, ptr = *alloca_ = &array[0]
|
// first dim base, ptr = *alloca_ = &array[0]
|
||||||
auto base_ptr = build_InstGEP(alloca_, {CONST0, CONST0}, _state.current_bb);
|
auto base_ptr = build_InstGEP(alloca_, {CONST0, CONST0}, _state.current_bb);
|
||||||
@ -193,12 +193,12 @@ std::any Visitor::visitVarDef(SysyParser::VarDefContext *ctx) {
|
|||||||
_state.isGlobalIint = true;
|
_state.isGlobalIint = true;
|
||||||
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitInitVal(ctx->initVal()));
|
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitInitVal(ctx->initVal()));
|
||||||
_state.isGlobalIint = false;
|
_state.isGlobalIint = false;
|
||||||
auto global_var_int = GlobalVar::make_shared(var_name, result->type,result, false);
|
auto global_var_int = GlobalVar::make_shared(var_name, result->type, result, false);
|
||||||
module.global_var_list.push_back(global_var_int);
|
module.global_var_list.push_back(global_var_int);
|
||||||
_scope_tab.push_name(var_name, global_var_int);
|
_scope_tab.push_name(var_name, global_var_int);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto global_var_int = GlobalVar::make_shared(var_name, CONST0->type,CONST0, false);
|
auto global_var_int = GlobalVar::make_shared(var_name, CONST0->type, CONST0, false);
|
||||||
module.global_var_list.push_back(global_var_int);
|
module.global_var_list.push_back(global_var_int);
|
||||||
_scope_tab.push_name(var_name, global_var_int);
|
_scope_tab.push_name(var_name, global_var_int);
|
||||||
}
|
}
|
||||||
@ -393,9 +393,9 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) {
|
|||||||
return {result};
|
return {result};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp()));
|
|
||||||
if (ctx->addExp()) {
|
if (ctx->addExp()) {
|
||||||
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
||||||
|
auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp()));
|
||||||
if (std::dynamic_pointer_cast<IntegerType>(add_exp->type)->isI1()) {
|
if (std::dynamic_pointer_cast<IntegerType>(add_exp->type)->isI1()) {
|
||||||
add_exp = build_InstZext(add_exp, _state.current_bb);
|
add_exp = build_InstZext(add_exp, _state.current_bb);
|
||||||
}
|
}
|
||||||
@ -410,8 +410,11 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
panic("Unreachable");
|
panic("Unreachable");
|
||||||
|
return mul_exp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return visitMulExp(ctx->mulExp());
|
||||||
}
|
}
|
||||||
return mul_exp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,9 +438,9 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) {
|
|||||||
return {result};
|
return {result};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto unary_exp = any_to_Value(visitUnaryExp(ctx->unaryExp()));
|
|
||||||
if (ctx->mulExp()) {
|
if (ctx->mulExp()) {
|
||||||
auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp()));
|
auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp()));
|
||||||
|
auto unary_exp = any_to_Value(visitUnaryExp(ctx->unaryExp()));
|
||||||
if (std::dynamic_pointer_cast<IntegerType>(unary_exp->type)->isI1()) {
|
if (std::dynamic_pointer_cast<IntegerType>(unary_exp->type)->isI1()) {
|
||||||
unary_exp = build_InstZext(unary_exp, _state.current_bb);
|
unary_exp = build_InstZext(unary_exp, _state.current_bb);
|
||||||
}
|
}
|
||||||
@ -455,15 +458,18 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
panic("Unreachable");
|
panic("Unreachable");
|
||||||
|
return {unary_exp};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return visitUnaryExp(ctx->unaryExp());
|
||||||
}
|
}
|
||||||
return {unary_exp};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
|
// relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
|
||||||
std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
||||||
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
|
||||||
if (ctx->relExp()) {
|
if (ctx->relExp()) {
|
||||||
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
||||||
|
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
||||||
sysy_assert(TypeHelper::isIntegerTypeI32(rel_exp->type));
|
sysy_assert(TypeHelper::isIntegerTypeI32(rel_exp->type));
|
||||||
if (ctx->LE()) {
|
if (ctx->LE()) {
|
||||||
add_exp = build_InstBinary(InstTag::Le, rel_exp, add_exp, _state.current_bb);
|
add_exp = build_InstBinary(InstTag::Le, rel_exp, add_exp, _state.current_bb);
|
||||||
@ -481,16 +487,19 @@ std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
|||||||
LOG(ERROR) << ctx->relExp()->getStart()->getLine() << ":" << ctx->relExp()->getText();
|
LOG(ERROR) << ctx->relExp()->getStart()->getLine() << ":" << ctx->relExp()->getText();
|
||||||
panic("Unreachable");
|
panic("Unreachable");
|
||||||
}
|
}
|
||||||
|
return add_exp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return visitAddExp(ctx->addExp());
|
||||||
}
|
}
|
||||||
return add_exp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// eqExp: relExp | eqExp ('==' | '!=') relExp;
|
// eqExp: relExp | eqExp ('==' | '!=') relExp;
|
||||||
std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
||||||
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
|
||||||
bool need_zext = false;
|
|
||||||
if (ctx->eqExp()) {
|
if (ctx->eqExp()) {
|
||||||
auto eq_exp = any_to_Value(visitEqExp(ctx->eqExp()));
|
bool need_zext = false;
|
||||||
|
auto eq_exp = any_to_Value(visitEqExp(ctx->eqExp()));
|
||||||
|
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
||||||
if (TypeHelper::isIntegerTypeI32(eq_exp->type) || TypeHelper::isIntegerTypeI32(rel_exp->type)) {
|
if (TypeHelper::isIntegerTypeI32(eq_exp->type) || TypeHelper::isIntegerTypeI32(rel_exp->type)) {
|
||||||
need_zext = true;
|
need_zext = true;
|
||||||
}
|
}
|
||||||
@ -508,12 +517,16 @@ std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
panic("Unreachable");
|
panic("Unreachable");
|
||||||
|
return rel_exp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return visitRelExp(ctx->relExp());
|
||||||
}
|
}
|
||||||
return rel_exp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notes about SideEffect: except for || and &&, other sub-expression evaluations are unsequenced
|
// Notes about SideEffect: except for || and &&, other sub-expression evaluations are unsequenced
|
||||||
// as long as they are calculated before the operator
|
// as long as they are calculated before the operator
|
||||||
|
// BUT, in sysy test, it seems that, it is a must ti compute from left to right
|
||||||
// lAndExp: eqExp | lAndExp '&&' eqExp;
|
// lAndExp: eqExp | lAndExp '&&' eqExp;
|
||||||
// Luckily, there is only one path to lOrExp, which is `stmt` -> `cond` -> `lOrExp`
|
// Luckily, there is only one path to lOrExp, which is `stmt` -> `cond` -> `lOrExp`
|
||||||
// Thus, there is no need to care about what if it appears in a arithmetic expression
|
// Thus, there is no need to care about what if it appears in a arithmetic expression
|
||||||
@ -729,8 +742,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
|||||||
return lval;
|
return lval;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(WARNING) << "Unexpected array referece" << lval->to_string()
|
LOG(WARNING) << "Unexpected array referece" << lval->to_string() << " : " << ctx->getStart()->getLine();
|
||||||
<< " : "<< ctx->getStart()->getLine();
|
|
||||||
// array index, perhaps
|
// array index, perhaps
|
||||||
// @retval: InstGEP
|
// @retval: InstGEP
|
||||||
auto gep = lval;
|
auto gep = lval;
|
||||||
@ -793,7 +805,9 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
|||||||
return arr_elem_ptr;
|
return arr_elem_ptr;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic("Should be int");
|
LOG(WARNING) << "Should be int";
|
||||||
|
auto arr_ptr = build_InstGEP(ptr, {CONST0, offset}, _state.current_bb);
|
||||||
|
return arr_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -833,7 +847,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
|||||||
// return the address of an sub array
|
// return the address of an sub array
|
||||||
auto array_type = std::dynamic_pointer_cast<ArrayType>(pointed_type);
|
auto array_type = std::dynamic_pointer_cast<ArrayType>(pointed_type);
|
||||||
auto dim_size = ConstantInt::make_shared(array_type->element_count);
|
auto dim_size = ConstantInt::make_shared(array_type->element_count);
|
||||||
auto inst_mul = build_InstBinary(InstTag::Mul, offset, dim_size, _state.current_bb);
|
offset = build_InstBinary(InstTag::Mul, offset, dim_size, _state.current_bb);
|
||||||
auto arr_elem_ptr = build_InstGEP(ptr, {CONST0, offset}, _state.current_bb);
|
auto arr_elem_ptr = build_InstGEP(ptr, {CONST0, offset}, _state.current_bb);
|
||||||
return arr_elem_ptr;
|
return arr_elem_ptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,10 +43,15 @@ std::shared_ptr<InstStore> build_InstStore(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// a little bit different, we put all alloca in the head of each basic block
|
// a little bit different, we put all alloca in the head of each basic block
|
||||||
std::shared_ptr<InstAlloca> build_InstAlloca(const std::string & name, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb) {
|
std::shared_ptr<InstAlloca> build_InstAlloca(
|
||||||
auto inst_alloca = std::make_shared<InstAlloca>(type, parent_bb);
|
const std::string &name,
|
||||||
|
TypePtr_t type,
|
||||||
|
std::shared_ptr<BasicBlock> parent_bb
|
||||||
|
) {
|
||||||
|
auto inst_alloca = std::make_shared<InstAlloca>(type, parent_bb);
|
||||||
inst_alloca->name = name;
|
inst_alloca->name = name;
|
||||||
parent_bb->inst_list.insert(parent_bb->inst_list.begin(), inst_alloca);
|
auto func_head_bb = parent_bb->parent->bb_list.front();
|
||||||
|
func_head_bb->inst_list.insert(func_head_bb->inst_list.begin(), inst_alloca);
|
||||||
// parent_bb->inst_list.push_back(inst_alloca);
|
// parent_bb->inst_list.push_back(inst_alloca);
|
||||||
return inst_alloca;
|
return inst_alloca;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -153,6 +153,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list<BasicBlockPtr_t> &bl
|
|||||||
ostr << block->ir_seqno << ":" << std::endl;
|
ostr << block->ir_seqno << ":" << std::endl;
|
||||||
}
|
}
|
||||||
for (int j = 0; j < block->inst_list.size(); ++j) {
|
for (int j = 0; j < block->inst_list.size(); ++j) {
|
||||||
|
ostr << " ";
|
||||||
auto _inst = block->inst_list[j];
|
auto _inst = block->inst_list[j];
|
||||||
VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string();
|
VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string();
|
||||||
switch (_inst->tag) {
|
switch (_inst->tag) {
|
||||||
@ -251,6 +252,7 @@ static void _gen_blocks(std::ostream &ostr, const std::list<BasicBlockPtr_t> &bl
|
|||||||
LOG(ERROR) << "Unexpected type of op1: " << inst->operand_list[1]->to_string();
|
LOG(ERROR) << "Unexpected type of op1: " << inst->operand_list[1]->to_string();
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
ostr << ", align 4";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Call's seqno is dependent on its return type
|
// Call's seqno is dependent on its return type
|
||||||
@ -470,8 +472,8 @@ void Visitor::llir_gen(std::ostream &ostr) {
|
|||||||
}
|
}
|
||||||
else if (global_var_type->pointed_type->type_tag == Type::TypeTag::ArrayType) {
|
else if (global_var_type->pointed_type->type_tag == Type::TypeTag::ArrayType) {
|
||||||
// sysy_assert(global_var->)
|
// sysy_assert(global_var->)
|
||||||
auto array_type = std::dynamic_pointer_cast<ArrayType>(global_var_type->pointed_type);
|
auto array_type = std::dynamic_pointer_cast<ArrayType>(global_var_type->pointed_type);
|
||||||
auto init_value = std::dynamic_pointer_cast<ConstantArr>(global_var->init_value);
|
auto init_value = std::dynamic_pointer_cast<ConstantArr>(global_var->init_value);
|
||||||
if (init_value != nullptr) {
|
if (init_value != nullptr) {
|
||||||
auto hierarchy_array = gen_arr_hierarchy(array_type, init_value->value_list, 0, init_value->value_list.size());
|
auto hierarchy_array = gen_arr_hierarchy(array_type, init_value->value_list, 0, init_value->value_list.size());
|
||||||
if (hierarchy_array) {
|
if (hierarchy_array) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user