问题标签 [constantfolding]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
78 浏览

c++ - 修改 const 值的“未定义”机制

我已经读过,在某些 C 标准(可能是 99?)中未定义它在修改 const 时会发生什么。但是一个学生给了我一些代码,我对其进行了修改。

我看不出常量变量的地址有什么特别之处a。我验证了&a并且b是相同的,所以编译器并没有巧妙地指向其他位置。然而,当我分配时*bconst值不会改变。

我没有运行优化。当我使用-g标志进行编译以调试并单步执行代码时,我得到了我期望的结果(变量的内存位置发生了a变化)。然而,下面显示的代码并未反映a.

即使在调试模式下,临时工现在也被放置在寄存器中,没有优化?

0 投票
2 回答
754 浏览

c# - 减去 uint 和 int 以及常量折叠

基于这个有趣的问题:添加 int 和 uint并玩弄Nicholas Carey 的回答中提到的常量折叠,我偶然发现了编译器看似不一致的行为:

考虑以下代码片段:

这里编译器正确解析klong. 正如前面提到的问题的答案中所解释的那样,这种特殊行为在规范中得到了很好的定义。

令我惊讶的是,在处理文字常量或一般常量时,行为会发生变化。阅读 Nicholas Carey 的回答,我意识到行为可能不一致,所以我检查并确定:

k在这种情况下被解决为Uint32.

处理常量时行为不同是否有原因,或者这是编译器中的一个小但不幸的“错误”(缺乏更好的术语)?

0 投票
0 回答
149 浏览

f# - F#什么时候做常量折叠?

我刚刚写了一些内联的数学实用函数,并且在测试时注意到

完全折叠printAn (18, 0, 0),而开始时(3.0f, 0.0f, 0.0f, 3.0f)仅插入原始值0.0f3.0f常量值,而不评估任何浮点运算符,并且Tuple实例化了一些 s(但几乎没有调试模式下那么多)。

(我使用针对 4.5 框架的 Visual Studio 2013 Update 4,使用默认Release配置。取消定义TRACE常量似乎没有什么区别,也没有open Unchecked。)


不太关心性能影响,因为如果它成为一个问题,应该很容易通过 IL 编织折叠表达式,但我仍然对编译器可以常量折叠的确切内容感兴趣。

0 投票
2 回答
722 浏览

python - 带标签的 Python 常量折叠

我想做一些类似于使用 Python 进行常量折叠的事情。

Python 有一个方便的内置函数 eval(),因此可以通过应用 eval() 轻松折叠只有常量的方程。

例子:

但是,我想实现的常量折叠应该处理非常量标签。

例子:

如果常量部分由标签分隔,例如 (s = '2 + _tbl + 4'),它仍应生成 '_tbl + 6' (或 '6 + _tbl)。

几年前,我使用“C”编写了一个常量折叠例程。这不是一个小例程,因为我需要构建一棵树并评估运算符的优先级。

由于 Python 语言比“C”强大得多,所以在使用 Python 做同样的事情之前,我想寻求其他人的智慧。

非常感谢您对这一挑战的见解。

0 投票
1 回答
313 浏览

c++ - 具有内存屏障的恒定折叠/传播优化

我已经阅读了一段时间,以便更好地了解使用现代(多核)CPU 进行多线程编程时发生的情况。但是,当我阅读本文时,我注意到“显式编译器障碍”部分中的以下代码,它没有将 volatile 用于IsPublished全局。

问题是,在IsPublished这里省略 volatile 是否安全?许多人提到“volatile”关键字与多线程编程无关,我同意他们的看法。但是,在编译器优化期间可以应用“恒定折叠/传播”,并且如wiki 页面所示,如果编译器不太了解谁可以if (IsPublished)更改. 我在这里错过或误解了什么吗?if (false)IsPublished

内存屏障可以防止 CPU 的编译器排序和乱序执行,但正如我在上一段中所说,我仍然需要volatile避免“恒定折叠/传播”,这是一种危险的优化,尤其是使用全局变量作为标志无锁码?

0 投票
1 回答
1191 浏览

c++ - 防止编译器不断折叠表达式的技巧

我的程序中有一个字符串文字,我正在尝试创建一个业余校验和以确保该字符串文字没有在可移植可执行文件中被替换。

为此,我创建了字符串文字的散列,并将其作为整数文字存储在程序中。现在我有两种文字,一种用于字符串,一种用于哈希。

在我的代码中,我通过使用以相同方式散列字符串文字的函数来实现校验和,我创建一个新的运行时散列并根据散列文字检查该散列。

问题当然是,通过编译器优化,它可能会预先计算运行时哈希,然后我会根据哈希文字检查哈希文字,并且校验和将始终返回 true。

所以我正在寻找一种技巧,让编译器认为字符串文字是一个可以是任何东西的动态字符串,这样它就不会对运行时哈希进行常量折叠优化,我的代码也能正常工作。

0 投票
1 回答
440 浏览

haskell - 有没有办法禁用 GHC 中的常量折叠优化?

我需要编译一些带有 GHC -O1 优化但禁用常量折叠优化的 Haskell 源代码。但是,我在 GHC 手册中找不到用于切换常量折叠的优化标志。这是否可以关闭它同时保持其他优化?

0 投票
2 回答
311 浏览

c - C中的最小保证常数折叠

问题

我很好奇是否有任何关于在 C 中进行恒定折叠的保证。

我看过的地方

一个我不知道声誉的网站上的这个链接提出了一个临时评论:

所有 C 编译器都可以折叠宏扩展后出现的整数常量表达式(ANSI C 要求)。

但是我没有在例如 The C Programming Language, second edition 中看到任何内容(我认为它已经彻底更新以说明 ANSI C 的所有细节)。但是在检查索引以获取相关词的引用后,我没有发现任何可以保证这一点的东西。第 38 页和第 209 页特别接近,因为他们说任何可以在编译时计算的表达式都可以在可以使用常量的地方使用(如果我们足够迂腐的话,可能会有一些限制),并且它说这样的表达式“可能”在编译时被评估,而不是“将”/(一些同义词)。

我搜索了这个 C89 最终草案。单词“folding”和“folded”没有产生值的结果,搜索“constant expression”产生了63个匹配,其中我检查了大约一半。感兴趣的主要部分似乎与本书基本相同(它使用单词“ can ”而不是“may”,但在这种情况下它们是同义词)。

这两个似乎在逻辑上强烈暗示每个 ANSI C 编译器都必须具有基本的常量折叠功能,但与此同时,似乎没有任何硬性禁止将常量表达式编译成计算表达式的代码在运行时(这样的实现仍然受益于常量表达式,因为编译器可以生成计算一次的代码,然后假设值不会改变,并且这样的实现可能会受到给定底层架构的限制 - 例如几个 RISC 架构必须使用两条指令来初始化某些可能的值,或者从内存位置加载它们)。

我还简要搜索了这个 C99 最终草案,但“折叠”产生了一个没有价值的结果,而“折叠”和“常量”各有一百多个匹配项,我目前无法分配时间来爬取。

动机

我编写了这些宏是为了在一些有点旋转的代码中更清晰地表达语义/意图:

..wheren始终是整数文字。我想得到安慰,听到一个令人放心的声音说“没关系,使用的每个远程重要的 C 编译器都会为你折叠这些常量”。(PS 我问了一个单独的问题,即是否UCHAR_NTH_BIT_m应该像位从第 0 位或第 1 位开始一样,希望在正确的位置。)

是的,底部的宏可以变成单独的宏,例如#define UCHAR_1ST_BIT_m (unsigned char )1通过#define UCHAR_3RD_BIT_m (unsigned char )4代码或我在代码中碰巧需要的宏 - 虽然我不确定哪个更好,但这可能是一个有争议的问题,因为如果我想要要成为一名优秀的迂腐语言律师类型的 C 程序员,我不能完全避免顶级程序员(必须确保代码在那些 DSP/嵌入式和古老的大型机 C 实现上做正确的事情)。

0 投票
0 回答
126 浏览

babeljs - babel 6 和常量折叠/传播

有人可以建议在生产模式下从代码中消除常量的正确方法吗?我已经测试过babel-plugin-constant-foldingbabel-plugin-dead-code-elimination但它们都只适用于 babel 5,而不适用于 babel 6。

例子:

我希望得到:

或者,更好(老实说,我不需要这种级别的优化,用没有字符串 concat 的值替换所有 ID 对我来说完全足够了):

但只得到:

有人可以建议我正确的 babel 插件顺序吗?

0 投票
2 回答
112 浏览

gcc - 在 16 位目标架构上不断折叠期间溢出

我在 16 位目标平台上使用 avr-gcc

我想做这样的事情:

正如预期的那样,我收到一个溢出错误,因为 MIN_UPDATES_PER_REV*MAX_RPM 的计算结果为 0xf4240:

如果我将常量强制为 32 位并在折叠后转换回 uint16_t,事情就会解决,尽管我失去了 -Woverflow 的好处:

我可以强制 gcc 在恒定折叠期间处理较大的中间值吗?

我可以强制预处理器为我做持续折叠吗?

是否有我应该了解的最佳实践?