LLVM系列第八章:算术运算语句Arithmetic Statement
系列文章目錄
LLVM系列第一章:編譯LLVM源碼
LLVM系列第二章:模塊Module
LLVM系列第三章:函數(shù)Function
LLVM系列第四章:邏輯代碼塊Block
LLVM系列第五章:全局變量Global Variable
LLVM系列第六章:函數(shù)返回值Return
LLVM系列第七章:函數(shù)參數(shù)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循環(huán)
LLVM系列第十八章:寫一個簡單的IR處理流程Pass
LLVM系列第十九章:寫一個簡單的Module Pass
LLVM系列第二十章:寫一個簡單的Function Pass
LLVM系列第二十一章:寫一個簡單的Loop Pass
LLVM系列第二十二章:寫一個簡單的編譯時函數(shù)調用統(tǒng)計器(Pass)
LLVM系列第二十三章:寫一個簡單的運行時函數(shù)調用統(tǒng)計器(Pass)
LLVM系列第二十四章:用Xcode編譯調試LLVM源碼
LLVM系列第二十五章:簡單統(tǒng)計一下LLVM源碼行數(shù)
LLVM系列第二十六章:理解LLVMContext
LLVM系列第二十七章:理解IRBuilder
LLVM系列第二十八章:寫一個JIT Hello World
LLVM系列第二十九章:寫一個簡單的常量加法“消除”工具(Pass)
flex&bison系列
本文目錄
- 前言
- 一、Hello Arithmetic Statement
- 二、編譯
- 三、運行
- 四、總結
前言
在此記錄下用LLVM創(chuàng)建一個算術運算語句(Arithmetic Statement)的過程,以備查閱。
開發(fā)環(huán)境的配置請參考第一章 《LLVM系列第一章:編譯LLVM源碼》。
我們知道一個基本邏輯代碼塊(BasicBlock)是由一系列的指令(Instruction)組成的。一條指令主要是為了完成某個任務(操作),比如一個算術運算操作。為簡單起見,我們在這里可以把一個簡單的算術運算語句理解為一條指令。
在LLVM中,一個簡單的算術運算操作需要用到操作符和操作數(shù)。例如,一個乘法操作用到了一個乘法操作符和兩個乘數(shù)。所以,要創(chuàng)建一條乘法運算指令,我們首先要得到兩個操作數(shù),它們可以來自于函數(shù)的參數(shù)、數(shù)值變量、數(shù)值常量等等。乘法操作是一個二元操作,IRBuilder里面提供了很多API,可以用來方便地創(chuàng)建二元操作指令。
本章,我們就在一個函數(shù)里創(chuàng)建一條簡單的算術運算指令。
一、Hello Arithmetic Statement
為簡單起見,假定這個函數(shù)帶有兩個整數(shù)型參數(shù),它們的名稱分別為a和b。我們把第一個參數(shù)乘以3,其結果就是函數(shù)的返回值。代碼如下(示例):
// 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 moduleModule* module = new Module("HelloModule", context);// Add a global variablemodule->getOrInsertGlobal("helloGlobalVariable", builder.getInt32Ty());GlobalVariable* globalVariable = module->getNamedGlobal("helloGlobalVariable");globalVariable->setLinkage(GlobalValue::CommonLinkage);globalVariable->setAlignment(MaybeAlign(4));// Add a function with parametersstd::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 functionfunction->getArg(0)->setName("a");function->getArg(1)->setName("b");// Create a blockBasicBlock* block = BasicBlock::Create(context, "entry", function);builder.SetInsertPoint(block);// Create an arithmetic statementValue* arg1 = function->getArg(0);ConstantInt* three = builder.getInt32(3);Value* result = builder.CreateMul(arg1, three, "multiplyResult");// Add a returnbuilder.CreateRet(result);// Print the IRverifyFunction(*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的可執(zhí)行程序。
三、運行
運行HelloArithmeticStatement(示例):
./HelloArithmeticStatement輸出結果如下(示例):
; ModuleID = 'HelloModule' source_filename = "HelloModule"@helloGlobalVariable = common global i32, align 4define i32 @HelloFunction(i32 %a, i32 %b) { entry:%multiplyResult = mul i32 %a, 3ret i32 %multiplyResult }以上IR代碼中,變量%multiplyResult就是乘法運算的結果,也是函數(shù)的返回值。
四、總結
我們用LLVM提供的C++ API,創(chuàng)建了一個算術運算語句(Arithmetic Statement),并打印出了它的IR代碼。完整源碼示例請參看:
https://github.com/wuzhanglin/llvm-IR-examples
總結
以上是生活随笔為你收集整理的LLVM系列第八章:算术运算语句Arithmetic Statement的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html做一个京东搜索功能,连续动作:自
- 下一篇: 2023驾考宝典