编译器技术
文章平均质量分 87
介绍编译器实现和优化
Victor Fung
主要涉及分布式中间件、分布式存储、数据库、linux内核、编译器。。。
展开
-
llvm中端之mem2reg源码分析
mem2reg源码依赖了一些封装库,包括分析器、util、mem2reg自身的封装。DominatorTree:由DominatorTreeAnalysis生成,用于获取函数的支配树,建立函数基本块之间的支配关系;AssumptionCache:由AssumptionAnalysis生成,用于注册ICmpInst指令和建立影响该指令结果的映射关系。对后续的指令预判有用;ValueTracking:依赖AssumptionCache,对Value跟踪分析并作一些结果判断;原创 2024-09-12 16:19:59 · 829 阅读 · 0 评论 -
llvm后端之局部变量
llvm后端对局部变量(即alloc节点)的访问,首先,将对alloc节点转为FrameIndex,所有对alloc的load和store均用FrameIndex取代;对于RISCV而言,就是RISCV::ADJCALLSTACKDOWN和RISCV::ADJCALLSTACKUP两条指令,前者是增长栈、后者为缩小栈。局部变量包括固定大小的变量,不固定大小的变量(例如不定长的数组)。由于FrameIndex操作数是一个抽象的操作数,对它的替换是在PEI这个pass中进行的。原创 2024-09-10 16:14:02 · 1139 阅读 · 0 评论 -
llvm后端之函数栈帧
细心的朋友可能会发现之前的代码逻辑缺失了寄存器的保留与恢复操作。这部分指令是在PEI这个pass中完成的,该pass是在TargetPassConfig::addMachinePasses中完成添加的。TargetInstrInfo类的storeRegToStackSlot和loadRegFromStackSlot方法用于寄存器压栈和出栈指令的生成。注:由于先生成的保留寄存器的压栈与出栈指令,所以目标在实现emitPrologue和emitEpilogue方法时,需要注指令的插入位置;原创 2024-09-09 18:27:23 · 1325 阅读 · 0 评论 -
llvm后端之tblgen寄存器信息
其生成规则是按枚举出现顺序将sub_8bit、sub_8bit_hi、sub_8bit_hi_phony、sub_16bit_hi、sub_32bit、sub_xmm、sub_ymm被设置为0x01、0x02、0x04、0x08、0x10、0x20、0x40。注:并不是有多少个寄存器就有多少个寄存器单元,例如两个8位BL和BH组成了16位BX、两个16位BX和HBX组成了32位EBX、EBX扩展成64位RBX,有6个寄存器却只有X86::BL、X86::BH、X86::HBX三个寄存器单元。原创 2024-08-30 12:25:34 · 872 阅读 · 0 评论 -
llvm后端之SelectionDag源码分析
例如AMDGPU中的Load节点,对于AMDGPUAS::CONSTANT_ADDRESS_32BIT地址空间的数据load是具备恒定的,因为该地址空间的数据运行后不会更改;DAG合法化是最后一个合法化阶段,它在SelectionDAG::Legalize中完成,它会不断通过SelectionDAGLegalize::LegalizeOp对每个节点合法化,直到所有节点都不再需要合法化结束。注:一般地,在参数寄存器还可以分配的时候,会优先使用CCState::AllocateReg分配参数寄存器;原创 2024-01-08 12:47:20 · 1284 阅读 · 0 评论 -
llvm后端之SDNode设计
DAG节点的类型(也就是操作类型,对应于指令类型)是定义在llvm::ISD::NodeType枚举类型中;EVT是对MVT的封装,此外还提供了对MVT类型的扩展。当表示MVT之外的类型时,其V.SimpleTy为INVALID_SIMPLE_VALUE_TYPE。蓝色表示指令序列化时两个节点中间可以插入其他节点对应的指令,而红色节点表示两个节点生成的指令中间不能插入其他节点的指令。llvm后端DAG的类型系统分为三个层级,从外到内为:EVT、MVT、SimpleValueType。原创 2023-12-20 22:28:45 · 1586 阅读 · 0 评论 -
数据流分析之推导要点
数据流分析在编译器中作用显著,它能辅助实现各种优化过程。数据流分析有两种常见的推导方法:一种是use-def推导、另一种是gen-kill模式。原创 2023-03-31 19:54:10 · 300 阅读 · 0 评论 -
数据流分析之定值分析
若一条指令对寄存器R生成了定值,其他指令对R的生成定值称为对该条指令关于R的杀死定值。指令n的杀死定值集合表示为kill[n],n为指令序号、元素为寄存器+赋值指令序号的二元组;指令n的生成定值集合表示为gen[n],n为指令序号、元素为寄存器+赋值指令序号的二元组(一般有0个或1个元素);指每条指令执行后的相关变量的可能值。指令n的出口定值集合表示为out[n],n为指令序号、元素为寄存器+赋值指令序号的二元组;指令n的入口定值集合表示为in[n],n为指令序号、元素为寄存器+赋值指令序号的二元组;原创 2023-02-12 20:44:59 · 667 阅读 · 0 评论 -
控制流分析之构建支配树
在编译器中,支配树作用显著。例如,它可以辅助我们识别函数中的循环等功能。本文将将讨论如何从一个图构建支配树?原创 2023-01-05 20:39:23 · 851 阅读 · 0 评论 -
数据流分析之活跃分析
注:这种优化,只求出了跨基本块的入口活跃列表和出口活跃列表的变量;我们对一个函数的每个结点生成入口活跃列表和出口活跃列表是比较耗时的,但是,很多时候我们只需要求出每个基本块的入口活跃列表和出口活跃列表。指令n的定值集合表示为def[n], n为指令序号、元素为寄存器(一般有0个或1个元素);指令n的引用集合表示为use[n], n为指令序号、元素为寄存器;指令n的出口活跃集合表示为out[n],n为指令序号、元素为寄存器;指令n的入口活跃集合表示为in[n],n为指令序号、元素为寄存器;原创 2022-12-14 22:25:52 · 675 阅读 · 0 评论 -
llvm中端之IR设计
llvm IR是llvm对代码的一种中间表示。它来源AST(抽象语法树),是llvm代码优化的主要对象。IR的很多组成元素都是以Value为基类。llvm并没有采用C++的RTTI,而是自实现了一套多态系统,其实现核心就在Class Value::Subclass*系列字段。每个模块代表链接前的一个编译单元,模块一般包括:此外,还包括:IRBuilder是指令和常量的构建器,它是一个模板类,它有两个模板参数:Instruction表示一个IR指令,llvm采用静态单赋值(Static Single Ass原创 2022-12-05 22:18:05 · 1222 阅读 · 0 评论