【发布时间】:2015-01-19 22:48:55
【问题描述】:
像MLton 这样的全程序编译器创建优化的二进制文件的部分原因是它们能够使用二进制文件的全部源代码来执行部分评估:积极内联常量并评估它们直到卡住——所有这些都在编译期间!
Gabriel Gonzalez's Morte 已在 Haskell 空间中对这一点进行了一些探索。
现在我的理解是 Haskell 并没有做太多这方面的事情——如果有的话。我理解的引用原因是分开编译是对立的。禁止跨源文件边界进行部分评估是有道理的,但似乎文件内部分评估仍然是一种选择。
据我所知,仍然没有执行文件内部分评估。
我的问题是:这是真的吗?如果是这样,执行文件内部分评估的权衡是什么?如果不是,那么可以通过将更多功能放入同一个文件来提高编译性能的示例文件是什么?
(编辑:为了澄清上述内容,我知道有很多问题是关于什么是最好的减排措施——许多是无法确定的!我想知道在“工业实力”中做出的权衡具有单独编译的编译器,如果有任何有趣的事情要讨论,则处于高于选择正确方程理论的水平。编译速度或文件膨胀等问题更接近我感兴趣的范围。同一空间中的另一个问题可能是:“为什么 MLton 不能通过单独编译每个模块、暴露 API,然后将它们全部链接在一起来获得单独的编译?”)
【问题讨论】:
-
部分评估的问题是它会遇到停止问题。您何时决定停止对表达式进行部分计算?例如,采用表达式
enumFrom 0 :: [Integer]。如果您尝试对它进行部分评估,那么您的编译器将永远不会终止,这是一件非常糟糕的事情。一种解决方案是不以弱头范式评估表达式。然而,这意味着某些表达式将不可优化。重写是一种快速而肮脏的方式来摆脱对中间数据结构的砍伐。加上它终止。问题是正确性。 -
Glasgow Haskell 编译器确实执行内联,但并不积极:stackoverflow.com/q/26996110/783743。似乎很多人都对激进的内联感兴趣:stackoverflow.com/questions/26827663/…。我最后一年的学士学位项目是关于函数式编程语言的重写和部分评估。
-
我应该添加到问题中更清楚。我知道这里的许多等式是不可判定的(在 Haskell 中它可能比 ML 更糟),但 MLton 是一个(部分)存在证明,证明存在一些既有益又能终止的归约等式。在不深入研究要执行的正确缩减的情况下,我想了解在具有单独编译的“工业实力”编译器中实现它们的原因。
-
麻烦不一定非要不可判定。极端情况下,任何“计算这个数学表达式并打印它”类型的程序最终都会变成
main = print 42。当然,这对于大型晶格计算也是不可取的。但我猜大多数程序都不是这种类型,我想它会比没有更有用,特别是如果一个标志可以关闭它。 -
@jamshidh 那是考虑到程序不接受任何外部输入。根据定义,部分评估仅在编译时评估程序中的静态已知表达式。
标签: haskell compiler-construction ghc compiler-optimization