IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> LLVM系列第二十八章:写一个JIT Hello World -> 正文阅读

[移动开发]LLVM系列第二十八章:写一个JIT Hello World

系列文章目录

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系列第二十六章:理解LLVMContext
LLVM系列第二十七章:理解IRBuilder
LLVM系列第二十八章:写一个JIT Hello World



前言

在此记录下基于LLVM提供的ORC JIT引擎写一个简单的Hello World的过程,以备查阅。

开发环境的配置请参考第一章 《LLVM系列第一章:编译LLVM源码》。

ORC(On Request Compilation)是LLVM提供的新一代JIT引擎。JIT(Just In Time)也是一个程序,它在运行时,创建并执行了一些新的代码,而这些新代码并不是属于JIT程序本身的。以下是原英文解释:

Whenever a program, while running, creates and runs some new executable code which was not part of the program when it was stored on disk, it’s a JIT.

LLVM提供了三种JIT的实现:

  1. Legacy JIT (LLVM 1.0 - 3.5),引入了ExecutionEngine、延迟编译(lazy compilation),在当前进程中运行(in-process only),在 LLVM 3.5之后被移除了
  2. MCJIT (LLVM 2.9 - 现在),实现了ExecutionEngine,可编译链接多个目标(cross-target),不支持延迟编译
  3. ORC JIT (LLVM 3.7 - 现在),提供预先查询(forward looking) API,没有实现ExecutionEngine

本章我们就来写一个简单的Hello World,初步感受一下LLVM的ORC JIT引擎是什么样子的。

一、Hello JIT

为了简单起见,我们就用以下IR代码为例子,试着调用ORC JIT来编译并执行它:

; ModuleID = 'Add.c'
source_filename = "Add.c"

define i32 @Add(i32 %a, i32 %b) {
entry:
  %result = add i32 %a, %b
  ret i32 %result
}

其对应的C代码如下(示例):

// Add.c

int Add(int a, int b)
{
    return a + b;
}

以下我们就来调用LLVM API生成IR代码,并调用ORC JIT对其进行编译执行(示例):

// HelloJIT.cpp

#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include <iostream>
#include <utility>
#include <vector>

using namespace llvm;
using namespace llvm::orc;

typedef int (*AddFunctionType)(int, int);

// Create a module to represent the following C function
//   int Add(int a, int b)
//   {
//       return a + b;
//   }
ThreadSafeModule CreateModule()
{
    auto context = std::make_unique<LLVMContext>();
    IRBuilder<> builder(*context);

    // Create a module
    auto module = std::make_unique<Module>("Add.c", *context);

    // Create a function that looks like:
    //   int Add(int a, int b)
    std::vector<Type*> parameters(2, builder.getInt32Ty());
    FunctionType* functionType = FunctionType::get(builder.getInt32Ty(), parameters, false);
    Function* function = Function::Create(functionType, GlobalValue::ExternalLinkage, "Add", module.get());

    // Set arguments for the function
    function->getArg(0)->setName("a");
    function->getArg(1)->setName("b");

    // Create a block in the function
    BasicBlock* block = BasicBlock::Create(*context, "entry", function);
    builder.SetInsertPoint(block);

    // Create an instruction to add a and b:
    //   return a + b;
    Value* a = function->getArg(0);
    Value* b = function->getArg(1);
    Value* result = builder.CreateAdd(a, b, "result");
    builder.CreateRet(result);

    // Print the IR
    verifyFunction(*function);
    module->print(outs(), nullptr);

    return ThreadSafeModule(std::move(module), std::move(context));
}

// Compile and run the "Add()" function
int main(int argc, char* argv[])
{
    // Do initialization for JIT
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();

    // Create the JIT
    ExitOnError ExitOnErr;
    auto jit = ExitOnErr(LLJITBuilder().create());
    auto module = CreateModule();
    ExitOnErr(jit->addIRModule(std::move(module)));

    // Find the "Add()" function
    auto functionSymbol = ExitOnErr(jit->lookup("Add"));
    AddFunctionType add = (AddFunctionType)functionSymbol.getAddress();

    // Use the "Add()" function
    int result = add(12, 34);
    std::cout << "\n-----------------\n";
    std::cout << "Add(12, 34) = " << result << std::endl;

    return 0;
}

二、编译

用clang++进行编译(示例):

# Set up C++ standard library and header path
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)

# Compile
clang++ -w -o HelloJIT `llvm-config --cxxflags --ldflags --system-libs --libs all` HelloJIT.cpp

以上命令会生成一个名为HelloJIT的可执行程序。

三、运行

运行HelloJIT(示例):

./HelloJIT

输出结果如下(示例):

; ModuleID = 'Add.c'
source_filename = "Add.c"

define i32 @Add(i32 %a, i32 %b) {
entry:
  %add.result = add i32 %a, %b
  ret i32 %add.result
}

-----------------
Add(12, 34) = 46

四、总结

我们利用LLVM提供的OCR JIT引擎,编译并执行了一段简单的IR代码。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:55:38  更:2022-08-06 10:57:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:21:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码