
编译原理及技术
文章平均质量分 92
记录做编译器前端、IR及后端时用到的一些技术,主要参考书籍是《编译器设计》第2版
yelvens
我很懒,什么都没留下…
展开
-
LuaJIT:Garbage Collector Algorithms
本篇文章是对MakePall发表wili内容《》的翻译和扩展,因为原文是对LuaJIT2.xGC重要功能的简介和对LuaJIT3.0newGC的工作计划,所以它并不是系统性介绍GC的文章。希望以后能有精力系统性的对LuaJIT2.xGC做个总结。到目前(2025-1-17)为止,LuaJIT3.0尚未发布。看Make列的3.0plan,其中优化了很多功能,非常值得期待。但他也说了,3.0有可能永远不会发布,这将是非常遗憾的一件事情。原创 2025-01-17 15:56:31 · 959 阅读 · 0 评论 -
基于Trace的类型特化动态语言JIT编译
动态语⾔JavaScript、Python 和 Ruby 等语⾔⾮常流⾏,因为它们表达能⼒强、⾮专业⼈⼠也能轻松使⽤,并且部署起来就像分发源⽂件⼀样简单。它们既可⽤于⼩型脚本,也可⽤于复杂的应⽤程序。例如,JavaScript 是客户端 Web 编程的事实标准并⽤于基于浏览器的⽣产⼒应⽤程序(例如 Google Mail、Google Docs 和 Zimbra Collaboration Suite)的应⽤程序逻辑。原创 2024-07-18 18:28:31 · 1308 阅读 · 0 评论 -
编译器设计(十四)——寄存器分配
在程序中的每个位置上,寄存器分配器会确定哪些值将位于寄存器中,哪个寄存器将容纳哪些值。如果分配器无法将某个值在其整个生命周期均保持在寄存器中,那么在其生命周期的部分或全部时间,该值必须存储到内存中。分配器可能会将一个值逐出到内存,因为代码包含的活跃值数据超出了目标机寄存器集合的容量。另外,在一个值各次使用之间的间歇,它可能被保存到内存中,因为分配器无法证明它能够安全地驻留在寄存器里。原创 2023-05-23 17:25:16 · 4370 阅读 · 0 评论 -
编译器设计(十三)——指令调度
对程序块或过程中的操作进行排序以有效利用处理器资源的任务称为指令调度调度器的输入是由目标机汇编语言操作组成的一个部分有序的列表,输出是同一列表的一个有序版本。一组指令的执行时间严重依赖于其执行顺序,指令调度会重排一个过程中的各个指令,使每个周期执行尽可能多的指令,以改进其运行时间。对于整数加法或减法是1个周期;对于整数乘法或浮点加减法是3个周期;对于浮点乘法是5个周期;对于浮点除法是12-18个周期;对于整数除法是20-40周期。原创 2022-12-29 11:07:26 · 3434 阅读 · 0 评论 -
编译器设计(十二)——指令选择
指令选择(instruction selection),将编译器的IR映射到目标ISA,这实际上是一个模式匹配问题,其复杂性源自常见的ISA为(即使是简单的)操作提供的大量备选实现方案。在其最简单的形式下,编译器可以为每个IR操作提供一个目标ISA操作序列。由此形成的指令选择器提供了一个类似模板的展开,最终会生成正确的代码。遗憾的是,这种代码对目标机资源的利用比较糟糕。更好的方法会对每个IR操作考虑许多可能的候选代码序列,并从中选择预期代价最低的代码序列。本章阐述指令选择的两种方法:一种基于树模式匹配。原创 2022-12-09 16:19:44 · 2428 阅读 · 1 评论 -
编译器设计(十一)——标量优化
所谓的标量优化,指的是单个控制线程下代码的优化。大多数优化器都被构建为一系列处理趟(pass),如下图所示。每趟以IR形式的代码作为其输入,以重写后的IR代码版本作出其输出。这种结构将实现划分为若干小片段,从而避免了大型单块程序引起的部分复杂性。这允许独立地构建并测试各个处理趟,简化了开发、测试和维护。这建立的方法颇为自然,使编译器能够提供不同的优化级别,每个级别规定了一组需要运行的处理趟。趟结构使编译器编写者能够多次运行某些趟(如果需要的话)。原创 2022-11-24 11:20:13 · 1574 阅读 · 0 评论 -
编译器设计(十)——数据流分析
数据流分析是用于编译时程序分析的经典技术,它使编译器能够推断程序中的值在运行时的流动。在简单的情况下,静态分析可以生成精确的结果,此时编译器能够确切地知道在代码执行时到底将发生什么。如果编译器能够推导出精确信息,那么它可以将表达式或函数的运行时求值操作替换为对(编译时预计算)结果的立即数加载操作。另一方面,如果代码从任何外部来源读取值、涉及(即使很少的)控制流,或者遇到具有歧义的内存引用(指针、数组引用或引用调用参数),那么静态分析会变得困难得多,而分析的结果也会变得不那么精确。原创 2022-10-25 14:12:34 · 4976 阅读 · 0 评论 -
编译器设计(九)——优化简介
代码优化的目标是在编译时发现有关程序运行时行为的信息,并利用该信息来改进编译器生成的代码。改进可能有许多种形式。优化最常见的目标是提高编译后代码的运行速度。但对于某些应用程序来说,编译后代码的长度要比其执行速度更重要。例如,考虑某个将烧录到只读存储器的应用程序,其代码长度会影响整个系统的成本。优化的其他目标包括降低执行的能耗、提高代码对实时事件的响应、降低对内存的总访问量、优化寄存器的使用等。有两个关于优化的比较经典的例子,后面补上。原创 2022-09-17 15:09:29 · 7013 阅读 · 0 评论 -
编译器设计(八)——代码形式
如果允许用户获得结构数组中数组元素的地址,那么编译骈在内存中对数据进行布局时,结构数组的布局将呈现为多个布局相同、在内存中连续出现的结构实例。如果编译器将一个静态值保持在寄存器中,那么在过程中第一次使用该值之前,必须将其从内存加载到寄存器,在离开过程之前(退出该过程时,或在过程内部调用其他过程时),必须将其写回到内存。,命名值a,未命名值b + 1),编译器都必须确定在何处存储这些值:是在内存中还是在寄存器中,不管是哪种情况,都要给出具体的位置。、最后一维的下界、B中一个元素的长度,来计算一个偏移量。原创 2022-09-09 09:19:37 · 1177 阅读 · 0 评论 -
编译器设计(七)——过程抽象
文章目录一、过程调用二、运行时结构2.1 支持类Algol语言的运行时结构2.2 支持面向对象语言的运行时结构三、过程之间值的传递3.1 传递参数3.2 返回值3.3 确定可寻地址四、标准化链接五、高级主题5.1 堆的显示管理5.2 隐式释放一、过程调用在编译器为调用和返回生成代码时,代码中必须保留足够的信息,确保调用和返回能够正确地运转。如下图所示,在Foe调用Fum时,编译器针对调用生成的代码必须记录Foe中的地址,Fum执行完毕后将控 制返回到该地址。Fum可能因为运行时错误、无限循环或其调用的另原创 2022-04-15 23:15:19 · 903 阅读 · 0 评论 -
编译器设计(六)——中间代码表示
文章目录一、IR分类及其性质二、图IR2.1 与语法相关的树1) 语法分析树2) 抽象语法树3) 有向非循环图4) 抽象层次(底层AST)2.2 图三、线性IR一、IR分类及其性质编译器通常组织为一连串的处理趟,随着编译器不断推导有关被编译代码的知识,它必须将这些信息从一趟传递到另一趟,因而,对于推导出有关程序的全部事实,编译器需要一种表示,我们将这种表示称为中间表示(intermediate representation),简称为IR。如果源语言语法结构较为简单,编译器可能会用唯一的IR,如果源语言语原创 2022-02-22 21:22:48 · 6662 阅读 · 0 评论 -
编译器设计(二)——上下文无关文法及推导
文章目录一、语法和语义二、文法一、语法和语义什么是语法?程序本质上是一定字符集上的字符串,这些字符串描述了一定数据的处理过程,语法规则和词法规则定义了程序的形式结构。所以呢,语法就是一组规则,用它可以形成和产生一个合式(well-formed)的程序。词法规则:单词符号的形成规则单词符号是语言中具有独立意义的最基本结构,一般包括:常数、标识符、基本字、算符、界符等。描述工具:有限自动机语法规则:语法单位的形成规则语法单位通常包括:表达式、语句、分程序、过程、函数、程序等。描述工具:上原创 2021-01-13 13:20:25 · 8194 阅读 · 4 评论 -
简单介绍一个编译器的结构(下)
经过中间代码生成过程产生的中间代码是正确的,但未必就是更“好”的,所以我们要对中间代码做一些优化,使其可以更“好”。这个“好”是个泛指,比如我们希望它生成的汇编代码量可以更小(GCC加-Os)、或者生成的汇编代码执行时的内存使用量更小、或者生成的汇编代码执行速度可以更快(GCC加-O[1/2/3])。一般而言,最期望的“好”还是执行速度可以更快,我们接下来的介绍也是以这部分内容展开。原创 2023-06-15 17:22:04 · 978 阅读 · 2 评论 -
简单介绍一个编译器的结构(上)
一个编译器的结构一、语言处理器二、编译器的结构三、词法分析语法分析语义分析中间代码生成代码优化代码生成符号表管理将多个步骤组合成趟(pass)编译器构造工具我打算做一个编译原理及技术的专栏,这是整个专栏的第一章,从整体上介绍了一下编译器及编译器相关的一些东西,不会展开细说,具体内容后面再到具体章节去介绍,希望我能坚持下去!不是从事编译器工作,或者对编译原理掌握的不是很彻底的同学,可能会对某些内容比较模糊,也很难坚持从头看下去,但是如果能坚持看完,多少对你都会有些帮助,毕竟我花大量时间总结的依附是经典教原创 2020-11-30 00:15:44 · 7099 阅读 · 2 评论 -
动态语言和静态语言的区别
本文转自:https://www.cnblogs.com/zy1987/p/3784753.html?utm_source=tuicool 编译型语言和解释型语言1、编译型语言需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)、链接(linker)这两个步骤。编...转载 2020-07-15 21:50:23 · 652 阅读 · 0 评论