LLVM(5)ORC实例分析
ORC实例总结
总结
- 因为API茫茫多,逻辑上的一些概念需要搞清,编码时会容易很多。
- JIT的运行实体使用LLVMOrcCreateLLJIT可以创建出来,逻辑上的JIT实例。
- JIT实例需要加入运行库(依赖库)和用户定义的context(运行内容)才能运行,LLVMOrcLLJITAddLLVMIRModule函数负责将运行库和ctx加入JIT实例。
- 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实例分析
ORC实例总结 总结 因为API茫茫多,逻辑上的一些概念需要搞清,编码时会容易很多。JIT的运行实体使用LLVMOrcCreateLLJIT可以创建出来,逻辑上的JIT实例。JIT实例需要加入运行库(依赖库)和用户定义的context(…...
jvm内存使用测试
记一次摸不着头脑的FullGC问题 (Thumbnails压缩图片占用巨大内存)_thumbnails内存溢出-CSDN博客 谈谈Runtime类中的freeMemory,totalMemory,maxMemory几个方法-CSDN博客 JVM实战:CMS和G1的物理内存归还机制_shrinkheapinsteps-CSDN博客 J…...

Web1.0——Web2.0时代——Web3.0
Web1.0 Web1.0是互联网的早期阶段,也被称为个人电脑时代的互联网。在这个阶段,用户主要通过web浏览器从门户网站单向获取内容,进行浏览和搜索等操作。在这个时代,技术创新主导模式、基于点击流量的盈利共通点、门户合流、明晰的主…...

【深蓝学院】手写VIO第7章--VINS初始化和VIO系统--笔记
0. 内容 1. VIO回顾 整个视觉前端pipeline回顾: 两帧图像,可提取特征点,特征匹配(描述子暴力匹配或者光流)已知特征点匹配关系,利用几何约束计算relative pose([R|t]),translation只有方向&…...
大开眼界:Netbios 上古时代如何用一个参数实现一个世界 负面典型
今天的程序员普遍遵循这样的接口设计原则:通过不同的接口名和参数列表准确表达不同的功能。 这似乎是理所当然的,然而上古时代却并非如此,比如Netbios协议整个协议的接口只有一个函数、一个参数! 当初是基于什么原则这样设计不晓得…...
el-table制作表格,改变表格的滚动条样式
// 改变滚动条相关样式 *::-webkit-scrollbar {width:10px; height:0px; background-color:transparent;} /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ *::-webkit-scrollbar-track {background-color: rgba(0,0,0,0.3); } /*定义滚动条轨道 内阴影圆角*/ *::-web…...
Cmd报错:No module named ‘pip’
目录 1、问题描述2、问题原因3、问题解决 1、问题描述 今天在cmd命令行安装Twisted的扩展包whl文件时报错: ...... ModuleNotFoundError: No module named pip2、问题原因 升级pip时命令使用错误 3、问题解决 1) 重装pip python -m ensurepip2&#x…...
python输出奇数:如何使用Python输出奇数?
Python输出奇数的方法有很多种,下面给出一种使用for循环的实现方式:上述代码的输出结果为: Python输出奇数的方法有很多种,下面给出一种使用for循环的实现方式: # 定义一个变量n,表示要输出的奇数的最大值…...

2023 NewStarCTF --- wp
文章目录 前言Week1MiscCyberChefs Secret机密图片流量!鲨鱼!压缩包们空白格隐秘的眼睛 Web泄露的秘密Begin of UploadErrorFlaskBegin of HTTPBegin of PHPR!C!E!EasyLogin CryptobrainfuckCaesars SecertfenceVigenrebabyrsaSmall dbabyxorbabyencodin…...

一键切换IP地址:电脑IP更改的简便方法
今天我要和大家分享一个电脑IP更改的简便方法——一键切换IP地址。如果您想要更改电脑的IP地址,无需繁琐的设置和复杂的步骤,只需使用以下简单的方法,即可轻松实现IP地址的切换。让我们开始吧! 1、使用批处理脚本 批处理脚本是一…...
计算机相关内容的网站主题说明书
1. 网站名称: 中职计算机学堂 2. 网站目标: 主要目标:为中职学生提供计算机基础教程、编程入门、IT技能培训。次要目标:鼓励学生发表自己的作品,交流技术问题,构建IT爱好者社区。 3. 目标受众࿱…...

zabbix监控项
一、监控项(items) 1、获取监控数据的方式: ① zabbix-agent:代理程序是在被监控主机上运行的软件,负责收集和报告有关主机性能和状态的数据,监控系统通过与代理程序通信来获取数据。 ② SNMP࿱…...
Java基础面试-重载和重写的区别
重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可 以不同,发生在编译时。 重写:发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类&…...

记一次生产大对象及GC时长优化经验
最近在做一次系统整体优化,发现系统存在GC时长过长及JVM内存溢出的问题,记录一下优化的过程 面试的时候我们都被问过如何处理生产问题,尤其是线上oom或者GC调优的问题更是必问,所以到底应该如何发现解决这些问题呢,用真实的场景实操ÿ…...
Vue项目为页面添加水印效果
最近在做项目,有这样要求,需要在指定容器中添加水印,也可不设置容器,如果没有容器,则添加在整个页面中,即body,当接到这个需求的时候我第一想的方法就是用canvas来实现,话不多说搞起…...
两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...

试过GPT-4V后,微软写了个166页的测评报告,业内人士:高级用户必读
一周之前,ChatGPT迎来重大更新,不管是 GPT-4 还是 GPT-3.5 模型,都可以基于图像进行分析和对话。与之对应的,多模态版GPT-4V模型相关文档也一并放出。当时 OpenAI 放出的文档只有18页,很多内容都无从得知,对…...
使用Python构造VARIMA模型
简介 VARMA(p,q)结合了VAR和VMA模型,其中p是向量自回归(VAR)模型的滞后期数,q是VMA模型的移动平均的阶数。 VARMA是ARMA的推广,它将ARMA模型扩展到多个时间序列变量的情况,通过VAR和VMA的线性组合来描述多个时间序列变量之间的联…...

Java基于SpringBoot+Vue的考研资讯平台
1 简介 大家好,我是程序员徐师兄,今天为大家带来的是Java基于SpringBootVue的考研资讯平台 Java基于SpringBoot的考研资讯平台,在系统当中学生可以根据不同的信息来实现该网站的考研资讯平台信息的管理。 系统主要分为前台和后台。主要包括…...

信钰证券:9月以来A股20家银行 获机构不同批次调研
Wind数据显现,自9月份以来,已经有20家银行获安排不同批次调研。其间常熟银行、瑞丰银行被调研次数较多,别离为20次、11次;宁波银行、渝农商行获安排调研家数居前,别离为206家、128家。从上市银行宣布的调研情况来看&am…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...