JIT fails to escape simple usage of `List<>` and `[]`

Open
#111,838 11 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
csharp

Research direction

Start with the ListUsage, ArrayUsage, and Expected methods and reproduce their generated machine code using the linked Godbolt example against the main branch. Investigate the JIT behavior for the local List and int[] allocations and constant indexing; done means the intended optimization is implemented and verified by comparing the generated code.

Written by the indexing model from the issue text.

Description

area-CodeGen-coreclr

Was tinkering around JIT generated code for List<> and raw arrays for very simple below code.

    public static void ListUsage()
    {
        List<int> numbers = new(1);
        numbers.Add(1);
        Console.WriteLine(numbers[0]);
    }

    public static void ArrayUsage()
    {
        int[] numbers = new int[1] {1};
        Console.WriteLine(numbers[0]);
    }

    public static void Expected()
    {
        Console.WriteLine(1);
    }

The code is very self explanatory, nothing magical or complex as such. I was comparing the machine code generated by each method. I was expecting JIT to see the code flow and optimize the code gen generated for ListUsage and ArrayUsage to be similar as Expected method, but it does not.

Below are things JIT can see and I would expect it to optimize it further.

  1. JIT can see List<int> numbers (in method ListUsage) and int[] numbers (in method ArrayUsage) are declared inside the method and get destroyed in method itself at the end (does not get pass to any other method). It even sees the maximum size of those data structure which is 1 so ideally it should stack allocate those instead of doing heap allocation.
  2. The number that is getting added to collection is pure constant (1), so its not dynamic value. And on very next line we are even printing it directly by indexing and after that the method ends. So ideally JIT should see this flow and should optimize the code gen just like the code-gen generated by Expected method in above code.

Tested against main branch on CC => https://godbolt.org/z/eWv6Yaoaj

Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from dotnet/runtime

All issues in dotnet/runtime

Similar issues

More C# issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.