LLVM(5)ORC实例分析

2023-10-15 16:30
文章标签 分析 实例 llvm orc

本文主要是介绍LLVM(5)ORC实例分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

ORC实例总结

总结

  1. 因为API茫茫多,逻辑上的一些概念需要搞清,编码时会容易很多。
  2. JIT的运行实体使用LLVMOrcCreateLLJIT可以创建出来,逻辑上的JIT实例。
  3. JIT实例需要加入运行库(依赖库)和用户定义的context(运行内容)才能运行,LLVMOrcLLJITAddLLVMIRModule函数负责将运行库和ctx加入JIT实例。
  4. context相当于给用户自定义代码的上下文,其中可以加入多个module,每个module中又可以加入多个function。可以理解为一个工程(context)里面加入多个文件,每个文件(module)中又包含多个函数(function)。

请添加图片描述

注释

LLVMOrcThreadSafeModuleRef createDemoModule(void) {
// 创建一个新的ThreadSafeContext和底层的LLVMContext。
LLVMOrcThreadSafeContextRef TSCtx = LLVMOrcCreateNewThreadSafeContext();// 获取底层的LLVMContext的引用。
LLVMContextRef Ctx = LLVMOrcThreadSafeContextGetContext(TSCtx);// 创建一个新的LLVM模块。
LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);// 添加一个名为"sum"的函数:
// - 创建函数类型和函数实例。
LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};
LLVMTypeRef SumFunctionType =
LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);
LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);// - 向函数添加一个基本块。
LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");// - 创建一个IR构建器并将其定位到基本块的末尾。
LLVMBuilderRef Builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(Builder, EntryBB);// - 获取两个函数参数,并使用它们构造一个"add"指令。
LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);
LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);
LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");// - 构建返回指令。
LLVMBuildRet(Builder, Result);// 演示模块现在已经完成。将其和ThreadSafeContext封装到ThreadSafeModule中。
LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(M, TSCtx);// 释放本地的ThreadSafeContext值。底层的LLVMContext将由ThreadSafeModule TSM保持活动状态。
LLVMOrcDisposeThreadSafeContext(TSCtx);// 返回结果。
return TSM;
}int main(int argc, char *argv[]) {
int MainResult = 0;// 解析命令行参数并初始化LLVM Core。
LLVMParseCommandLineOptions(argc, (const char **)argv, "");
LLVMInitializeCore(LLVMGetGlobalPassRegistry());// 初始化本地目标代码生成和汇编打印器。
LLVMInitializeNativeTarget();
LLVMInitializeNativeAsmPrinter();// 创建LLJIT实例。
LLVMOrcLLJITRef J;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {
MainResult = handleError(Err);
goto llvm_shutdown;
}
}// 创建演示模块。
LLVMOrcThreadSafeModuleRef TSM = createDemoModule();// 将演示模块添加到JIT中。
{
LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J);
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITAddLLVMIRModule(J, MainJD, TSM))) {
// 如果添加ThreadSafeModule失败,我们需要自己清理它。
// 如果添加成功,JIT将管理内存。
LLVMOrcDisposeThreadSafeModule(TSM);
MainResult = handleError(Err);
goto jit_cleanup;
}
}// 查找演示入口点的地址。
LLVMOrcJITTargetAddress SumAddr;
{
LLVMErrorRef Err;
if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {
MainResult = handleError(Err);
goto jit_cleanup;
}
}// 如果程序执行到这里,说明一切顺利。执行JIT生成的代码。
int32_t (Sum)(int32_t, int32_t) = (int32_t()(int32_t, int32_t))SumAddr;
int32_t Result = Sum(1, 2);// 打印结果。
printf("1 + 2 = %i\n", Result);jit_cleanup:
// 销毁JIT实例。这将清理JIT所拥有的任何内存。
// 这个操作是非平凡的(例如,可能需要JIT静态析构函数),也可能失败。
// 如果失败,我们希望将错误输出到stderr,但不要覆盖任何现有的返回值。
{
LLVMErrorRef Err;
if ((Err = LLVMOrcDisposeLLJIT(J))) {
int NewFailureResult = handleError(Err);
if (MainResult == 0) MainResult = NewFailureResult;
}
}llvm_shutdown:
// 关闭LLVM。
LLVMShutdown();return MainResult;
}

ORC完整

//===------ OrcV2CBindingsBasicUsage.c - Basic OrcV2 C Bindings Demo ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//#include <stdio.h>#include "llvm-c/Core.h"
#include "llvm-c/Error.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/LLJIT.h"
#include "llvm-c/Support.h"
#include "llvm-c/Target.h"int handleError(LLVMErrorRef Err) {char *ErrMsg = LLVMGetErrorMessage(Err);fprintf(stderr, "Error: %s\n", ErrMsg);LLVMDisposeErrorMessage(ErrMsg);return 1;
}LLVMOrcThreadSafeModuleRef createDemoModule(void) {// Create a new ThreadSafeContext and underlying LLVMContext.LLVMOrcThreadSafeContextRef TSCtx = LLVMOrcCreateNewThreadSafeContext();// Get a reference to the underlying LLVMContext.LLVMContextRef Ctx = LLVMOrcThreadSafeContextGetContext(TSCtx);// Create a new LLVM module.LLVMModuleRef M = LLVMModuleCreateWithNameInContext("demo", Ctx);// Add a "sum" function"://  - Create the function type and function instance.LLVMTypeRef ParamTypes[] = {LLVMInt32Type(), LLVMInt32Type()};LLVMTypeRef SumFunctionType =LLVMFunctionType(LLVMInt32Type(), ParamTypes, 2, 0);LLVMValueRef SumFunction = LLVMAddFunction(M, "sum", SumFunctionType);//  - Add a basic block to the function.LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock(SumFunction, "entry");//  - Add an IR builder and point it at the end of the basic block.LLVMBuilderRef Builder = LLVMCreateBuilder();LLVMPositionBuilderAtEnd(Builder, EntryBB);//  - Get the two function arguments and use them co construct an "add"//    instruction.LLVMValueRef SumArg0 = LLVMGetParam(SumFunction, 0);LLVMValueRef SumArg1 = LLVMGetParam(SumFunction, 1);LLVMValueRef Result = LLVMBuildAdd(Builder, SumArg0, SumArg1, "result");//  - Build the return instruction.LLVMBuildRet(Builder, Result);// Our demo module is now complete. Wrap it and our ThreadSafeContext in a// ThreadSafeModule.LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule(M, TSCtx);// Dispose of our local ThreadSafeContext value. The underlying LLVMContext// will be kept alive by our ThreadSafeModule, TSM.LLVMOrcDisposeThreadSafeContext(TSCtx);// Return the result.return TSM;
}int main(int argc, char *argv[]) {int MainResult = 0;// Parse command line arguments and initialize LLVM Core.LLVMParseCommandLineOptions(argc, (const char **)argv, "");LLVMInitializeCore(LLVMGetGlobalPassRegistry());// Initialize native target codegen and asm printer.LLVMInitializeNativeTarget();LLVMInitializeNativeAsmPrinter();// Create the JIT instance.LLVMOrcLLJITRef J;{LLVMErrorRef Err;if ((Err = LLVMOrcCreateLLJIT(&J, 0))) {MainResult = handleError(Err);goto llvm_shutdown;}}// Create our demo module.LLVMOrcThreadSafeModuleRef TSM = createDemoModule();// Add our demo module to the JIT.{LLVMOrcJITDylibRef MainJD = LLVMOrcLLJITGetMainJITDylib(J);LLVMErrorRef Err;if ((Err = LLVMOrcLLJITAddLLVMIRModule(J, MainJD, TSM))) {// If adding the ThreadSafeModule fails then we need to clean it up// ourselves. If adding it succeeds the JIT will manage the memory.LLVMOrcDisposeThreadSafeModule(TSM);MainResult = handleError(Err);goto jit_cleanup;}}// Look up the address of our demo entry point.LLVMOrcJITTargetAddress SumAddr;{LLVMErrorRef Err;if ((Err = LLVMOrcLLJITLookup(J, &SumAddr, "sum"))) {MainResult = handleError(Err);goto jit_cleanup;}}// If we made it here then everything succeeded. Execute our JIT'd code.int32_t (*Sum)(int32_t, int32_t) = (int32_t(*)(int32_t, int32_t))SumAddr;int32_t Result = Sum(1, 2);// Print the result.printf("1 + 2 = %i\n", Result);jit_cleanup:// Destroy our JIT instance. This will clean up any memory that the JIT has// taken ownership of. This operation is non-trivial (e.g. it may need to// JIT static destructors) and may also fail. In that case we want to render// the error to stderr, but not overwrite any existing return value.{LLVMErrorRef Err;if ((Err = LLVMOrcDisposeLLJIT(J))) {int NewFailureResult = handleError(Err);if (MainResult == 0) MainResult = NewFailureResult;}}llvm_shutdown:// Shut down LLVM.LLVMShutdown();return MainResult;
}

这篇关于LLVM(5)ORC实例分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/218372

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

Java操作ElasticSearch的实例详解

《Java操作ElasticSearch的实例详解》Elasticsearch是一个分布式的搜索和分析引擎,广泛用于全文搜索、日志分析等场景,本文将介绍如何在Java应用中使用Elastics... 目录简介环境准备1. 安装 Elasticsearch2. 添加依赖连接 Elasticsearch1. 创

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制