SelectionDAGISel算法经过了LLVM IR的DAG化、合法化、匹配表查找等复杂过程,会耗费大量时间。为了提高指令选择的速度,LLVM实现了一个快速指令选择算法(FastISel),这一算法只适用于部分后端的O0阶段,是以牺牲指令选择的质量来换取编译时间。

阅读全文 »

SelectionDAGIsel是一种局部指令选择算法,它以函数中的基本块为粒度,针对基本块内的LLVM IR生成最优的MIR指令,不考虑跨基本块间的指令处理。但是基本块中有一个特殊的指令φ函数需要特别处理,一方面是因为φ函数在后端中并没有一条指令与之对应,另一方面则是因为φ函数表达的是基本块之间的汇聚关系,在处理当前基本块时,编译器并不知道控制流汇聚的情况。所以SelectionDAGIsel实现时将指令分成2类处理。

阅读全文 »

在编译器中,将高级语言映射到目标架构指令的过程称为指令选择。无论是简单的编译器(直接将高级语言转为目标架构指令),还是优化能力较强的编译器(通过IR进行优化后再转为目标架构指令)都会有这样一个阶段。这是因为高级语言(或者中间表示语言)与目标架构指令之间存在语义差异,需要通过一定的规则才能将高级语言指令转为对应的目标架构指令。规则有可能很简单、也可能很复杂。

阅读全文 »

代码生成是编译器后端的统称,在编译器的实现中占据着非常重要的地位,也是非常复杂的模块。以LLVM 15为例,整个项目代码行数超过1000万^1,其中clang相关代码超过400万行,LLVM中端优化以及后端代码生成相关代码也已经有近400万行代码。其中代码生成代码量约为200万行,包含了架构无关的代码和架构相关的代码。其中架构无关代码约为50万行,架构相关约为150万行。架构无关的代码主要包了含指令选择、指令调度、寄存器分配和机器码生成;架构相关代码是LLVM所有支持的后端代码总和,目前LLVM已经支持超过20种后端,有些后端的实现非常复杂,如X86后端代码量超过了20万行,而有些又非常简单,如BPF后端代码量只有1万行左右。

阅读全文 »

ADT(Abstract Data Type)是LLVM定义的一套高级数据类型,是LLVM项目的基础组件。ADT定义了“基础类型”、“容器”、“算法”、“迭代器”,具体来说:

阅读全文 »

方言概述

MLIR社区提供的方言超过40余个方言,理解全部的方言已经非常困难。下面是有一个部分重要方言的降级流程图。

阅读全文 »

MLIR学习系列1-MLIR概述

MLIR自2019年发布后就成为编译界的新贵,不仅仅AI编译器、领域编译器、新型硬件公司和新型语言都在尝试使用MLIR,其中以AI编译器取得的成果最为显著。本文简单介绍MLIR的基础知识、MLIR构建和MLIR相关工具的使用。

阅读全文 »

背景

clang 是一个类 C 语言的编译器前端和基础设施工具。开发 clang 的目的是为了更好的编译报错提示信息、更优的 IDE 亲和性和更友好的 License。

阅读全文 »
0%