不愧是长期搞compiler的,有很深的洞见。现在的compiler设计思路耦合行太强,灵活度不够。比如很多compiler设计时,是一个统一的优化思路,这个优化里塞了串行的pass。新的优化实现需求往往不能够很好的拓展(不知道新的需求应该放到compiler哪里做)。
- 灵活性
- 很少的builtin(内置,固化)的组件。大部分组件是用户可随意定制的。这样这套东西拿出去给用户用时,或者面临新的需求时,可以根据需求定制新的东东,无缝接入MLIR这套框架里。比如类型,操作,属性这些编译器IR经常用到的东西,用户都可自定义。框架提供了用户自定义需要的基础设施,我们可以拿来自定义拓展。
- 多层次设计
- 大佬们利用长期编译器开发经验,认为编译器将编程语言lower到底层硬件指令的过程,应该是一层层往下,每层按照当前需求抽象,由高层次抽象依次lower到底层次抽象。只有保证每个层次的抽象在下一层不需要时,或者说当前的整体抽象信息在当前层完全处理完毕后,lower到下一层会将当前信息打散成更小更细粒度的抽象,下一层抽象将优化和转化更细粒度的抽象。🤗
- 举一个极端的例子,如果抽象层次只有一层,从编程语言直接到硬件指令。这意味着我们直接在硬件指令上做转化优化,即使一个简单的function可能面临几百个指令,当function很复杂时,做全面的数据依赖分析和优化难度可想而知。❤️
- 多层次设计也会带来灵活性,而不是传统编译器固定化的pipeline。这些丰富经验的大佬们已经发现,如果我们把一些经常用到的优化能够以各种方式组合使用,将会给程序优化带来更多的好处。(无论是transformation还是优化pas,他们之间在后期时难免会需要互相交互)。
- 这种设计,就会要求框架的用户,需要及时合理抽象当前要解决的问题处于高层级还是低层级。如果是高层级,要保留合理的高层次语义,帮助你进行更合理更舒服的优化。(比如你要分析for loop,那么CFG的信息就不能丢,你慢慢反推当前分析应该放在哪里)。
- 统一的报错回溯机制 ❣️
- 编译器做复杂了,抽象的层级和使用的pass甚至多达上百个。需要有良好的定位手段,在当前的某个pass中能将报错信息正确报出来。
- 一个是基本组件的正确性,对类型、属性和操作等拥有一套verify机制,如果用户create一个新的op,类型属性等不对,会直接报错,报出错误信息越早越好,越能直接定位本质问题。
- 出了基本的debug问题回溯,更重要的是编程语言到当前优化的pass,能够准确定位当前优化的内容,是编程语言的哪个位置(location)。准确帮用户定位问题。
- 编译器做复杂了,抽象的层级和使用的pass甚至多达上百个。需要有良好的定位手段,在当前的某个pass中能将报错信息正确报出来。
Comments NOTHING