dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.09k stars 4.7k forks source link

Consider hoisting of class init checks for loop cloning and inversion #49102

Open BruceForstall opened 3 years ago

BruceForstall commented 3 years ago

Cloning to allow for a loop with a class init check, and one where the class init check is removed, could be profitable.

AndyAyersMS writes:

I wonder if we should consider using this check as a gating condition for loop cloning... Also may factor into the do-while transformation heuristics, these try to account for the potential "savings" from hoisting the class init call check out of the loop.

So for some subset of loops we would produce a loop that knows classes are inited and does no checks, and another that will conditionally check within the loop body as above.

Related: https://github.com/dotnet/runtime/pull/47901

category:cq theme:loop-opt skill-level:expert cost:medium impact:medium

EgorBo commented 3 years ago

What is going to happen for, let's say:

class MyStaticCctor
{
    public static readonly int s_Field = 0;

    static MyStaticCctor()
    {
        s_Field = 42;
    }
}

class Tests
{
    void TestMethod(int[] array)
    {
        for (int i = 0; i < 1000; i++)
            array[i] = MyStaticCctor.s_Field;
    }
}

Here we already are going to clone the loop for Length>=1000 check. Will it look like this then?:

if (array.Length>=1000 && MyStaticCctor.IsInited)
    fast-loop
else
    slow-loop
BruceForstall commented 3 years ago

Yeah, that's the idea, where slow-loop is required to have an in-loop init check, and fast-loop can remove it. It wouldn't be valuable if the init check can already be hoisted.