You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

974 lines
31 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
class Type;
class IntegerType;
class ArrayType;
class PointerType;
class FunctionType;
class Value;
class Constant;
class ConstantInt;
class ConstantFloat;
class ConstantArray;
class ConstantZero;
class Module;
class GlobalVariable;
class Function;
class BasicBlock;
class Argument;
class Instruction;
class BinaryInst;
class UnaryInst;
class ICmpInst;
class FCmpInst;
class CallInst;
class BranchInst;
class ReturnInst;
class GetElementPtrInst;
class StoreInst;
class LoadInst;
class AllocaInst;
struct Use {
Value *val_;
unsigned int arg_no_; // 操作数的序号如func(a,b)中a的序号为0b的序号为1
Use(Value *val, unsigned int no) : val_(val), arg_no_(no) {}
};
//-----------------------------------------------Type-----------------------------------------------
class Type {
public:
enum TypeID {
VoidTyID, // Void
LabelTyID, // Labels, e.g., BasicBlock
IntegerTyID, // Integers, include 32 bits and 1 bit
FloatTyID, // Floats, only 32 bits
FunctionTyID, // Functions
ArrayTyID, // Arrays
PointerTyID, // Pointer
};
explicit Type(TypeID tid) : tid_(tid) {}
~Type() = default;
virtual std::string print();
TypeID tid_;
};
class IntegerType : public Type {
public:
explicit IntegerType(unsigned num_bits)
: Type(Type::IntegerTyID), num_bits_(num_bits) {}
unsigned num_bits_;
};
//[2 x [3 x i32]]: num_elements_ = 2, contained_ = [3 x i32]
class ArrayType : public Type {
public:
ArrayType(Type *contained, unsigned num_elements)
: Type(Type::ArrayTyID), num_elements_(num_elements),
contained_(contained) {}
Type *contained_; // The element type of the array.
unsigned num_elements_; // Number of elements in the array.
};
//[2 x [3 x i32]]*
class PointerType : public Type {
public:
PointerType(Type *contained)
: Type(Type::PointerTyID), contained_(contained) {}
Type *contained_; // The element type of the ptr.
};
// declare i32 @putarray(i32, i32*)
class FunctionType : public Type {
public:
FunctionType(Type *result, std::vector<Type *> params)
: Type(Type::FunctionTyID) {
result_ = result;
for (Type *p : params) {
args_.push_back(p);
}
}
Type *result_;
std::vector<Type *> args_;
};
//-----------------------------------------------Value-----------------------------------------------
class Value {
public:
explicit Value(Type *ty, const std::string &name = "")
: type_(ty), name_(name) {}
~Value() = default;
virtual std::string print() = 0;
void remove_use(Value *val) {
auto is_val = [val](const Use &use) { return use.val_ == val; };
use_list_.remove_if(is_val);
}
//******************************************************************
std::list<Use>::iterator add_use(Value *val, unsigned arg_no) {
use_list_.emplace_back(Use(val, arg_no));
std::list<Use>::iterator re = use_list_.end();
return --re;
}
// 删除迭代器指出的use
void remove_use(std::list<Use>::iterator it) { use_list_.erase(it); }
// user的第i个操作数准备不再使用this因此删除this与user相关的use联系
bool remove_used(Instruction *user, unsigned int i);
// Return if the value is a constant.
bool is_constant();
//******************************************************************
void replace_all_use_with(Value *new_val);
Type *type_;
std::string name_;
std::list<Use>
use_list_; // 所有引用该Value的Instruction的集合以及该Value在该Instruction的第几个操作数位置被引用
};
//-----------------------------------------------Constant-----------------------------------------------
// 常量都是无名的(name=="")
class Constant : public Value {
public:
Constant(Type *ty, const std::string &name = "") : Value(ty, name) {}
~Constant() = default;
};
// i32 -23
class ConstantInt : public Constant {
public:
ConstantInt(Type *ty, int val) : Constant(ty, ""), value_(val) {}
virtual std::string print() override;
int value_;
};
// float 0x4057C21FC0000000
// float -3.300000e+04
class ConstantFloat : public Constant {
public:
ConstantFloat(Type *ty, float val) : Constant(ty, ""), value_(val) {}
virtual std::string print() override;
float value_;
std::string print32();
};
//[3 x i32] [i32 42, i32 11, i32 74]
class ConstantArray : public Constant {
public:
ConstantArray(ArrayType *ty, const std::vector<Constant *> &val)
: Constant(ty, "") {
this->const_array.assign(val.begin(), val.end());
}
~ConstantArray() = default;
virtual std::string print() override;
std::vector<Constant *> const_array;
};
// i32 zeroinitializer
//[2 x [100 x float]] zeroinitializer
// 注意zeroinitializer是有类型的
class ConstantZero : public Constant {
public:
ConstantZero(Type *ty) : Constant(ty, "") {}
virtual std::string print() override;
};
//-----------------------------------------------Module-----------------------------------------------
class Module {
public:
explicit Module() {
void_ty_ = new Type(Type::VoidTyID);
label_ty_ = new Type(Type::LabelTyID);
int1_ty_ = new IntegerType(1);
int32_ty_ = new IntegerType(32);
float32_ty_ = new Type(Type::FloatTyID);
}
~Module() {
delete void_ty_;
delete label_ty_;
delete int1_ty_;
delete int32_ty_;
delete float32_ty_;
}
virtual std::string print();
void add_global_variable(GlobalVariable *g) { global_list_.push_back(g); }
void add_function(Function *f) { function_list_.push_back(f); }
PointerType *get_pointer_type(Type *contained) {
if (!pointer_map_.count(contained)) {
pointer_map_[contained] = new PointerType(contained);
}
return pointer_map_[contained];
}
ArrayType *get_array_type(Type *contained, unsigned num_elements) {
if (!array_map_.count({contained, num_elements})) {
array_map_[{contained, num_elements}] =
new ArrayType(contained, num_elements);
}
return array_map_[{contained, num_elements}];
}
Function *getMainFunc();
std::vector<GlobalVariable *> global_list_;
std::vector<Function *> function_list_;
IntegerType *int1_ty_;
IntegerType *int32_ty_;
Type *float32_ty_;
Type *label_ty_;
Type *void_ty_;
std::map<Type *, PointerType *> pointer_map_;
std::map<std::pair<Type *, int>, ArrayType *> array_map_;
};
//-----------------------------------------------GlobalVariable-----------------------------------------------
//@c = global [4 x i32] [i32 6, i32 7, i32 8, i32 9]
//@a = constant [5 x i32] [i32 0, i32 1, i32 2, i32 3, i32 4]
class GlobalVariable : public Value {
public:
GlobalVariable(std::string name, Module *m, Type *ty, bool is_const,
Constant *init = nullptr)
: Value(m->get_pointer_type(ty), name), is_const_(is_const),
init_val_(init) {
m->add_global_variable(this);
}
virtual std::string print() override;
bool is_const_;
Constant *init_val_;
};
//-----------------------------------------------Function-----------------------------------------------
// 注Argument的构造函数只由Function的构造函数调用不单独调用
class Argument : public Value {
public:
explicit Argument(Type *ty, const std::string &name = "",
Function *f = nullptr, unsigned arg_no = 0)
: Value(ty, name), parent_(f), arg_no_(arg_no) {}
~Argument() {}
virtual std::string print() override;
Function *parent_;
unsigned arg_no_; // argument No.
};
class Function : public Value {
public:
Function(FunctionType *ty, const std::string &name, Module *parent)
: Value(ty, name), parent_(parent), seq_cnt_(0) {
parent->add_function(this);
size_t num_args = ty->args_.size();
use_ret_cnt = 0;
for (size_t i = 0; i < num_args; i++) {
arguments_.push_back(new Argument(ty->args_[i], "", this, i));
}
}
~Function();
virtual std::string print() override;
void add_basic_block(BasicBlock *bb) { basic_blocks_.push_back(bb); }
Type *get_return_type() const {
return static_cast<FunctionType *>(type_)->result_;
}
bool is_declaration() { return basic_blocks_.empty(); }
void set_instr_name();
void remove_bb(BasicBlock *bb);
BasicBlock *getRetBB();
std::vector<BasicBlock *> basic_blocks_; // basic blocks
std::vector<Argument *> arguments_; // argument
Module *parent_;
unsigned seq_cnt_;
std::vector<std::set<Value *>> vreg_set_;
int use_ret_cnt; // 程序中真正使用返回值的次数
};
//-----------------------------------------------BasicBlock-----------------------------------------------
// 注BasicBlock一定是LabelTyID
class BasicBlock : public Value {
public:
explicit BasicBlock(Module *m, const std::string &name, Function *parent)
: Value(m->label_ty_, name), parent_(parent) {
parent_->add_basic_block(this);
}
bool add_instruction(Instruction *instr); // 尾部插入指令,返回成功与否
bool add_instruction_front(Instruction *instr); // 头部插入指令,返回成功与否
bool add_instruction_before_terminator(
Instruction *instr); // 插入到BB倒数第二条指令即br前
bool add_instruction_before_inst(
Instruction *new_inst,
Instruction *
inst); // 将新指令插入到原来指令前返回成功与否需要保证原指令在bb内
void add_pre_basic_block(BasicBlock *bb) { pre_bbs_.push_back(bb); }
void add_succ_basic_block(BasicBlock *bb) { succ_bbs_.push_back(bb); }
void remove_pre_basic_block(BasicBlock *bb) {
// pre_bbs_.remove(bb);
pre_bbs_.erase(std::remove(pre_bbs_.begin(), pre_bbs_.end(), bb),
pre_bbs_.end());
}
void remove_succ_basic_block(BasicBlock *bb) {
// succ_bbs_.remove(bb);
succ_bbs_.erase(std::remove(succ_bbs_.begin(), succ_bbs_.end(), bb),
succ_bbs_.end());
}
int isDominate(
BasicBlock
*bb2) { // 返回1表示支配bb2返回0表示不支配返回-1输入的块出错
if (!bb2 || this->parent_ != bb2->parent_)
return -1;
while (bb2->name_ != "label_entry") {
if (bb2->idom_ == this)
return 1;
bb2 = bb2->idom_;
}
return 0;
}
// Returns the terminator instruction if the block is well formed or null
// if the block is not well formed.
Instruction *get_terminator();
bool delete_instr(
Instruction *instr); // 返回false则说明指令不能重复删除或者不属于这个bb
bool remove_instr(
Instruction *
instr); // 从bb移出一个指令但是不删指令的use关系因为还要插入其他bb
virtual std::string print() override;
//********************使用list替换vector---------
std::list<Instruction *> instr_list_;
//********************使用list替换vector---------
Function *parent_;
/****************api about cfg****************/
std::vector<BasicBlock *> pre_bbs_;
std::vector<BasicBlock *> succ_bbs_;
/****************api about dominate tree****************/
std::set<BasicBlock *> dom_frontier_;
std::set<BasicBlock *> rdom_frontier_;
std::set<BasicBlock *> rdoms_;
BasicBlock *idom_;
std::set<Value *> live_in;
std::set<Value *> live_out;
};
//-----------------------------------------------Instruction-----------------------------------------------
class Instruction : public Value {
public:
enum OpID {
// Terminator Instructions
Ret = 11,
Br,
// Standard unary operators
FNeg,
// Standard binary operators
Add,
Sub,
Mul,
SDiv,
SRem,
UDiv,
URem,
// Float binary opeartors
FAdd,
FSub,
FMul,
FDiv,
// Logical operators
Shl,
LShr,
AShr,
And,
Or,
Xor,
// Memory operators
Alloca,
Load,
Store,
GetElementPtr,
// Cast operators
ZExt,
FPtoSI,
SItoFP,
BitCast,
// Other operators
ICmp,
FCmp,
PHI,
Call,
};
// 创建指令并插入基本块ty是指令返回值类型
// If before set to true, then use add_instruction_front() instead of
// add_instruction()
Instruction(Type *ty, OpID id, unsigned num_ops, BasicBlock *parent,
bool before = false)
: Value(ty, ""), op_id_(id), num_ops_(num_ops), parent_(parent) {
operands_.resize(
num_ops_,
nullptr); // 此句不能删去否则operands_为空时无法用set_operand设置操作数而只能用push_back设置操作数
use_pos_.resize(num_ops_);
if (!before)
parent_->add_instruction(this);
else
parent_->add_instruction_front(this);
}
// 仅创建指令不插入基本块ty是指令返回值类型
Instruction(Type *ty, OpID id, unsigned num_ops)
: Value(ty, ""), op_id_(id), num_ops_(num_ops), parent_(nullptr) {
operands_.resize(num_ops_, nullptr);
use_pos_.resize(num_ops_);
}
Value *get_operand(unsigned i) const { return operands_[i]; }
//***************************
void set_operand(unsigned i, Value *v) {
operands_[i] = v;
use_pos_[i] = v->add_use(this, i);
}
void add_operand(Value *v) { // 添加指令操作数用于phi指令
operands_.push_back(v);
use_pos_.emplace_back(v->add_use(this, num_ops_));
num_ops_++;
}
void
remove_use_of_ops() { // 删除此指令所有操作数的uselist中与此指令相关的use
for (int i = 0; i < operands_.size(); i++) {
operands_[i]->remove_use(use_pos_[i]);
}
}
// 删除phi指令中的一对操作数
void remove_operands(int index1, int index2) {
for (int i = index1; i <= index2; i++) {
operands_[i]->remove_use(use_pos_[i]);
}
// 后面操作数的位置要做相应修改
for (int i = index2 + 1; i < operands_.size(); i++) {
for (auto &use : operands_[i]->use_list_) {
if (use.val_ == this) {
use.arg_no_ -= index2 - index1 + 1;
break;
}
}
}
operands_.erase(operands_.begin() + index1, operands_.begin() + index2 + 1);
use_pos_.erase(use_pos_.begin() + index1, use_pos_.begin() + index2 + 1);
// std::cout<<operands_.size()<<std::endl;
num_ops_ = operands_.size();
}
// ↓↓↓↓↓↓↓↓--------增加快速类型判断
bool is_void() {
return ((op_id_ == Ret) || (op_id_ == Br) || (op_id_ == Store) ||
(op_id_ == Call && this->type_->tid_ == Type::VoidTyID));
}
bool is_phi() { return op_id_ == PHI; }
bool is_store() { return op_id_ == Store; }
bool is_alloca() { return op_id_ == Alloca; }
bool is_ret() { return op_id_ == Ret; }
bool is_load() { return op_id_ == Load; }
bool is_br() { return op_id_ == Br; }
bool is_add() { return op_id_ == Add; }
bool is_sub() { return op_id_ == Sub; }
bool is_mul() { return op_id_ == Mul; }
bool is_div() { return op_id_ == SDiv; }
bool is_rem() { return op_id_ == SRem; }
bool is_fadd() { return op_id_ == FAdd; }
bool is_fsub() { return op_id_ == FSub; }
bool is_fmul() { return op_id_ == FMul; }
bool is_fdiv() { return op_id_ == FDiv; }
bool is_cmp() { return op_id_ == ICmp; }
bool is_fcmp() { return op_id_ == FCmp; }
bool is_call() { return op_id_ == Call; }
bool is_gep() { return op_id_ == GetElementPtr; }
bool is_zext() { return op_id_ == ZExt; }
bool is_fptosi() { return op_id_ == FPtoSI; }
bool is_sitofp() { return op_id_ == SItoFP; }
bool is_int_binary() {
return (is_add() || is_sub() || is_mul() || is_div() || is_rem()) &&
(num_ops_ == 2);
}
bool is_float_binary() {
return (is_fadd() || is_fsub() || is_fmul() || is_fdiv()) &&
(num_ops_ == 2);
}
bool is_binary() { return is_int_binary() || is_float_binary(); }
bool isTerminator() { return is_br() || is_ret(); }
// ↑↑↑↑↑↑↑↑--------增加快速类型判断-
virtual std::string print() = 0;
BasicBlock *parent_;
OpID op_id_;
unsigned num_ops_;
std::vector<Value *> operands_; // operands of this value
std::vector<std::list<Use>::iterator>
use_pos_; // 与操作数数组一一对应是对应的操作数的uselist里面与当前指令相关的use的迭代器
std::vector<std::list<Instruction *>::iterator>
pos_in_bb; // 在bb的指令list的位置迭代器,最多只能有一个
};
//%77 = add i32 %74, %76
//%10 = and i1 %7, %9
//%7 = xor i1 %6, true
//%13 = fmul float %12, 0x400921FB60000000
class BinaryInst : public Instruction {
public:
BinaryInst(Type *ty, OpID op, Value *v1, Value *v2, BasicBlock *bb)
: Instruction(ty, op, 2, bb) {
set_operand(0, v1);
set_operand(1, v2);
}
// 只创建,不加入基本块末尾
BinaryInst(Type *ty, OpID op, Value *v1, Value *v2, BasicBlock *bb, bool flag)
: Instruction(ty, op, 2) {
set_operand(0, v1);
set_operand(1, v2);
this->parent_ = bb;
}
virtual std::string print() override;
};
//%8 = zext i1 %7 to i32
//%51 = fptosi float %50 to i32
//%4 = sitofp i32 %3 to float
//%8 = fneg float %7
//%3 = bitcast [4 x [2 x i32]]* %2 to i32*
class UnaryInst : public Instruction {
public:
UnaryInst(Type *ty, OpID op, Value *val, BasicBlock *bb)
: Instruction(ty, op, 1, bb) {
set_operand(0, val);
}
virtual std::string print() override;
};
//%18 = icmp ne i32 %12, %17
class ICmpInst : public Instruction {
public:
enum ICmpOp {
ICMP_EQ = 32, ///< equal
ICMP_NE = 33, ///< not equal
ICMP_UGT = 34, ///< unsigned greater than
ICMP_UGE = 35, ///< unsigned greater or equal
ICMP_ULT = 36, ///< unsigned less than
ICMP_ULE = 37, ///< unsigned less or equal
ICMP_SGT = 38, ///< signed greater than
ICMP_SGE = 39, ///< signed greater or equal
ICMP_SLT = 40, ///< signed less than
ICMP_SLE = 41 ///< signed less or equal
};
static const std::map<ICmpInst::ICmpOp, std::string> ICmpOpName;
ICmpInst(ICmpOp op, Value *v1, Value *v2, BasicBlock *bb)
: Instruction(bb->parent_->parent_->int1_ty_, Instruction::ICmp, 2, bb),
icmp_op_(op) {
set_operand(0, v1);
set_operand(1, v2);
}
virtual std::string print() override;
ICmpOp icmp_op_;
};
//%5 = fcmp olt float %4, 0.000000e+00
class FCmpInst : public Instruction {
public:
enum FCmpOp {
FCMP_FALSE = 10, // Always false (always folded)
FCMP_OEQ = 11, // True if ordered and equal
FCMP_OGT = 12, // True if ordered and greater than
FCMP_OGE = 13, // True if ordered and greater than or equal
FCMP_OLT = 14, // True if ordered and less than
FCMP_OLE = 15, // True if ordered and less than or equal
FCMP_ONE = 16, // True if ordered and operands are unequal
FCMP_ORD = 17, // True if ordered (no nans)
FCMP_UNO = 18, // True if unordered: isnan(X) | isnan(Y)
FCMP_UEQ = 19, // True if unordered or equal
FCMP_UGT = 20, // True if unordered or greater than
FCMP_UGE = 21, // True if unordered, greater than, or equal
FCMP_ULT = 22, // True if unordered or less than
FCMP_ULE = 23, // True if unordered, less than, or equal
FCMP_UNE = 24, // True if unordered or not equal
FCMP_TRUE = 25 // Always true (always folded)
};
static const std::map<FCmpInst::FCmpOp, std::string> FCmpOpName;
FCmpInst(FCmpOp op, Value *v1, Value *v2, BasicBlock *bb)
: Instruction(bb->parent_->parent_->int1_ty_, Instruction::FCmp, 2, bb),
fcmp_op_(op) {
set_operand(0, v1);
set_operand(1, v2);
}
virtual std::string print() override;
FCmpOp fcmp_op_;
};
//%111 = call i32 @QuickSort(i32* %108, i32 %109, i32 %110)
class CallInst : public Instruction {
public:
CallInst(Function *func, std::vector<Value *> args, BasicBlock *bb)
: Instruction(static_cast<FunctionType *>(func->type_)->result_,
Instruction::Call, args.size() + 1, bb) {
int num_ops = args.size() + 1;
for (int i = 0; i < num_ops - 1; i++) {
set_operand(i, args[i]);
}
set_operand(num_ops - 1, func);
}
virtual std::string print() override;
};
// 注br的返回值类型一定是VoidTyID
class BranchInst : public Instruction {
public:
// br i1 %7, label %8, label %9
BranchInst(Value *cond, BasicBlock *if_true, BasicBlock *if_false,
BasicBlock *bb)
: Instruction(if_true->parent_->parent_->void_ty_, Instruction::Br, 3,
bb) {
if_true->add_pre_basic_block(bb);
if_false->add_pre_basic_block(bb);
bb->add_succ_basic_block(if_false);
bb->add_succ_basic_block(if_true);
set_operand(0, cond);
set_operand(1, if_true);
set_operand(2, if_false);
}
// br label %31
BranchInst(BasicBlock *if_true, BasicBlock *bb)
: Instruction(if_true->parent_->parent_->void_ty_, Instruction::Br, 1,
bb) {
if_true->add_pre_basic_block(bb);
bb->add_succ_basic_block(if_true);
set_operand(0, if_true);
}
virtual std::string print() override;
};
// ret i32 %4
// ret void
// 注ret的返回值类型一定是VoidTyID
class ReturnInst : public Instruction {
public:
ReturnInst(Value *val, BasicBlock *bb)
: Instruction(bb->parent_->parent_->void_ty_, Instruction::Ret, 1, bb) {
set_operand(0, val);
}
ReturnInst(Value *val, BasicBlock *bb, bool flag)
: Instruction(bb->parent_->parent_->void_ty_, Instruction::Ret, 1) {
set_operand(0, val);
this->parent_ = bb;
}
ReturnInst(BasicBlock *bb)
: Instruction(bb->parent_->parent_->void_ty_, Instruction::Ret, 0, bb) {}
virtual std::string print() override;
};
//%1 = getelementptr [5 x [4 x i32]], [5 x [4 x i32]]* @a, i32 0, i32 2, i32 3
class GetElementPtrInst : public Instruction {
public:
GetElementPtrInst(Value *ptr, std::vector<Value *> idxs, BasicBlock *bb)
: Instruction(bb->parent_->parent_->get_pointer_type(
get_GEP_return_type(ptr, idxs.size())),
Instruction::GetElementPtr, idxs.size() + 1, bb) {
set_operand(0, ptr);
for (size_t i = 0; i < idxs.size(); i++) {
set_operand(i + 1, idxs[i]);
}
}
Type *get_GEP_return_type(Value *ptr, size_t idxs_size) {
Type *ty =
static_cast<PointerType *>(ptr->type_)->contained_; //[5 x [4 x i32]]
if (ty->tid_ == Type::ArrayTyID) {
ArrayType *arr_ty = static_cast<ArrayType *>(ty);
for (size_t i = 1; i < idxs_size; i++) {
ty = arr_ty->contained_; //[4 x i32], i32
if (ty->tid_ == Type::ArrayTyID) {
arr_ty = static_cast<ArrayType *>(ty);
}
}
}
return ty;
}
virtual std::string print() override;
};
// store <ty> <value>, <ty>* <pointer>
// store i32 %57, i32* %55
// 注store的返回值类型一定是VoidTyID
class StoreInst : public Instruction {
public:
StoreInst(Value *val, Value *ptr, BasicBlock *bb)
: Instruction(bb->parent_->parent_->void_ty_, Instruction::Store, 2, bb) {
assert(val->type_ == static_cast<PointerType *>(ptr->type_)->contained_);
set_operand(0, val);
set_operand(1, ptr);
}
// 创建store指令不插入到基本块中但是设定parent
StoreInst(Value *val, Value *ptr, BasicBlock *bb, bool)
: Instruction(bb->parent_->parent_->void_ty_, Instruction::Store, 2) {
assert(val->type_ == static_cast<PointerType *>(ptr->type_)->contained_);
set_operand(0, val);
set_operand(1, ptr);
this->parent_ = bb;
}
virtual std::string print() override;
};
//<result> = load <ty>, <ty>* <pointer>
//%60 = load i32, i32* %59
class LoadInst : public Instruction {
public:
LoadInst(Value *ptr, BasicBlock *bb)
: Instruction(static_cast<PointerType *>(ptr->type_)->contained_,
Instruction::Load, 1, bb) {
set_operand(0, ptr);
}
virtual std::string print() override;
};
//%8 = alloca i32
class AllocaInst : public Instruction {
public:
AllocaInst(Type *ty, BasicBlock *bb)
: Instruction(bb->parent_->parent_->get_pointer_type(ty),
Instruction::Alloca, 0, bb, true),
alloca_ty_(ty) {}
// 创建指令不插入到最后但是会设定parent
AllocaInst(Type *ty, BasicBlock *bb, bool)
: Instruction(bb->parent_->parent_->get_pointer_type(ty),
Instruction::Alloca, 0),
alloca_ty_(ty) {
this->parent_ = bb;
}
virtual std::string print() override;
Type *alloca_ty_;
};
class ZextInst : public Instruction {
public:
ZextInst(OpID op, Value *val, Type *ty, BasicBlock *bb)
: Instruction(ty, op, 1, bb), dest_ty_(ty) {
set_operand(0, val);
}
virtual std::string print() override;
Type *dest_ty_;
};
class FpToSiInst : public Instruction {
public:
FpToSiInst(OpID op, Value *val, Type *ty, BasicBlock *bb)
: Instruction(ty, op, 1, bb), dest_ty_(ty) {
set_operand(0, val);
}
virtual std::string print() override;
Type *dest_ty_;
};
class SiToFpInst : public Instruction {
public:
SiToFpInst(OpID op, Value *val, Type *ty, BasicBlock *bb)
: Instruction(ty, op, 1, bb), dest_ty_(ty) {
set_operand(0, val);
}
virtual std::string print() override;
Type *dest_ty_;
};
//%3 = bitcast [4 x [2 x i32]]* %2 to i32*
class Bitcast : public Instruction {
public:
Bitcast(OpID op, Value *val, Type *ty, BasicBlock *bb)
: Instruction(ty, op, 1, bb), dest_ty_(ty) {
set_operand(0, val);
}
virtual std::string print() override;
Type *dest_ty_;
};
//%4 = phi i32 [ 1, %2 ], [ %6, %5 ]
class PhiInst : public Instruction {
public:
PhiInst(OpID op, std::vector<Value *> vals, std::vector<BasicBlock *> val_bbs,
Type *ty, BasicBlock *bb)
: Instruction(ty, op, 2 * vals.size()) {
for (int i = 0; i < vals.size(); i++) {
set_operand(2 * i, vals[i]);
set_operand(2 * i + 1, val_bbs[i]);
}
this->parent_ = bb;
}
static PhiInst *create_phi(Type *ty, BasicBlock *bb) {
std::vector<Value *> vals;
std::vector<BasicBlock *> val_bbs;
return new PhiInst(Instruction::PHI, vals, val_bbs, ty, bb);
}
void add_phi_pair_operand(Value *val, Value *pre_bb) {
this->add_operand(val);
this->add_operand(pre_bb);
}
virtual std::string print() override;
Value *l_val_;
};
//-----------------------------------------------IRStmtBuilder-----------------------------------------------
class IRStmtBuilder {
public:
BasicBlock *BB_;
Module *m_;
IRStmtBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){};
~IRStmtBuilder() = default;
Module *get_module() { return m_; }
BasicBlock *get_insert_block() { return this->BB_; }
void set_insert_point(BasicBlock *bb) {
this->BB_ = bb;
} // 在某个基本块中插入指令
BinaryInst *create_iadd(Value *v1, Value *v2) {
return new BinaryInst(this->m_->int32_ty_, Instruction::Add, v1, v2,
this->BB_);
} // 创建加法指令(以及其他算术指令)
BinaryInst *create_isub(Value *v1, Value *v2) {
return new BinaryInst(this->m_->int32_ty_, Instruction::Sub, v1, v2,
this->BB_);
}
BinaryInst *create_imul(Value *v1, Value *v2) {
return new BinaryInst(this->m_->int32_ty_, Instruction::Mul, v1, v2,
this->BB_);
}
BinaryInst *create_isdiv(Value *v1, Value *v2) {
return new BinaryInst(this->m_->int32_ty_, Instruction::SDiv, v1, v2,
this->BB_);
}
BinaryInst *create_isrem(Value *v1, Value *v2) {
return new BinaryInst(this->m_->int32_ty_, Instruction::SRem, v1, v2,
this->BB_);
}
ICmpInst *create_icmp_eq(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_EQ, v1, v2, this->BB_);
}
ICmpInst *create_icmp_ne(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_NE, v1, v2, this->BB_);
}
ICmpInst *create_icmp_gt(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_SGT, v1, v2, this->BB_);
}
ICmpInst *create_icmp_ge(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_SGE, v1, v2, this->BB_);
}
ICmpInst *create_icmp_lt(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_SLT, v1, v2, this->BB_);
}
ICmpInst *create_icmp_le(Value *v1, Value *v2) {
return new ICmpInst(ICmpInst::ICMP_SLE, v1, v2, this->BB_);
}
BinaryInst *create_fadd(Value *v1, Value *v2) {
return new BinaryInst(this->m_->float32_ty_, Instruction::FAdd, v1, v2,
this->BB_);
}
BinaryInst *create_fsub(Value *v1, Value *v2) {
return new BinaryInst(this->m_->float32_ty_, Instruction::FSub, v1, v2,
this->BB_);
}
BinaryInst *create_fmul(Value *v1, Value *v2) {
return new BinaryInst(this->m_->float32_ty_, Instruction::FMul, v1, v2,
this->BB_);
}
BinaryInst *create_fdiv(Value *v1, Value *v2) {
return new BinaryInst(this->m_->float32_ty_, Instruction::FDiv, v1, v2,
this->BB_);
}
FCmpInst *create_fcmp_eq(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_UEQ, v1, v2, this->BB_);
}
FCmpInst *create_fcmp_ne(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_UNE, v1, v2, this->BB_);
}
FCmpInst *create_fcmp_gt(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_UGT, v1, v2, this->BB_);
}
FCmpInst *create_fcmp_ge(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_UGE, v1, v2, this->BB_);
}
FCmpInst *create_fcmp_lt(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_ULT, v1, v2, this->BB_);
}
FCmpInst *create_fcmp_le(Value *v1, Value *v2) {
return new FCmpInst(FCmpInst::FCMP_ULE, v1, v2, this->BB_);
}
CallInst *create_call(Value *func, std::vector<Value *> args) {
#ifdef DEBUG
assert(dynamic_cast<Function *>(func) && "func must be Function * type");
#endif
return new CallInst(static_cast<Function *>(func), args, this->BB_);
}
BranchInst *create_br(BasicBlock *if_true) {
return new BranchInst(if_true, this->BB_);
}
BranchInst *create_cond_br(Value *cond, BasicBlock *if_true,
BasicBlock *if_false) {
return new BranchInst(cond, if_true, if_false, this->BB_);
}
ReturnInst *create_ret(Value *val) { return new ReturnInst(val, this->BB_); }
ReturnInst *create_void_ret() { return new ReturnInst(this->BB_); }
GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs) {
return new GetElementPtrInst(ptr, idxs, this->BB_);
}
StoreInst *create_store(Value *val, Value *ptr) {
return new StoreInst(val, ptr, this->BB_);
}
LoadInst *create_load(Type *ty, Value *ptr) {
return new LoadInst(ptr, this->BB_);
}
LoadInst *create_load(Value *ptr) {
#ifdef DEBUG
assert(ptr->get_type()->is_pointer_type() && "ptr must be pointer type");
#endif
// return LoadInst::create_load(ptr->get_type()->get_pointer_element_type(),
// ptr, this->BB_);
return new LoadInst(ptr, this->BB_);
}
AllocaInst *create_alloca(Type *ty) { return new AllocaInst(ty, this->BB_); }
ZextInst *create_zext(Value *val, Type *ty) {
return new ZextInst(Instruction::ZExt, val, ty, this->BB_);
}
FpToSiInst *create_fptosi(Value *val, Type *ty) {
return new FpToSiInst(Instruction::FPtoSI, val, ty, this->BB_);
}
SiToFpInst *create_sitofp(Value *val, Type *ty) {
return new SiToFpInst(Instruction::SItoFP, val, ty, this->BB_);
}
Bitcast *create_bitcast(Value *val, Type *ty) {
return new Bitcast(Instruction::BitCast, val, ty, this->BB_);
}
};