如何防止通用子表达消除(CSE)与GHC [英] How to prevent common sub-expression elimination (CSE) with GHC

查看:230
本文介绍了如何防止通用子表达消除(CSE)与GHC的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出程序:

import Debug.Trace
main = print $ trace "hit" 1 + trace "hit" 1



如果我使用 ghc -O (7.0.1或更高)我得到的输出:

If I compile with ghc -O (7.0.1 or higher) I get the output:

hit
2

ie GHC使用公共子表达式消除(CSE)来重写我的程序:

i.e. GHC has used common sub-expression elimination (CSE) to rewrite my program as:

main = print $ let x = trace "hit" 1 in x + x


$ b 然后我看到命中出现了两次。

If I compile with -fno-cse then I see hit appearing twice.

可以通过修改该程序?是否有任何子表达式 e ,我可以保证 e + e 不会被CSE'd?我知道 lazy ,但找不到任何旨在禁止CSE的设计。

Is it possible to avoid CSE by modifying the program? Is there any sub-expression e for which I can guarantee e + e will not be CSE'd? I know about lazy, but can't find anything designed to inhibit CSE.

这个问题的背景是cmdargs 库,其中CSE断开库(由于库中的杂质)。一个解决方案是要求库的用户指定 -fno-cse ,但我更喜欢修改库。

The background of this question is the cmdargs library, where CSE breaks the library (due to impurity in the library). One solution is to ask users of the library to specify -fno-cse, but I'd prefer to modify the library.

推荐答案

读取GHC的源代码,唯一不符合CSE的表达式是那些未能通过 exprIsBig 测试。目前,这意味着 Expr 注意案例,以及包含这些的表达式。

Reading the source code to GHC, the only expressions that aren't eligible for CSE are those which fail the exprIsBig test. Currently that means the Expr values Note, Let and Case, and expressions which contain those.

因此,上述问题的答案是:

Therefore, an answer to the above question would be:

unit = reverse "" `seq` ()

main = print $ trace "hit" (case unit of () -> 1) +
               trace "hit" (case unit of () -> 1)

value 单位,它解析为(),但GHC无法确定的值(通过使用递归函数GHC无法优化 - reverse 只是一个简单的手)。这意味着GHC不能CSE trace 函数,它的2个参数,我们得到命中打印两次。这适用于 -O2 下的GHC 6.12.4和7.0.3。

Here we create a value unit which resolves to (), but which GHC can't determine the value for (by using a recursive function GHC can't optimise away - reverse is just a simple one to hand). This means GHC can't CSE the trace function and it's 2 arguments, and we get hit printed twice. This works with both GHC 6.12.4 and 7.0.3 at -O2.

这篇关于如何防止通用子表达消除(CSE)与GHC的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆