GCC O2中实现常量折叠的具体选项及相关编译优化疑问
GCC与虚拟机编译优化问题解答
一、GCC O2中实现常量折叠的具体选项
你给出的C代码:
int a=145;int b=267+a; printf("%d/n",b);
无优化编译时会生成addl指令,开启O2后直接输出412,这个优化属于常量传播+常量折叠的组合效果,对应的GCC核心选项是:
-fconstant-folding:负责在编译期计算常量表达式的结果-fconstant-propagation:负责将已知的常量值替换到引用它的地方
这两个选项默认包含在O1及以上的优化级别中,而O2优化集合包含了所有O1的优化项,因此开启O2时会自动触发该优化。
二、javac的常量折叠能力与栈虚拟机的优化情况
你的判断正确:javac仅支持基础的常量折叠。对于
int a=1+2+3这类纯字面量组成的表达式,javac会在编译期直接计算出结果a=6;但对于int a=1;b=2;c=3;d=a+b+c这种涉及变量的表达式,javac不会在编译期将其折叠为d=6,而是生成对应字节码在运行时执行计算。这是因为javac作为前端编译器,设计上更侧重字节码的兼容性和简洁性,把复杂优化交给JVM的JIT编译器在运行时完成。栈虚拟机并非都无法实现这类优化:
- 比如CLR的JIT编译器会在运行时对这类表达式进行常量传播和折叠优化;
- LuaJIT作为Lua的JIT编译器,也能在编译或运行阶段完成这类变量表达式的常量折叠;
- 只有部分栈虚拟机的前端编译器(如javac)因设计目标限制,未在前端做此类优化,而非栈虚拟机本身不支持。
内容的提问来源于stack exchange,提问作者wang kai
相关产品推荐
相关产品推荐

