155 lines
5.2 KiB
C++
155 lines
5.2 KiB
C++
#include "common.h"
|
|
#include "llir.h"
|
|
#include "visitor.h"
|
|
#include <cassert>
|
|
#include <memory>
|
|
|
|
namespace CompSysY {
|
|
|
|
std::shared_ptr<ConstantInt> build_ConstantInt(const std::string &name, int value) {
|
|
auto lala = std::make_shared<ConstantInt>(name, value);
|
|
return lala;
|
|
}
|
|
|
|
std::shared_ptr<BasicBlock> build_BasicBlock(
|
|
const std::string &name,
|
|
std::shared_ptr<Function> parent,
|
|
const BasicBlockListNode_t &cur_bb_itr
|
|
) {
|
|
static int count = 0;
|
|
auto basic_block = std::make_shared<BasicBlock>("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<InstLoad> build_InstLoad(
|
|
std::shared_ptr<Value> value,
|
|
TypePtr_t type,
|
|
std::shared_ptr<BasicBlock> parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstLoad>(value, type, parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstStore> build_InstStore(
|
|
std::shared_ptr<Value> value,
|
|
std::shared_ptr<Value> pointer,
|
|
std::shared_ptr<BasicBlock> parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstStore>(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<InstAlloca> build_InstAlloca(
|
|
const std::string &name,
|
|
TypePtr_t type,
|
|
std::shared_ptr<BasicBlock> parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstAlloca>(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<InstBinary> build_InstBinary(
|
|
InstTag inst_tag,
|
|
std::shared_ptr<Value> op1,
|
|
std::shared_ptr<Value> op2,
|
|
std::shared_ptr<BasicBlock> parent_bb
|
|
) {
|
|
std::shared_ptr<InstBinary> inst;
|
|
if (InstTag::Lt <= inst_tag && inst_tag <= InstTag::Ne) {
|
|
inst = std::make_shared<InstBinary>(inst_tag, TypeHelper::TYPE_I1, op1, op2, parent_bb);
|
|
}
|
|
else if (InstTag::Add <= inst_tag && inst_tag <= InstTag::Div) {
|
|
inst = std::make_shared<InstBinary>(inst_tag, TypeHelper::TYPE_I32, op1, op2, parent_bb);
|
|
}
|
|
else {
|
|
panic("Invalid Binary Operation");
|
|
}
|
|
assert(Type::isType<IntegerType>(op1->type));
|
|
assert(Type::isType<IntegerType>(op2->type));
|
|
if (!(Type::asType<IntegerType>(op1->type)->int_type == Type::asType<IntegerType>(op2->type)->int_type)) {
|
|
if (!(Value::is<ConstantInt>(op1) && Value::as<ConstantInt>(op1)->value == 0)
|
|
&& !(Value::is<ConstantInt>(op2) && Value::as<ConstantInt>(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<InstZext> build_InstZext(std::shared_ptr<Value> op, std::shared_ptr<BasicBlock> parent_bb) {
|
|
auto inst = std::make_shared<InstZext>(op, parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstBranch> build_InstBranch(
|
|
ValuePtr_t cond,
|
|
BasicBlockPtr_t true_block,
|
|
BasicBlockPtr_t false_block,
|
|
BasicBlockPtr_t parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstBranch>(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<InstBranch> build_InstBranch(BasicBlockPtr_t target_block, BasicBlockPtr_t parent_bb) {
|
|
auto inst = std::make_shared<InstBranch>(target_block, parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstReturn> build_InstReturn(ValuePtr_t ret_val, BasicBlockPtr_t parent_bb) {
|
|
auto inst = std::make_shared<InstReturn>(ret_val, parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstReturn> build_InstReturn(BasicBlockPtr_t parent_bb) {
|
|
auto inst = std::make_shared<InstReturn>(parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstCall> build_InstCall(
|
|
FunctionPtr_t func,
|
|
const std::vector<ValuePtr_t> &args,
|
|
BasicBlockPtr_t parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstCall>(func, args, parent_bb);
|
|
inst->inst_itr = parent_bb->inst_list.insert(parent_bb->inst_list.end(), inst);
|
|
return inst;
|
|
}
|
|
|
|
std::shared_ptr<InstGEP> build_InstGEP(
|
|
ValuePtr_t pointer,
|
|
const std::vector<ValuePtr_t> &indices,
|
|
BasicBlockPtr_t parent_bb
|
|
) {
|
|
auto inst = std::make_shared<InstGEP>(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<InstPhi>(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
|