04_llvm_IR测试生成运算指令
四则运算指令
介绍如下:
#include <vector>
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/GlobalVariable.h"
// #include "llvm/Support/Alignment.h"
#include "llvm/IR/Constants.h"
using namespace llvm;
using namespace std;
/*
代码块(BasicBlock)由一系列指令(Instruction)组成,完成算术与逻辑等运算操作,
如一个加法算术操作,操作符是"+",操作数可来自参数、变量、常量等,统一都由IRBuilder类来创建。
*/
int main() {
LLVMContext c;
Module *m = new Module("test module", c);
IRBuilder<> builder(c);
// 创建一个全局变量
m->getOrInsertGlobal("test_global_var", Type::getInt32Ty(c));
GlobalVariable *gv = m->getNamedGlobal("test_global_var");
gv->setLinkage(GlobalValue::CommonLinkage); // 链接类型
/*llvm 13写法
函数定义变了 ../output/include/llvm/IR/GlobalObject.h函数 void setAlignment(MaybeAlign Align);
其中 include/llvm/Support/Alignment.h:109:struct MaybeAlign : public llvm::Optional<Align> {
*/
// gv->setAlignment(MaybeAlign(4));/*llvm 13写法*/
/*以下是基于低版本llvm 6.0的写法*/
// llvm-6.0/include/llvm/IR/GlobalObject.h:64函数 void setAlignment(unsigned Align),参数是unsigned int即可
gv->setAlignment(4);
// Type *voidTy = Type::getVoidTy(c);// 原来创建void 参数类型
vector<Type *> paramTys(2, builder.getInt32Ty());
/*get函数在 include/llvm/IR/DerivedTypes.h:102:class FunctionType : public Type {
/// This static method is the primary way of constructing a FunctionType.
static FunctionType *get(Type *Result, ArrayRef<Type*> Params, bool isVarArg);
*/
FunctionType *funcTy = FunctionType::get(builder.getInt32Ty(), paramTys, false);
Function *func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "test_function IR", m);
// 低版本无getArg()函数
func->getArg(0)->setName("a");
func->getArg(1)->setName("b");
// 创建一个block
BasicBlock *b = BasicBlock::Create(c, "entry_block", func);
builder.SetInsertPoint(b);
// arg0 + arg1 * 2,return ret
Value *arg0 = func->getArg(0);
Value *arg1 = func->getArg(1);
ConstantInt *two = builder.getInt32(2);
Value *tmp = builder.CreateMul(arg1, two, "mul_ans");
Value *ret = builder.CreateAdd(arg0, tmp, "add_ans");
// 创建返回值
builder.CreateRet(ret);
verifyFunction(*func);
m->print(outs(), nullptr);
return 0;
}
// 编译命令 ../clang-16/bin/clang++ -w -o test_return_bin `llvm-config --cxxflags --ldflags --system-libs --libs core` ./07_test_statement.cpp
// 运行结果
/*
; ModuleID = 'test module'
source_filename = "test module"
@test_global_var = common global i32, align 4
define i32 @"test_function IR"(i32 %a, i32 %b) {
entry_block:
%mul_ans = mul i32 %b, 2
%add_ans = add i32 %a, %mul_ans
ret i32 %add_ans
}
*/