-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Treat readonly fields as JIT time constants. #4287
Comments
"For example, there is already a JIT times constant - IntPtr.Size. In the following code JIT will get rid not only of the wrong branch but the comparison itself" As far as I can tell RyuJIT already does that: if (IntPtr.Size == 8)
Console.WriteLine(IntPtr.Size); generates this
Yet the following code runs and prints 42: public class Program {
public static readonly int x = 1;
static void Main() {
typeof(Program).GetField("x").SetValue(null, 42);
Console.WriteLine(typeof(Program).GetField("x").GetValue(null));
}
} |
IntPtr.Size is an old trick. The idea is to extend it to static readonly fields.
yeah.. that's not complete readonliness 😞 |
What about static readonly delegates? Could they be inlined or lifted? |
Ah, I see. It does that too: public class Program {
public static readonly int x = 1;
static void Main() {
if (x == 1)
Console.WriteLine(x);
}
} generates
Nope. Delegates are never inlined by current .NET JIT compilers. |
WHAAAT!?? It is already there!? Huge thanks guys! I dreamed of this feature :) 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 🎉 |
I checked it with ProcessorCount (just to be sure) class Program
{
public static readonly int procCount = Environment.ProcessorCount;
static void Main(string[] args)
{
if (procCount == 2)
Console.WriteLine("!");
}
} if is completely eliminated. As well as WriteLine if procCount != 2. I think this RuyJIT ability deserves a separate post in JIT team blog. People should know about it. |
For scalar types such as int or floats the JIT compilers have optimized this kinds of readonly fields since CLR 3.5 at least. If an Object based readonly static field is initialized then it is not possible to optimize them as their values depend upon the address assigned at runtime. |
I am happily closing this issue. |
If understand it right mutating readonly fields outside of constructors is forbidden at CLR level.
In certain conditions this could allow JIT to treat static fields of classes as JIT time constants.
And it opens interesting opportunities.
For example, there is already a JIT times constant - IntPtr.Size. In the following code JIT will get rid not only of the wrong branch but the comparison itself:
JIT could do the same with "constant" static readonly fields.
Imagine such field:
And this check:
Or it could be a performance counter or other similar thing.
Another case is static readonly array fields. JIT could skip bounds checking as if it were a local variable or a parameter.
There are possibly other optimization opportunities, you guys know your JIT better ;)
The text was updated successfully, but these errors were encountered: