Commit 4b7accb1 authored by 李晓奇's avatar 李晓奇

finish part2: write cpp to generate .ll file

parent a0b2bd9d
...@@ -2,5 +2,6 @@ build ...@@ -2,5 +2,6 @@ build
Documentations/1-parser/*.pdf Documentations/1-parser/*.pdf
compile_commands.json compile_commands.json
.cache .cache
todo.txt
tmp.cminus tmp.cminus
...@@ -18,11 +18,13 @@ class Argument; ...@@ -18,11 +18,13 @@ class Argument;
class Type; class Type;
class FunctionType; class FunctionType;
class Function : public Value, public llvm::ilist_node<Function> { class Function : public Value, public llvm::ilist_node<Function>
{
public: public:
Function(FunctionType *ty, const std::string &name, Module *parent); Function(FunctionType *ty, const std::string &name, Module *parent);
virtual ~Function(); virtual ~Function();
static Function *create(FunctionType *ty, const std::string &name, Module *parent); static Function *create(FunctionType *ty, const std::string &name,
Module *parent);
FunctionType *get_function_type() const; FunctionType *get_function_type() const;
...@@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node<Function> {
std::list<Argument *>::iterator arg_begin() { return arguments_.begin(); } std::list<Argument *>::iterator arg_begin() { return arguments_.begin(); }
std::list<Argument *>::iterator arg_end() { return arguments_.end(); } std::list<Argument *>::iterator arg_end() { return arguments_.end(); }
void remove(BasicBlock *bb); void remove(BasicBlock *bb);
BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); } BasicBlock *get_entry_block() { return &*basic_blocks_.begin(); }
llvm::ilist<BasicBlock> &get_basic_blocks() { return basic_blocks_; } llvm::ilist<BasicBlock> &get_basic_blocks() { return basic_blocks_; }
std::list<Argument *> &get_args() { return arguments_; } std::list<Argument *> &get_args() { return arguments_; }
bool is_declaration() { return basic_blocks_.empty(); } bool is_declaration() { return basic_blocks_.empty(); }
void set_instr_name(); void set_instr_name();
std::string print(); std::string print();
private: private:
...@@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node<Function> { ...@@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node<Function> {
private: private:
llvm::ilist<BasicBlock> basic_blocks_; // basic blocks llvm::ilist<BasicBlock> basic_blocks_; // basic blocks
std::list<Argument *> arguments_; // arguments std::list<Argument *> arguments_; // arguments
Module *parent_; Module *parent_;
unsigned seq_cnt_; unsigned seq_cnt_;
// unsigned num_args_; // unsigned num_args_;
// We don't need this, all value inside function should be unnamed // We don't need this, all value inside function should be unnamed
// std::map<std::string, Value*> sym_table_; // Symbol table of args/instructions // std::map<std::string, Value*> sym_table_; // Symbol table of
// args/instructions
}; };
// Argument of Function, does not contain actual value // Argument of Function, does not contain actual value
class Argument : public Value { class Argument : public Value
{
public: public:
/// Argument constructor. /// Argument constructor.
explicit Argument(Type *ty, const std::string &name = "", Function *f = nullptr, unsigned arg_no = 0) explicit Argument(Type *ty, const std::string &name = "",
: Value(ty, name), parent_(f), arg_no_(arg_no) {} Function *f = nullptr, unsigned arg_no = 0)
: Value(ty, name), parent_(f), arg_no_(arg_no)
{
}
virtual ~Argument() {} virtual ~Argument() {}
inline const Function *get_parent() const { return parent_; } inline const Function *get_parent() const { return parent_; }
inline Function *get_parent() { return parent_; } inline Function *get_parent() { return parent_; }
/// For example in "void foo(int a, float b)" a is 0 and b is 1. /// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned get_arg_no() const { unsigned get_arg_no() const
{
assert(parent_ && "can't get number of unparented arg"); assert(parent_ && "can't get number of unparented arg");
return arg_no_; return arg_no_;
} }
...@@ -83,7 +91,7 @@ class Argument : public Value { ...@@ -83,7 +91,7 @@ class Argument : public Value {
private: private:
Function *parent_; Function *parent_;
unsigned arg_no_; // argument No. unsigned arg_no_; // argument No.
}; };
#endif // SYSYC_FUNCTION_H #endif // SYSYC_FUNCTION_H
...@@ -6,96 +6,169 @@ ...@@ -6,96 +6,169 @@
#include "Instruction.h" #include "Instruction.h"
#include "Value.h" #include "Value.h"
class IRBuilder { class IRBuilder
{
private: private:
BasicBlock *BB_; BasicBlock *BB_;
Module *m_; Module *m_;
public: public:
IRBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){}; IRBuilder(BasicBlock *bb, Module *m) : BB_(bb), m_(m){};
~IRBuilder() = default; ~IRBuilder() = default;
Module *get_module() { return m_; } Module *get_module() { return m_; }
BasicBlock *get_insert_block() { return this->BB_; } BasicBlock *get_insert_block() { return this->BB_; }
void set_insert_point(BasicBlock *bb) { this->BB_ = bb; } // 在某个基本块中插入指令 void set_insert_point(BasicBlock *bb)
BinaryInst *create_iadd(Value *lhs, Value *rhs) { {
this->BB_ = bb;
} // 在某个基本块中插入指令
BinaryInst *create_iadd(Value *lhs, Value *rhs)
{
return BinaryInst::create_add(lhs, rhs, this->BB_, m_); return BinaryInst::create_add(lhs, rhs, this->BB_, m_);
} // 创建加法指令(以及其他算术指令) } // 创建加法指令(以及其他算术指令)
BinaryInst *create_isub(Value *lhs, Value *rhs) { return BinaryInst::create_sub(lhs, rhs, this->BB_, m_); } BinaryInst *create_isub(Value *lhs, Value *rhs)
BinaryInst *create_imul(Value *lhs, Value *rhs) { return BinaryInst::create_mul(lhs, rhs, this->BB_, m_); } {
BinaryInst *create_isdiv(Value *lhs, Value *rhs) { return BinaryInst::create_sdiv(lhs, rhs, this->BB_, m_); } return BinaryInst::create_sub(lhs, rhs, this->BB_, m_);
}
BinaryInst *create_imul(Value *lhs, Value *rhs)
{
return BinaryInst::create_mul(lhs, rhs, this->BB_, m_);
}
BinaryInst *create_isdiv(Value *lhs, Value *rhs)
{
return BinaryInst::create_sdiv(lhs, rhs, this->BB_, m_);
}
CmpInst *create_icmp_eq(Value *lhs, Value *rhs) { CmpInst *create_icmp_eq(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::EQ, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::EQ, lhs, rhs, this->BB_, m_);
} }
CmpInst *create_icmp_ne(Value *lhs, Value *rhs) { CmpInst *create_icmp_ne(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::NE, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::NE, lhs, rhs, this->BB_, m_);
} }
CmpInst *create_icmp_gt(Value *lhs, Value *rhs) { CmpInst *create_icmp_gt(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::GT, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::GT, lhs, rhs, this->BB_, m_);
} }
CmpInst *create_icmp_ge(Value *lhs, Value *rhs) { CmpInst *create_icmp_ge(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::GE, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::GE, lhs, rhs, this->BB_, m_);
} }
CmpInst *create_icmp_lt(Value *lhs, Value *rhs) { CmpInst *create_icmp_lt(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::LT, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::LT, lhs, rhs, this->BB_, m_);
} }
CmpInst *create_icmp_le(Value *lhs, Value *rhs) { CmpInst *create_icmp_le(Value *lhs, Value *rhs)
{
return CmpInst::create_cmp(CmpInst::LE, lhs, rhs, this->BB_, m_); return CmpInst::create_cmp(CmpInst::LE, lhs, rhs, this->BB_, m_);
} }
CallInst *create_call(Value *func, std::vector<Value *> args) { CallInst *create_call(Value *func, std::vector<Value *> args)
assert(dynamic_cast<Function *>(func) && "func must be Function * type"); {
assert(dynamic_cast<Function *>(func) &&
"func must be Function * type");
return CallInst::create(static_cast<Function *>(func), args, this->BB_); return CallInst::create(static_cast<Function *>(func), args, this->BB_);
} }
BranchInst *create_br(BasicBlock *if_true) { return BranchInst::create_br(if_true, this->BB_); } BranchInst *create_br(BasicBlock *if_true)
BranchInst *create_cond_br(Value *cond, BasicBlock *if_true, BasicBlock *if_false) { {
return BranchInst::create_br(if_true, this->BB_);
}
BranchInst *create_cond_br(Value *cond, BasicBlock *if_true,
BasicBlock *if_false)
{
return BranchInst::create_cond_br(cond, if_true, if_false, this->BB_); return BranchInst::create_cond_br(cond, if_true, if_false, this->BB_);
} }
ReturnInst *create_ret(Value *val) { return ReturnInst::create_ret(val, this->BB_); } ReturnInst *create_ret(Value *val)
ReturnInst *create_void_ret() { return ReturnInst::create_void_ret(this->BB_); } {
return ReturnInst::create_ret(val, this->BB_);
}
ReturnInst *create_void_ret()
{
return ReturnInst::create_void_ret(this->BB_);
}
GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs) { GetElementPtrInst *create_gep(Value *ptr, std::vector<Value *> idxs)
{
return GetElementPtrInst::create_gep(ptr, idxs, this->BB_); return GetElementPtrInst::create_gep(ptr, idxs, this->BB_);
} }
StoreInst *create_store(Value *val, Value *ptr) { return StoreInst::create_store(val, ptr, this->BB_); } StoreInst *create_store(Value *val, Value *ptr)
LoadInst *create_load(Type *ty, Value *ptr) { return LoadInst::create_load(ty, ptr, this->BB_); } {
LoadInst *create_load(Value *ptr) { return StoreInst::create_store(val, ptr, this->BB_);
assert(ptr->get_type()->is_pointer_type() && "ptr must be pointer type"); }
return LoadInst::create_load(ptr->get_type()->get_pointer_element_type(), ptr, this->BB_); LoadInst *create_load(Type *ty, Value *ptr)
{
return LoadInst::create_load(ty, ptr, this->BB_);
}
LoadInst *create_load(Value *ptr)
{
assert(ptr->get_type()->is_pointer_type() &&
"ptr must be pointer type");
return LoadInst::create_load(
ptr->get_type()->get_pointer_element_type(), ptr, this->BB_);
} }
AllocaInst *create_alloca(Type *ty) { return AllocaInst::create_alloca(ty, this->BB_); } AllocaInst *create_alloca(Type *ty)
ZextInst *create_zext(Value *val, Type *ty) { return ZextInst::create_zext(val, ty, this->BB_); } {
return AllocaInst::create_alloca(ty, this->BB_);
}
ZextInst *create_zext(Value *val, Type *ty)
{
return ZextInst::create_zext(val, ty, this->BB_);
}
SiToFpInst *create_sitofp(Value *val, Type *ty) { return SiToFpInst::create_sitofp(val, ty, this->BB_); } SiToFpInst *create_sitofp(Value *val, Type *ty)
FpToSiInst *create_fptosi(Value *val, Type *ty) { return FpToSiInst::create_fptosi(val, ty, this->BB_); } {
return SiToFpInst::create_sitofp(val, ty, this->BB_);
}
FpToSiInst *create_fptosi(Value *val, Type *ty)
{
return FpToSiInst::create_fptosi(val, ty, this->BB_);
}
FCmpInst *create_fcmp_ne(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_ne(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::NE, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::NE, lhs, rhs, this->BB_, m_);
} }
FCmpInst *create_fcmp_lt(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_lt(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::LT, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::LT, lhs, rhs, this->BB_, m_);
} }
FCmpInst *create_fcmp_le(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_le(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::LE, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::LE, lhs, rhs, this->BB_, m_);
} }
FCmpInst *create_fcmp_ge(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_ge(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::GE, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::GE, lhs, rhs, this->BB_, m_);
} }
FCmpInst *create_fcmp_gt(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_gt(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::GT, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::GT, lhs, rhs, this->BB_, m_);
} }
FCmpInst *create_fcmp_eq(Value *lhs, Value *rhs) { FCmpInst *create_fcmp_eq(Value *lhs, Value *rhs)
{
return FCmpInst::create_fcmp(FCmpInst::EQ, lhs, rhs, this->BB_, m_); return FCmpInst::create_fcmp(FCmpInst::EQ, lhs, rhs, this->BB_, m_);
} }
BinaryInst *create_fadd(Value *lhs, Value *rhs) { return BinaryInst::create_fadd(lhs, rhs, this->BB_, m_); } BinaryInst *create_fadd(Value *lhs, Value *rhs)
BinaryInst *create_fsub(Value *lhs, Value *rhs) { return BinaryInst::create_fsub(lhs, rhs, this->BB_, m_); } {
BinaryInst *create_fmul(Value *lhs, Value *rhs) { return BinaryInst::create_fmul(lhs, rhs, this->BB_, m_); } return BinaryInst::create_fadd(lhs, rhs, this->BB_, m_);
BinaryInst *create_fdiv(Value *lhs, Value *rhs) { return BinaryInst::create_fdiv(lhs, rhs, this->BB_, m_); } }
BinaryInst *create_fsub(Value *lhs, Value *rhs)
{
return BinaryInst::create_fsub(lhs, rhs, this->BB_, m_);
}
BinaryInst *create_fmul(Value *lhs, Value *rhs)
{
return BinaryInst::create_fmul(lhs, rhs, this->BB_, m_);
}
BinaryInst *create_fdiv(Value *lhs, Value *rhs)
{
return BinaryInst::create_fdiv(lhs, rhs, this->BB_, m_);
}
}; };
#endif // SYSYC_IRBUILDER_H #endif // SYSYC_IRBUILDER_H
This diff is collapsed.
...@@ -8,35 +8,35 @@ target_link_libraries( ...@@ -8,35 +8,35 @@ target_link_libraries(
IR_lib IR_lib
) )
# add_executable( add_executable(
# stu_assign_generator stu_assign_generator
# stu_cpp/assign_generator.cpp stu_cpp/assign_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_assign_generator stu_assign_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_fun_generator stu_fun_generator
# stu_cpp/fun_generator.cpp stu_cpp/fun_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_fun_generator stu_fun_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_if_generator stu_if_generator
# stu_cpp/if_generator.cpp stu_cpp/if_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_if_generator stu_if_generator
# IR_lib IR_lib
# ) )
# add_executable( add_executable(
# stu_while_generator stu_while_generator
# stu_cpp/while_generator.cpp stu_cpp/while_generator.cpp
# ) )
# target_link_libraries( target_link_libraries(
# stu_while_generator stu_while_generator
# IR_lib IR_lib
# ) )
#include "Module.h"
#include "IRBuilder.h"
#include "Type.h"
#include "Constant.h"
#include <iostream>
#include <vector>
int main()
{
auto mod = new Module("assign.c");
auto bud = new IRBuilder(nullptr, mod);
auto I32Type = Type::get_int32_type(mod);
auto I32x10Type = Type::get_array_type(I32Type, 10);
std::vector<Type *> NoneArg;
auto mainTp = FunctionType::get(I32Type, NoneArg);
auto mainFunc = Function::create(mainTp, "main", mod);
auto bb = BasicBlock::create(mod, "entry", mainFunc);
bud->set_insert_point(bb);
auto arr_ptr = bud->create_alloca(I32x10Type);
auto a0_ptr = bud->create_gep(
arr_ptr, {ConstantInt::get(0, mod), ConstantInt::get(0, mod)});
auto a1_ptr = bud->create_gep(
arr_ptr, {ConstantInt::get(0, mod), ConstantInt::get(0, mod)});
bud->create_store(ConstantInt::get(10, mod), a0_ptr);
auto a0_load = bud->create_load(a0_ptr);
auto mul = bud->create_imul(a0_load, ConstantInt::get(2, mod));
bud->create_store(mul, a1_ptr);
auto a1_load = bud->create_load(a1_ptr);
bud->create_ret(a1_load);
std::cout << mod->print();
delete mod;
return 0;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int main()
{
auto mod = new Module("Cminus code"); // module name是什么无关紧要
auto bud = new IRBuilder(nullptr, mod);
Type *I32Type = Type::get_int32_type(mod);
std::vector<Type *> OneIntArg(1, I32Type);
auto calleeTp = FunctionType::get(I32Type, OneIntArg);
auto calleeFunc = Function::create(calleeTp, "callee", mod);
auto bb = BasicBlock::create(mod, "entry", calleeFunc);
bud->set_insert_point(bb);
std::vector<Value *> arg_vs;
for (auto arg = calleeFunc->arg_begin(); arg != calleeFunc->arg_end();
arg++)
arg_vs.push_back(*arg);
auto mul = bud->create_imul(arg_vs[0], ConstantInt::get(2, mod));
bud->create_ret(mul);
auto mainTp = FunctionType::get(I32Type, {});
auto mainFunc = Function::create(mainTp, "main", mod);
bb = BasicBlock::create(mod, "entry", mainFunc);
bud->set_insert_point(bb);
auto call = bud->create_call(calleeFunc, {ConstantInt::get(110, mod)});
bud->create_ret(call);
std::cout << mod->print();
delete mod;
return 0;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int main()
{
auto mod = new Module("if.c");
auto bud = new IRBuilder(nullptr, mod);
Type *I32Type = Type::get_int32_type(mod);
Type *floatType = Type::get_float_type(mod);
auto mainTp = FunctionType::get(I32Type, {});
auto mainFunc = Function::create(mainTp, "main", mod);
auto bb = BasicBlock::create(mod, "entry", mainFunc);
bud->set_insert_point(bb);
auto aAlloc = bud->create_alloca(floatType);
bud->create_store(ConstantFP::get(5.555, mod), aAlloc);
auto aValue = bud->create_load(aAlloc);
auto cond = bud->create_fcmp_gt(aValue, ConstantFP::get(1, mod));
auto TBB = BasicBlock::create(mod, "trueCase", mainFunc);
auto FBB = BasicBlock::create(mod, "falseCase", mainFunc);
bud->create_cond_br(cond, TBB, FBB);
bud->set_insert_point(TBB);
bud->create_ret(ConstantInt::get(233, mod));
bud->set_insert_point(FBB);
bud->create_ret(ConstantInt::get(0, mod));
std::cout << mod->print();
delete mod;
return 0;
}
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int main()
{
auto mod = new Module("while.c");
auto bud = new IRBuilder(nullptr, mod);
Type *I32Type = Type::get_int32_type(mod);
// main函数
auto mainFunc =
Function::create(FunctionType::get(I32Type, {}), "main", mod);
auto bb = BasicBlock::create(mod, "entry", mainFunc);
auto judge = BasicBlock::create(mod, "judge", mainFunc);
auto loop = BasicBlock::create(mod, "loop", mainFunc);
auto exit = BasicBlock::create(mod, "exit", mainFunc);
bud->set_insert_point(bb);
auto aAlloc = bud->create_alloca(I32Type);
auto iAlloc = bud->create_alloca(I32Type);
bud->create_store(ConstantInt::get(10, mod), aAlloc);
bud->create_store(ConstantInt::get(0, mod), iAlloc);
bud->create_br(judge);
bud->set_insert_point(judge);
auto iV = bud->create_load(iAlloc);
auto cond = bud->create_icmp_lt(iV, ConstantInt::get(10, mod));
bud->create_cond_br(cond, loop, exit);
bud->set_insert_point(loop);
auto add = bud->create_iadd(iV, ConstantInt::get(1, mod));
bud->create_store(add, iAlloc);
//
auto aV = bud->create_load(aAlloc);
auto aadd = bud->create_iadd(add, aV);
bud->create_store(aadd, aAlloc);
bud->create_br(judge);
bud->set_insert_point(exit);
aV = bud->create_load(aAlloc);
bud->create_ret(aV);
std::cout << mod->print();
delete mod;
return 0;
}
define dso_local i32 @main() #0 { define dso_local i32 @main() #0 {
%a = alloca [10 x i32], align 4 %a = alloca [10 x i32]
; ptr is the pointer with type i32* ; ptr is the pointer with type i32*
%ptr = getelementptr [10 x i32], [10 x i32]* %a, i64 0, i64 0 %ptr = getelementptr [10 x i32], [10 x i32]* %a, i64 0, i64 0
%a0 = getelementptr i32, i32* %ptr, i64 0 ; %a0 = getelementptr i32, i32* %ptr, i64 0
%a1 = getelementptr i32, i32* %ptr, i64 1 %a1 = getelementptr i32, i32* %ptr, i64 1
store i32 10, i32* %a0 store i32 10, i32* %ptr
%v1 = load i32, i32* %a0 %v1 = load i32, i32* %ptr
%v2 = mul i32 %v1, 2 %v2 = mul i32 %v1, 2
store i32 %v2, i32* %a1 store i32 %v2, i32* %a1
%r = load i32, i32* %a1 %r = load i32, i32* %a1
......
...@@ -12,12 +12,13 @@ ...@@ -12,12 +12,13 @@
* #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // * #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; //
* 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */ * 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例 // 输出行号的简单示例
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl;
#define CONST_INT(num) ConstantInt::get(num, mod) #define CONST_INT(num) ConstantInt::get(num, mod)
#define CONST_FP(num) \ // 得到常数值的表示,方便后面多次用到
ConstantFP::get(num, mod) // 得到常数值的表示,方便后面多次用到 #define CONST_FP(num) ConstantFP::get(num, mod)
int main() int main()
{ {
...@@ -71,9 +72,10 @@ int main() ...@@ -71,9 +72,10 @@ int main()
mod, "", gcdFun); // return分支,提前create,以便true分支可以br mod, "", gcdFun); // return分支,提前create,以便true分支可以br
auto br = builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR auto br = builder->create_cond_br(icmp, trueBB, falseBB); // 条件BR
DEBUG_OUTPUT // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法 DEBUG_OUTPUT; // 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
builder->set_insert_point(
trueBB); // if true; 分支的开始需要SetInsertPoint设置 // if true; 分支的开始需要SetInsertPoint设置
builder->set_insert_point(trueBB);
auto uLoad = builder->create_load(uAlloca); auto uLoad = builder->create_load(uAlloca);
builder->create_store(uLoad, retAlloca); builder->create_store(uLoad, retAlloca);
builder->create_br(retBB); // br retBB builder->create_br(retBB); // br retBB
...@@ -106,8 +108,8 @@ int main() ...@@ -106,8 +108,8 @@ int main()
auto bAlloca = builder->create_alloca(Int32Type); // b的存放 auto bAlloca = builder->create_alloca(Int32Type); // b的存放
auto tempAlloca = builder->create_alloca(Int32Type); // temp的存放 auto tempAlloca = builder->create_alloca(Int32Type); // temp的存放
std::vector<Value *> //获取funArray函数的形参,通过Function中的iterator
args1; //获取funArrayFun函数的形参,通过Function中的iterator std::vector<Value *> args1;
for (auto arg = funArrayFun->arg_begin(); arg != funArrayFun->arg_end(); for (auto arg = funArrayFun->arg_begin(); arg != funArrayFun->arg_end();
arg++) { arg++) {
args1.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素 args1.push_back(*arg); // * 号运算符是从迭代器中取出迭代器当前指向的元素
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment