#include "common.h" #include "llir.h" #include "visitor.h" #include #include namespace CompSysY { std::shared_ptr build_ConstantInt(const std::string &name, int value) { auto lala = std::make_shared(name, value); return lala; } std::shared_ptr build_BasicBlock( const std::string &name, std::shared_ptr parent, const BasicBlockListNode_t &cur_bb_itr ) { static int count = 0; auto basic_block = std::make_shared("blk" + std::to_string(count++), parent); basic_block->itr = parent->bb_list.insert(std::next(cur_bb_itr), basic_block); return basic_block; } std::shared_ptr build_InstLoad( std::shared_ptr value, TypePtr_t type, std::shared_ptr parent_bb ) { auto inst = std::make_shared(value, type, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstStore( std::shared_ptr value, std::shared_ptr pointer, std::shared_ptr parent_bb ) { auto inst = std::make_shared(value, pointer, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } // a little bit different, we put all alloca in the head of each basic block std::shared_ptr build_InstAlloca( const std::string &name, TypePtr_t type, std::shared_ptr parent_bb ) { auto inst = std::make_shared(type, parent_bb); inst->name = name; auto func_head_bb = parent_bb->parent->bb_list.front(); inst->inst_itr = func_head_bb->inst_list.insert(func_head_bb->inst_list.begin(), inst); // parent_bb->inst_list.push_back(inst_alloca); return inst; } std::shared_ptr build_InstBinary( InstTag inst_tag, std::shared_ptr op1, std::shared_ptr op2, std::shared_ptr parent_bb ) { std::shared_ptr inst; if (InstTag::Lt <= inst_tag && inst_tag <= InstTag::Ne) { inst = std::make_shared(inst_tag, TypeHelper::TYPE_I1, op1, op2, parent_bb); } else if (InstTag::Add <= inst_tag && inst_tag <= InstTag::Div) { inst = std::make_shared(inst_tag, TypeHelper::TYPE_I32, op1, op2, parent_bb); } else { panic("Invalid Binary Operation"); } assert(Type::isType(op1->type)); assert(Type::isType(op2->type)); if (!(Type::asType(op1->type)->int_type == Type::asType(op2->type)->int_type)) { if (!(Value::is(op1) && Value::as(op1)->value == 0) && !(Value::is(op2) && Value::as(op2)->value == 0)) { LOG(ERROR) << op1->to_string() << ",\t" << op2->to_string(); assert(0); } } inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstZext(std::shared_ptr op, std::shared_ptr parent_bb) { auto inst = std::make_shared(op, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstBranch( ValuePtr_t cond, BasicBlockPtr_t true_block, BasicBlockPtr_t false_block, BasicBlockPtr_t parent_bb ) { auto inst = std::make_shared(cond, true_block, false_block, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb) { auto inst = std::make_shared(target_block, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb) { auto inst = std::make_shared(ret_val, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstReturn(BasicBlockPtr_t parent_bb) { auto inst = std::make_shared(parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstCall( FunctionPtr_t func, const std::vector &args, BasicBlockPtr_t parent_bb ) { auto inst = std::make_shared(func, args, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } std::shared_ptr build_InstGEP( ValuePtr_t pointer, const std::vector &indices, BasicBlockPtr_t parent_bb ) { auto inst = std::make_shared(pointer, indices, parent_bb); inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst); return inst; } InstPhiPtr_t build_InstPhi( TypePtr_t type, const decltype(Function::bb_list) &incoming_vals, BasicBlockPtr_t parent_bb, const std::string &name ) { auto inst = std::make_shared(type, incoming_vals, parent_bb); inst->name = name; inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.begin(), inst); return inst; } } // namespace CompSysY