指令选择小结

本章主要介绍了LLVM中实现的3种指令选择算法的基本原理和实现细节,从上述章节的描述中,我们可以大致看出3种算法是具有一些相似性的,同时也有许多方面是不同的。因此,本节将3种算法放到了一起,通过简单的比较,定性地给出3个算法的差异情况和使用场景。

首先是相同点,3个算法都是基于规则(指令模式)的指令选择算法。因此,适配一个新架构时,工程师需要熟悉新架构的特性和指令集,然后根据这些信息,编写LLVM IR到新架构指令的映射关系(规则)。
然后是不同点,由于算法本身的复杂度和应用场景的多样性,可以比较的维度是比较多的,我们选取了实现和使用编译器比较常用的8个维度进行简单比较,如表7-2所示。

中间表示 匹配范围 覆盖方式 执行方式 编译时间 生成代码质量 开发周期 可维护性
FastISel 单指令 单指令覆盖 手动匹配 一般
SelectionDAGISel DAGIR 基本块 树覆盖[ 除了多输出指令可以构成 DAG 形式的覆盖,LLVM 中实现的大部分指令都只能构建成树模式的覆盖形式,因此在本章中将 SelectionDAGISel 和 GlobalISel 的覆盖方式都称为树覆盖形式。] 自动匹配和手动匹配 极好 一般
GlobalISel GMIR 函数 树覆盖 自动匹配和手动匹配 极长

表7-2 LLVM中实现的三种指令选择算法比较

根据笔者个人经验,在编译时间有高要求的场景,优先使用FastISel;对性能和开发周期有要求的场景,优先使用SelectionDAGISel算法;从发展的角度看,使用GlobalISel算法是可能同时具有FastISel和SelectionDAGISel的优点。