当前位置:网站首页>LLVM系列第八章:算术运算语句Arithmetic Statement
LLVM系列第八章:算术运算语句Arithmetic Statement
2022-08-02 14:07:00 【飞翼剑仆】
系列文章目录
LLVM系列第一章:编译LLVM源码
LLVM系列第二章:模块Module
LLVM系列第三章:函数Function
LLVM系列第四章:逻辑代码块Block
LLVM系列第五章:全局变量Global Variable
LLVM系列第六章:函数返回值Return
LLVM系列第七章:函数参数Function Arguments
LLVM系列第八章:算术运算语句Arithmetic Statement
LLVM系列第九章:控制流语句if-else
LLVM系列第十章:控制流语句if-else-phi
LLVM系列第十一章:写一个Hello World
LLVM系列第十二章:写一个简单的词法分析器Lexer
LLVM系列第十三章:写一个简单的语法分析器Parser
LLVM系列第十四章:写一个简单的语义分析器Semantic Analyzer
LLVM系列第十五章:写一个简单的中间代码生成器IR Generator
LLVM系列第十六章:写一个简单的编译器
LLVM系列第十七章:for循环
LLVM系列第十八章:写一个简单的IR处理流程Pass
LLVM系列第十九章:写一个简单的Module Pass
LLVM系列第二十章:写一个简单的Function Pass
LLVM系列第二十一章:写一个简单的Loop Pass
LLVM系列第二十二章:写一个简单的编译时函数调用统计器(Pass)
LLVM系列第二十三章:写一个简单的运行时函数调用统计器(Pass)
LLVM系列第二十四章:用Xcode编译调试LLVM源码
LLVM系列第二十五章:简单统计一下LLVM源码行数
前言
在此记录下用LLVM创建一个算术运算语句(Arithmetic Statement)的过程,以备查阅。
开发环境的配置请参考第一章 《LLVM系列第一章:编译LLVM源码》。
一个基本的逻辑代码块(Basic Block)是由一系列的指令(Instruction)组成的。一条指令主要是为了完成某个任务(操作),比如一个算术运算。一条指令可以是一个简单的语句,比如一个算术运算语句。
在LLVM中,一个简单的算术运算需要用到操作符和操作数。例如,一个乘法运算用到了一个乘法操作符和两个乘数。所以,要创建一个乘法运算语句,我们首先要得到两个操作数,比如它可以来自于函数的参数、数字常量等等。我们知道,乘法操作是一个二元操作,IRBuilder里面提供了很多API,可以用来方便地创建二元操作语句。
本章,我们就在一个函数里创建一个简单的算术运算语句。
一、Hello Arithmetic Statement
为简单起见,假定这个函数带有两个整数型参数,它们的名称为a和b。我们把第一个参数乘以3,其结果就是函数的返回值。代码如下(示例):
// HelloArithmeticStatement.cpp
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include <vector>
using namespace llvm;
int main(int argc, char* argv[])
{
LLVMContext context;
IRBuilder<> builder(context);
// Create a module
Module* module = new Module("HelloModule", context);
// Add a global variable
module->getOrInsertGlobal("helloGlobalVariable", builder.getInt32Ty());
GlobalVariable* globalVariable = module->getNamedGlobal("helloGlobalVariable");
globalVariable->setLinkage(GlobalValue::CommonLinkage);
globalVariable->setAlignment(MaybeAlign(4));
// Add a function
std::vector<Type*> parameters(2, builder.getInt32Ty());
FunctionType* functionType = FunctionType::get(builder.getInt32Ty(), parameters, false);
Function* function = Function::Create(functionType, GlobalValue::ExternalLinkage, "HelloFunction", module);
// Set arguments for the function
function->getArg(0)->setName("a");
function->getArg(1)->setName("b");
// Create a block
BasicBlock* block = BasicBlock::Create(context, "entry", function);
builder.SetInsertPoint(block);
// Create an arithmetic statement
Value* arg1 = function->getArg(0);
ConstantInt* three = builder.getInt32(3);
Value* result = builder.CreateMul(arg1, three, "multiplyResult");
// Add a return
builder.CreateRet(result);
// Print the IR
verifyFunction(*function);
module->print(outs(), nullptr);
return 0;
}
二、编译
用clang++进行编译(示例):
# Set up C++ standard library and header path
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
# Compile
clang++ -w -o HelloArithmeticStatement `llvm-config --cxxflags --ldflags --system-libs --libs core` HelloArithmeticStatement.cpp
以上命令会生成一个名为HelloArithmeticStatement的可执行程序。
三、运行
运行HelloArithmeticStatement(示例):
./HelloArithmeticStatement
输出结果如下(示例):
; ModuleID = 'HelloModule'
source_filename = "HelloModule"
@helloGlobalVariable = common global i32, align 4
define i32 @HelloFunction(i32 %a, i32 %b) {
entry:
%multiplyResult = mul i32 %a, 3
ret i32 %multiplyResult
}
以上IR代码中,变量%multiplyResult就是乘法运算的结果,它也是函数的返回值。
四、总结
我们用LLVM提供的C++ API,创建了一个算术运算语句(Arithmetic Statement),并打印出了它的IR代码。完整源码示例请参看:
https://github.com/wuzhanglin/llvm-IR-examples
边栏推荐
猜你喜欢
随机推荐
Flink前期代码结构
C语言——一级指针初识
LLVM系列第十九章:写一个简单的Module Pass
PHP版本切换:5.x到7.3
Flink依赖汇总
线性代数期末复习存档
C语言初级—用一角,两角,五角和一元组成3.5元有多少种组合方法
关于spark
MySQL知识总结 (二) 存储引擎
What?It's 2020, you still can't adapt the screen?
C语言日记 3 常量
LLVM系列第二十六章:理解LLVMContext
IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but
uniCloud 未能获取当前用户信息:30205 | 当前用户为匿名身份
宝塔搭建PHP自适应懒人网址导航源码实测
执行npm install有错误error
C语言一级指针(补)
什么?都0202年了,你还不会屏幕适配?
使用flutter小记
MySQL知识总结 (九) 用户与用户权限管理