LLVM学习笔记(49)

news/2025/2/7 4:39:30/

4.1.3. 降级

在前面的章节里,我们展示了目标机器特定节点与目标机器无关节点共存的一个图。你可能会问,如果这是指令选择的一个输入,为什么在SelectionDAG类中已经有一些目标机器特定的节点?要理解这,我们首先在下图概括指令选择之前所有的步骤,从左上角的LLVM IR步骤开始:

首先,一个SelectionDAGBuilder实例访问每个函数并为每个基本块创建一个SelectionDAG对象。在这个过程中,一些特殊的IR指令,比如call与ret,需要将目标机器特定的习语——例如,如何传递实参,如何从一个函数返回——翻译为SelectionDAG节点。为解决这个问题,类TargetLowering中的算法被第一次使用。这个类是每个目标机器必须都实现的一个抽象接口,它拥有所有后端可以使用的大量的通用功能。

要实现这个抽象接口,每个目标机器声明一个名为<Target>TargetLowering的TargetLowering子类。每个目标机器还重载方法,以实现如何将一个特定的、目标机器无关的高级节点降级到更接近这个机器的形式。正如期望的,仅有少数节点必须以这个方式降级,而大多数其他节点在指令选择时被匹配、替换。例如,在sum.bc的SelectionDAG中,X86TargetLowering::LowerReturn()方法用于降级IR ret指令。在这期间,它生成了X86ISD::RET_FLAG节点,它将函数结果拷贝到EAX——一个处理函数返回值的目标机器特定方式。

4.1.4. DAG合并与合法化

来自SelectionDAGBuilder的SelectionDAG输出还不能进行指令选择,必须通过额外的转换——显示在上图。在指令选择前应用的遍序列如下:

  • 匹配一组节点,在有利时使用更简单的构造来替换它们,DAG合并遍优化SelectionDAG的结构。例如,(add (Register X), (constant 0))可以折叠为(Register X)。类似的,目标机器的合并方法可以识别节点模式,决定是否合并以及折叠它们,提升目标机器指令选择的质量。方法setTargetDAGCombine标记目标机器希望合并的节点。例如,MIPS后端尝试合并加法——参考lib/Target/Mips/MipsISelLowering.cpp的setTargetDAGCombine(ISD::ADD)与performADDCombine()。

(注:在每个合法化阶段后运行DAG合并以尽量减少SelectionDAG冗余。另外,DAG合并知道运行到遍链(pass chain)的何处(例如,在合法化或向量合法化之后),并且可以更精确地使用这个信息。)

  • 类型合法化遍确保指令选择仅需要处理合法的类型。合法类型是目标机器原生支持的类型。例如,在仅支持i32类型的目标机器上带有i64操作数的加法是非法的。在这个情形里,类型合法器执行整数扩展,将一个i64操作数分解为两个i32操作数,同时生成处理它们的合适的代码。目标机器定义每个类型与哪些寄存器类相关,明确声明支持的类型。因此,必须相应地检测与处理非法类型:标量类型可以被提升、扩展或者弱化,而向量类型可以被分裂、标量化或者加宽。同样,目标机器也可以定制类型合法化的方法。类型合法器运行两次,在第一次DAG合并后,以及向量合法化后。
  • 存在后端直接支持一个向量类型的情形,这意味着对此有一个寄存器类,但在一个给定向量类型上的一个特定操作不一定。例如,有SSE2的X86支持v4i32向量类型。不过,在ISD::OR上没有支持v4i32类型的X86指令,仅支持v2i64。因此,向量合法化器使用指令的合法类型提升或扩展来处理这些情形。在上述ISD::OR情形里,操作被提升为使用v2i64类型。

(注:对某些类型,扩展将消除向量类型,使用标量类型。这会导致目标机器不支持的标量类型。不过,后续的类型合法化器将清除之。)

  • DAG合法化器具有与向量合法化器相同的任务,但处理任何带有不支持类型(标量或向量)的遗留操作。它支持相同的操作:提升,扩展,处理定制节点。例如,x86节点不支持以下三个中的任意一个:i8类型有符号整数到浮点数的操作(ISD::SINT_TO_FP),要求合法化器提升该操作;i32操作数上的有符号除法,要求一个扩展,发布一个库调用来处理该除法;f32操作数上浮点绝对值(ISD::FABS),使用一个定制句柄来生成具有相同效果的代码。X86以下列方式来发布这样的行为(参考lib/Target/X86/X86ISelLowering.cpp):

setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote);

setOperationAction(ISD::SDIV, MVT::i32, Expand);

setOperationAction(ISD::FABS, MVT::f32, Custom);


http://www.ppmy.cn/news/1173217.html

相关文章

2. 计算WPL

题目 Huffman编码是通信系统中常用的一种不等长编码&#xff0c;它的特点是&#xff1a;能够使编码之后的电文长度最短。 更多关于Huffman编码的内容参考教材第十章。 输入&#xff1a; 第一行为要编码的符号数量n 第二行&#xff5e;第n1行为每个符号出现的频率 输…

游戏盾如何有效防护DDoS

从进入计算机时代以来&#xff0c;DDoS攻击一直是网络世界中的一大威胁&#xff0c;让无数服务陷入瘫痪。这种攻击的原理非常简单&#xff1a;攻击者使用大量的僵尸主机或蠕虫病毒&#xff0c;向目标服务器发送海量请求&#xff0c;迅速耗尽服务器的资源&#xff0c;使其无法继…

css 雷达扫描图

html 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>css 雷达扫描</title><style>* {margin: 0;padding: 0;}body {background: #000000;height: 100vh;display: flex;align-items…

计算机考研自命题(6)

1、C语言–奇数求和 1、使用函数求奇数和&#xff1a;输入一批正整数&#xff08;以零或负数为结束标志&#xff09;&#xff0c;求其中的奇数和。要求定义和调用函数 odd(n) 判断数的奇偶 性&#xff0c;当 n 为偶数时返回 0 &#xff0c;否则返回 1 。试编写相应程序。 /* 解…

解决github ping不通的问题(1024程序员节快乐!

1024程序员节快乐&#xff01;&#xff08;随便粘贴一个文档&#xff0c;参加活动 解决github ping不通的问题 域名解析&#xff08;域名->IP&#xff09;&#xff1a;https://www.ipaddress.com/ Ubuntu平台 github经常ping不通或者访问缓慢&#xff0c;方法是更改host…

JS——垃圾回收的原理

引言 JavaScript是一种高级的、解释型的编程语言&#xff0c;广泛应用于网页开发和移动应用开发中。在JavaScript中&#xff0c;内存管理是一个重要的话题&#xff0c;而垃圾回收就是内存管理的一部分。本文将介绍JavaScript垃圾回收的原理&#xff0c;并提供一些示例代码来帮助…

国际物流报关流程

国际物流报关流程如下&#xff1a; 准备资料&#xff1a;根据国家和地区的要求&#xff0c;准备相关的报关资料&#xff0c;包括进出口货物清单、运输合同、发票、装箱单等文件。 海关申报&#xff1a;将准备好的报关资料递交给海关申报&#xff0c;海关会根据报关单上的信息对…

ant-design-vue 3 a-table保留选中状态

业务需求需要保留选中状态 <a-table class"satistic-table" :row-selection"{ selectedRowKeys: selectedRowKeys, onSelect:onSelect,onSelectAll:onSelectAll }" :row-key"(row)>{ return row.customerId}" :columns"columns"…