functional all pass
This commit is contained in:
parent
0bc5ea8f10
commit
57094c9afe
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,4 +2,5 @@ build/
|
||||
.antlr/
|
||||
*.log
|
||||
__pycache__/
|
||||
*.o
|
||||
*.o
|
||||
testcases/
|
||||
@ -219,7 +219,7 @@ public:
|
||||
if (pointed_type->type_tag == Type::TypeTag::IntegerType) {
|
||||
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) {
|
||||
pointed_type = std::dynamic_pointer_cast<ArrayType>(pointed_type)->element_type;
|
||||
}
|
||||
|
||||
@ -167,8 +167,13 @@ public:
|
||||
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) {}
|
||||
static std::shared_ptr<GlobalVar> make_shared(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);
|
||||
static std::shared_ptr<GlobalVar> make_shared(
|
||||
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 {
|
||||
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<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(
|
||||
InstTag inst_tag,
|
||||
|
||||
@ -193,6 +193,7 @@ class BatTest:
|
||||
self.diffout_template = f"{compiler.target_dir}/{{testcase}}/{self.label}.diff"
|
||||
|
||||
def bat_case(self, testcase, compile=False):
|
||||
Print_C.print_subheader(f"Diff test {self.label} on {testcase}")
|
||||
if compile:
|
||||
self.compiler.clean_case(testcase)
|
||||
self.compiler_rf.clean_case(testcase)
|
||||
@ -212,6 +213,7 @@ class BatTest:
|
||||
return True
|
||||
|
||||
def bat_all_tests(self, compile=False):
|
||||
|
||||
for testcase in self.testcases:
|
||||
if not self.bat_case(testcase, compile): break
|
||||
|
||||
@ -254,7 +256,7 @@ if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
print(args)
|
||||
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:
|
||||
os.system(f"rm -rfI {target_dir}")
|
||||
if not os.path.exists(target_dir):
|
||||
|
||||
@ -95,7 +95,7 @@ Visitor::Visitor(SysyLexer &) {
|
||||
_func_tab.push_name("putch", func_putch);
|
||||
|
||||
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);
|
||||
|
||||
// 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()) {
|
||||
// local const array
|
||||
// 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_);
|
||||
// first dim base, ptr = *alloca_ = &array[0]
|
||||
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;
|
||||
auto result = std::any_cast<std::shared_ptr<ConstantInt>>(visitInitVal(ctx->initVal()));
|
||||
_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);
|
||||
_scope_tab.push_name(var_name, global_var_int);
|
||||
}
|
||||
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);
|
||||
_scope_tab.push_name(var_name, global_var_int);
|
||||
}
|
||||
@ -393,9 +393,9 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) {
|
||||
return {result};
|
||||
}
|
||||
else {
|
||||
auto mul_exp = any_to_Value(visitMulExp(ctx->mulExp()));
|
||||
if (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()) {
|
||||
add_exp = build_InstZext(add_exp, _state.current_bb);
|
||||
}
|
||||
@ -410,8 +410,11 @@ std::any Visitor::visitAddExp(SysyParser::AddExpContext *ctx) {
|
||||
}
|
||||
else
|
||||
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};
|
||||
}
|
||||
else {
|
||||
auto unary_exp = any_to_Value(visitUnaryExp(ctx->unaryExp()));
|
||||
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()) {
|
||||
unary_exp = build_InstZext(unary_exp, _state.current_bb);
|
||||
}
|
||||
@ -455,15 +458,18 @@ std::any Visitor::visitMulExp(SysyParser::MulExpContext *ctx) {
|
||||
}
|
||||
else
|
||||
panic("Unreachable");
|
||||
return {unary_exp};
|
||||
}
|
||||
else {
|
||||
return visitUnaryExp(ctx->unaryExp());
|
||||
}
|
||||
return {unary_exp};
|
||||
}
|
||||
}
|
||||
// relExp: addExp | relExp ('<' | '>' | '<=' | '>=') addExp;
|
||||
std::any Visitor::visitRelExp(SysyParser::RelExpContext *ctx) {
|
||||
auto add_exp = any_to_Value(visitAddExp(ctx->addExp()));
|
||||
if (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));
|
||||
if (ctx->LE()) {
|
||||
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();
|
||||
panic("Unreachable");
|
||||
}
|
||||
return add_exp;
|
||||
}
|
||||
else {
|
||||
return visitAddExp(ctx->addExp());
|
||||
}
|
||||
return add_exp;
|
||||
}
|
||||
|
||||
// eqExp: relExp | eqExp ('==' | '!=') relExp;
|
||||
std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
||||
auto rel_exp = any_to_Value(visitRelExp(ctx->relExp()));
|
||||
bool need_zext = false;
|
||||
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)) {
|
||||
need_zext = true;
|
||||
}
|
||||
@ -508,12 +517,16 @@ std::any Visitor::visitEqExp(SysyParser::EqExpContext *ctx) {
|
||||
}
|
||||
else
|
||||
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
|
||||
// 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;
|
||||
// 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
|
||||
@ -729,8 +742,7 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
return lval;
|
||||
}
|
||||
else {
|
||||
LOG(WARNING) << "Unexpected array referece" << lval->to_string()
|
||||
<< " : "<< ctx->getStart()->getLine();
|
||||
LOG(WARNING) << "Unexpected array referece" << lval->to_string() << " : " << ctx->getStart()->getLine();
|
||||
// array index, perhaps
|
||||
// @retval: InstGEP
|
||||
auto gep = lval;
|
||||
@ -793,7 +805,9 @@ std::any Visitor::visitLVal(SysyParser::LValContext *ctx) {
|
||||
return arr_elem_ptr;
|
||||
}
|
||||
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
|
||||
auto array_type = std::dynamic_pointer_cast<ArrayType>(pointed_type);
|
||||
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);
|
||||
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
|
||||
std::shared_ptr<InstAlloca> build_InstAlloca(const std::string & name, TypePtr_t type, std::shared_ptr<BasicBlock> parent_bb) {
|
||||
auto inst_alloca = std::make_shared<InstAlloca>(type, parent_bb);
|
||||
std::shared_ptr<InstAlloca> build_InstAlloca(
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
}
|
||||
for (int j = 0; j < block->inst_list.size(); ++j) {
|
||||
ostr << " ";
|
||||
auto _inst = block->inst_list[j];
|
||||
VLOG(5) << "Build inst" << _inst->ir_seqno << ": " << _inst->to_string();
|
||||
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();
|
||||
assert(0);
|
||||
}
|
||||
ostr << ", align 4";
|
||||
break;
|
||||
}
|
||||
// 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) {
|
||||
// sysy_assert(global_var->)
|
||||
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 array_type = std::dynamic_pointer_cast<ArrayType>(global_var_type->pointed_type);
|
||||
auto init_value = std::dynamic_pointer_cast<ConstantArr>(global_var->init_value);
|
||||
if (init_value != nullptr) {
|
||||
auto hierarchy_array = gen_arr_hierarchy(array_type, init_value->value_list, 0, init_value->value_list.size());
|
||||
if (hierarchy_array) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user