Optimize Enum.HasFlag () implementation and recognize it in the JIT.
The previous implementation did a ton of reflection and boxing making
it about 4x slower than it should be. This new (native) implementation
simply memcpy ()s the values out of the Enum objects and then does the
bitwise AND.
In addition, the JIT now recognizes this common IL pattern:
<push int or long ptr>
<push int or long>
box MyFlagsEnum
constrained. MyFlagsEnum
callvirt instace bool class [mscorlib] System.Enum::HasFlag (class [mscorlib] System.Enum)
This is generated from C# code such as:
MyFlagsEnum a = ..., b = ...;
a.HasFlag (b);
When the operand types of the `box` and `constrained.` instructions are
the same, we can skip all the slow stuff that HasFlag () normally does
and simply turn the whole thing into this IR:
<this> = loadi4_membase <this_ptr>
<temp> = int_and <this> <flag>
icompare <temp> <flag>
<result> = int_ceq
This is about 60x faster than the old HasFlag () without any JIT support
and about 15x faster than the new HasFlag () native implementation.
Also, added missing argument checks to HasFlag ().