LLVM的中间表示

news2024/11/28 21:47:00

概括

选择编译器IR的决策很重要,它决定了优化过程将拥有多少信息来使代码运行得更快。

一方面非常高层级的IR允许优化器轻松地提取原始源代码的相关信息。

另一方面,低层的IR更加贴近目标机器,这样编译器更容易为特定的硬件生成相应的代码,并有可能利用目标机器的特性

但是IR的层级又不能太低

  • 当编译器将程序转换为更接近机器指令的表示时,将程序片段映射到源码会变得越来越困难
  • 如果编译器的IR设计采用与特定目标机器非常相似的表示,将不利于为其他不同结构的机器代码生成

LLVM项目从一系列围绕LLVM IR工具展开,这证明优化器是成熟的,用于本层的优化器数量是合理的。IR有三种等价的表达形式:

1.内存表示(Instruction类等)
2.被压缩的磁盘表示(位码文件)
3.人工可读文本的磁盘表示(LLVM汇编文件)

LLVM提供的工具和库使你能处理以上所有形式的IR,并且这些工具能够对IR进行不同表示形式的转换,同时应用优化

在这里插入图片描述

理解LLVMIR对编译目标的依赖

LLVM IR被设计成尽可能地与编译目标无关,但它仍然对编译目标有一定的依赖性。造成该依赖性的一个普遍承认的原因是C/C++语言固有的目标以来性质。要理解这一点,可以将在Linux系统中使用标准C头文件作为例子:程序会从Linux头文件专用文件夹bits中隐式导入一些文件。此文件加包含目标相关的头文件,这些文件中有一些宏定义会强迫某些具有特定的类型,以便与该内核的系统调用期望的类型相匹配。在导入头文件之后,当前端解析源代码时,还需要对int类型使用不同的大小,以匹配运行此代码的目标机器

因此,库头文件和C的类型都已经是依赖目标的,这使得要产生可以在之后被转换成其他目标的IR变得困难

如果仅考虑依赖目标的C标准库头文件,则给定编译单元的解析AST甚至在被转换为LLVM IR之前就已经是依赖目标的

此外前端生成IR代码时,需要使用与编译目标ABI相匹配的类型大小、调用惯例和特殊库调用等。

尽管如此,LLVM IR 还是非常灵活的,具有抽象应对不用的编译目标的能力

操作IR格式的基本工具示例

生成位码
clang sum.c -emit-llvm -c -o sum.bc
生成汇编
clang sum.c -emit-llvm -s -c -o sum.ll
汇编上述LLVM IR 汇编文本
llvm-as sum.ll -o sum.bc
从位码转换为IR汇编文本,反汇编程序:
llvm-dis sum.bc -o sum.ll
通过llvm提取工具llvm-extract ,可以提取IR函数、全局变量、删除IR模块中的全局变量
Ag:
llvm-extract -func=sum sum.bc -o sum-fn.bc
这条命令可以提取出sum函数
以上这些操作在这边博客中有写https://blog.csdn.net/m0_72827793/article/details/135894096

LLVM IR 语法介绍

在这里插入图片描述
整个LLVM文件的内容(无论是汇编码还是位码)被视为定义一个LLVM模块

模块是LLVM IR 顶层数据结构

每个模块包含一系列函数,每个函数由包含一系列指令的一系列基本块组成

模块还包含用于支持该模型的外围实体,如全局变量、目标数据布局、外部函数原型以及数据结构声明

LLVM局部变量与汇编语言中寄存器类似,可以用任何以%符号开头的名称命名

%7=add nsw i32 %5,%6
这一指令将执行两个局部变量%5和%6的加法,并将结果至于新的局部变量%7中

用户可以自由地给这些值命名,甚至可以只用数字就像上面一样

LLVM表达的基本属性:

  • 它使用的是静态单赋值(SSA)形式。请注意,该形式下每个变量都不会被重新赋值,每个变量只有唯一一条定义它的赋值语句。每次使用一个变量都可以立即回溯到负责其定义的唯一指令。使用SSA形式导致“使用定义链”(use-def链,即可以达到使用处的所有定义/赋值语句的集合)的生成变得非常简单,这个简单操作具有巨大的价值。使用定义链是经典优化(如传播和冗余表达式消除)的前提条件,如果LLVM没有使用SSA的形似,则需要运行单独的数据流分析来计算使用定义链
  • 代码被组成的三地址指令,数据处理指令有两个源操作数,并将结果放在不同的目标操作数中
  • 有无穷多的寄存器,注意LLVM局部变量可以使用以%符号开始的任意名称,例如%0、%1从零开始的数字,他对局部变量的最大数量没有限制

LLVM IR基本类型系统

类型系统具体的子类型
基本类型integer/floating point/label/void/metadata/x86mmx
派生类型array/function/pointer/structure/opaque structures/vector

LLVM IR指令集

指令类型具体的子类型
二元操作add/sub/mul/udiv/sdiv/urem/srem/fadd/fmul/fdiv/frem
按位二元操作shl/lshr/ashr/and/or/xor
终止指令ret/bt/switch/indirector/resume/unreachable/invoke
内存访问与地址操作alloc/load/store/atomic instructions/getelementptr
向量操作extractelement/insertelement/shufflevector
聚合操作extractvalue/insertvalue
转换操作trunc/zext/sext/fptrunc/fptoui/fptosi/uitofp/sitofp/ptrtoint/inttoptr/bicast
其他icmp/fcmp/select/phi/call/va_arg/landingpad

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1448181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis篇----第三篇

系列文章目录 文章目录 系列文章目录前言一、模糊查询 like 语句该怎么写?二、如何获取自动生成的(主)键值三、在 mapper 中如何传递多个参数?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,…

Golang中的fmt包:格式化输入输出的利器

Golang中的fmt包:格式化输入输出的利器 在软件开发的世界里,fmt包就像是一位忠实的伙伴,始终陪伴着开发人员。它简化了格式化输入输出的过程,让打印和扫描数据变得轻松自如。无论是向控制台输出简单的消息,还是处理复杂…

零基础学Python(10)— 序列通用操作

前言:Hello大家好,我是小哥谈。本节课就带大家认识下Python语言中常见的序列通用操作!~🌈 目录 🚀1.索引 🚀2.切片 🚀3.序列加法 🚀4.序列乘法 🚀5.检查某个元素是…

React18原理: 时间分片技术选择

渲染1w个节点的不同方式 1 &#xff09;案例1&#xff1a;一次渲染1w个节点 <div idroot><div><script type"text/javascript">function randomHexColor() {return "#" ("0000" (Math.random() * 0x1000000 << 0).toS…

在Docker中安装ubuntu镜像并安装Vim,将镜像命名

1、运行环境&#xff0c;腾讯云Ubuntu Server 22.04 LTS 64bit。默认用户名ubuntu&#xff0c;密码自己设置的啥写啥呗。 2、在docker中安装。 sudo docker pull ubuntu 3、查看docker中的镜像。 sudo docker images 4、 以交互模式进入容器。 sudo docker run -it ubuntu…

幻兽帕鲁服务器配置参数说明(Palworld官方汉化)

创建幻兽帕鲁服务器配置参数说明&#xff0c;Palworld服务器配置参数与解释&#xff0c;阿腾云atengyun.com分享&#xff1a; 自建幻兽帕鲁服务器教程&#xff1a; 阿里云教程 https://t.aliyun.com/U/bLynLC腾讯云教程 https://curl.qcloud.com/oRMoSucP 幻兽帕鲁服务器 幻…

Git中Idea操作git及Git Flow

目录 一、Idea中使用Git 1.idea配置Git和Gitee 2.实践操作 1.将本地项目推送到远程 2.从远程库克隆项目到本地 二、Git Flow 1.什么是Git Flow 2.工作流程 3.实践操作 一、Idea中使用Git 1.idea配置Git和Gitee 第一步&#xff1a;设置git.exe的安装路径 在设置中的…

预处理详解(上)

1. 预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的。 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSIC&…

Linux--目录结构

目录 一、Linux的目录结构二、常用的目录介绍 一、Linux的目录结构 Linux的目录结构是一个树型结构。 Windos 系统可以拥有多个盘符&#xff0c;如C盘&#xff0c;D盘,E盘。 Linux 木有盘符这个概念&#xff0c;只有一个根目录 /&#xff08;相当于文件夹&#xff09;&#xf…

掌握C语言文件操作:从入门到精通的完整指南!

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 什么是文件 文件其实是指一组相关数据的有序集合。这个数据集有一个名称&a…

MPLAB V8.92 printf

Compile error “A heap is required, but has not been specified” Set printf function #if 0 //for UART1 int fputc(int ch, FILE *f) { IFS1bits.U2TXIF 0; // if (runConfig.printOn 1) { // usart_data_transmit(USART0, (uint8_t)ch); U2TXREG ch; // while (RESE…

二分查找算法及其简单应用(C语言实现)

目录 二分查找算法介绍 二分查找算法的简单应用 二分查找算法介绍 二分查找算法&#xff0c;指在一组有序的数组内查找数值&#xff0c;查找的数值与查找范围内的中间数值进行比较&#xff0c;如果比中间数值小&#xff0c;则在原范围内的左侧范围内重复与该范围内的中间数值…

RK3568笔记十四:yolov8pose部署

若该文为原创文章&#xff0c;转载请注明原文出处。 本篇参考山水无移大佬文章&#xff0c;并成功部署了yolov8pose在RK3568板子上&#xff0c;这里记录下全过程。 在此特感谢所有分享的大佬&#xff0c;底部附大佬的链接。 一、环境 1、平台&#xff1a;rk3568 2、开发板: …

微信小程序 民宿预订租赁系统uniApp

通过山青水磨APP办理租房相关业务&#xff0c;线上解决预定、退订的业务&#xff0c;旅客在使用时更加灵活&#xff0c;实现了快速找房&#xff0c;在线沟通、便捷租赁等操作&#xff0c;除此以外&#xff0c;还能帮助旅客获取周边资讯、当地特色活动服务&#xff0c;提升旅客的…

C++,stl,函数对象,谓词,内建函数对象

目录 1.函数对象使用 2.谓词 1.一元谓词 2.二元谓词 3.内建函数对象 1.算术仿函数 2.关系仿函数 3.逻辑仿函数 1.函数对象使用 #include<bits/stdc.h> using namespace std;class add { public:int operator()(int v1,int v2){return v1 v2;} };class print { p…

origin技巧

origin技巧 1.去掉白边2.曲线平滑3.合并多层图例3.图例换方向 1.去掉白边 ctrlu 2.曲线平滑 3.合并多层图例 3.图例换方向 图例右键 “图例” 水平排布修改图例字&#xff1a;双击图例修改 https://blog.csdn.net/m0_47746156/article/details/121295151 https://blog.csdn.…

【网站项目】023实验室耗材管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

BUGKU-WEB GET

题目描述 没有提示&#xff0c;就一个get&#xff0c;启动场景看看&#xff1a; 解题思路 显然是PHP语言解读分析代码吧写出你的payload 相关工具 略 解题步骤 进入场景分析代码 $what$_GET[what]; echo $what; if($whatflag) echo flag{****};前两句&#xff1a;使用get…

《区块链公链数据分析简易速速上手小册》第3章:区块链数据结构(2024 最新版)

文章目录 3.1 区块和交易的结构3.1.1 基础知识3.1.2 重点案例&#xff1a;构建简单的区块链3.1.3 拓展案例 1&#xff1a;验证交易签名生成密钥对签名交易验证签名完整的交易签名与验证演示 3.1.4 拓展案例 2&#xff1a;监听和解析区块链事件代币合约示例&#xff08;Solidity…

HarmonyOS 通过getInspectorByKey获取指定元素高宽等属性

例如 这里 我们有这样一个组件 Entry Component struct Dom {build() {Column() {Row() {Circle({ width: 200, height: 200 }).fill(#20101010)}.id(ES)}.width(100%).height(100%)} }这里 我们就写了个很基本的组件结构 然后 我们写了个 Circle 组件 定义了宽高 然后 如果我…