One of the micro-optimizations I am about to merge from TCB involves disregarding V_MAY_DEF/V_MUST_DEF operands for read-only globals.
So, if a symbol is marked read-only and the operand scanner requests a V_MAY_DEF or V_MUST_DEF operand for it, we replace it with a VUSE. This works fine, except that I was having comparison errors with SPEC2000's eon. I tracked it down to the C++ FE emitting an assignment instruction for a global const variable. What follows is speculation, I have no idea how the FE really works: The source code declares const double ggPi = 3.14159265358979323846; double const divPi = 1 / ggPi; And since divPi is initialized to an expression, I guess it needs to compute it at runtime, so it emits an initialization function: void __static_initialization_and_destruction_0(int, int) (__initialize_p, __priority) { ... if (D.55019) { ggPi.319 = ggPi; D.55021 = 1.0e+0 / ggPi.319; divPi = D.55021; } ... } So, we now have an assignment for divPi in the IL stream. This throws a monkey wrench into my micro-optimization because it shouldn't really have ignored that V_MUST_DEF (we end up removing the assignment). I also wouldn't want the FE to mark divPi writeable, as we would now consider it call-clobbered. Is this analysis correct? Will other FEs need to do things like this? If so, then I'll just get rid of this transformation. We are already ignoring read-only symbols at call sites and there are new analysis for trimming clobbering lists even further down the pipe. Thanks. Diego.