Skip to content
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

JIT: Teach middle-end liveness to DCE dead calls without sideeffects #106183

Closed
wants to merge 2 commits into from

Conversation

jakobbotsch
Copy link
Member

Currently only the backend liveness pass will DCE calls without side effects when their result is unused. However, unused runtime lookups can end up expanded to control flow that we will be unable to DCE. This teaches the middle-end liveness pass to DCE dead calls as well.

Fix #106129

Currently only the backend liveness pass will DCE calls without side
effects when their result is unused. However, unused runtime lookups can
end up expanded to control flow that we will be unable to DCE. This
teaches the middle-end liveness pass to DCE dead calls as well.

Fix dotnet#106129
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 9, 2024
@jakobbotsch

This comment was marked as resolved.

@EgorBot

This comment was marked as resolved.

@EgorBot

This comment was marked as resolved.

@jakobbotsch
Copy link
Member Author

@EgorBot -amd -arm64

using System.Net;
using BenchmarkDotNet.Attributes;

namespace genericlist
{
    public sealed class BinaryTrie
    {
        [System.Runtime.CompilerServices.InlineArray(2)]
        public struct TwoBranches<TNodeLeaf>
        {
            private TNodeLeaf? _ref0;
        }
        public class Node<TNodeLeaf>
        {
            public TwoBranches<Node<TNodeLeaf>> Branches;
            public Node<TNodeLeaf> n0;
            public Node<TNodeLeaf> n1;
            public bool IsLeaf;
            public TNodeLeaf? NodeLeaf;
        }

        public static TLeaf? LookupInlineArray<TLeaf>(Node<TLeaf> root)
        {
            Node<TLeaf> currentNode = root;
            TLeaf? result = default;
            for (int i = 0; i < 8; i++)
            {
                int bit = i % 2;
                Node<TLeaf>? branch = currentNode.Branches[bit];
                if (branch is not null)
                {
                    return result;
                }
            }

            return result;
        }

        public static TLeaf? LookupTernary<TLeaf>(Node<TLeaf> root)
        {
            Node<TLeaf> currentNode = root;
            TLeaf? result = default;
            for (int i = 0; i < 8; i++)
            {
                int bit = i % 2;
                Node<TLeaf>? branch = bit == 0 ? currentNode.n0 : currentNode.n1;
                if (branch is not null)
                {
                    return result;
                }
            }

            return result;
        }
    }

    [DisassemblyDiagnoser]
    public class Benchmarks
    {
        BinaryTrie.Node<bool> _bool;
        BinaryTrie.Node<IPAddress> _ipaddress;

        [GlobalSetup]
        public void Setup()
        {
            _bool = new BinaryTrie.Node<bool>();
            _ipaddress = new BinaryTrie.Node<IPAddress>();
        }

        [Benchmark]
        public bool LookupBoolInlineArray()
        {
            return BinaryTrie.LookupInlineArray(_bool);
        }

        [Benchmark]
        public bool LookupBoolTernary()
        {
            return BinaryTrie.LookupTernary(_bool);
        }

        [Benchmark(Baseline = true)]
        public IPAddress LookupIPAddressInlineArray()
        {
            return BinaryTrie.LookupInlineArray(_ipaddress);
        }

        [Benchmark]
        public IPAddress LookupIPAddressTernary()
        {
            return BinaryTrie.LookupTernary(_ipaddress);
        }
    }
}

@EgorBot
Copy link

EgorBot commented Aug 9, 2024

Benchmark results on Amd
BenchmarkDotNet v0.14.0, Ubuntu 22.04.4 LTS (Jammy Jellyfish)
AMD EPYC 7763, 1 CPU, 8 logical and 4 physical cores
  Job-JTTXUS : .NET 9.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  Job-LXMITZ : .NET 9.0.0 (42.42.42.42424), X64 RyuJIT AVX2
Method Toolchain Mean Error Ratio Code Size
LookupBoolInlineArray Main 5.115 ns 0.0874 ns 0.63 10 B
LookupBoolTernary Main 6.980 ns 0.1289 ns 0.86 10 B
LookupIPAddressInlineArray Main 8.143 ns 0.0133 ns 1.00 20 B
LookupIPAddressTernary Main 7.487 ns 0.2102 ns 0.92 20 B
LookupBoolInlineArray PR 4.967 ns 0.1312 ns 0.61 10 B
LookupBoolTernary PR 6.749 ns 0.1179 ns 0.83 10 B
LookupIPAddressInlineArray PR 5.354 ns 0.1748 ns 0.66 20 B
LookupIPAddressTernary PR 7.517 ns 0.1750 ns 0.92 20 B

BDN_Artifacts.zip

@EgorBot
Copy link

EgorBot commented Aug 9, 2024

Benchmark results on Arm64
BenchmarkDotNet v0.14.0, Ubuntu 22.04.4 LTS (Jammy Jellyfish)
Unknown processor
  Job-QAGPZC : .NET 9.0.0 (42.42.42.42424), Arm64 RyuJIT AdvSIMD
  Job-DXQMVU : .NET 9.0.0 (42.42.42.42424), Arm64 RyuJIT AdvSIMD
Method Toolchain Mean Error Ratio Code Size
LookupBoolInlineArray Main 8.004 ns 0.0023 ns 0.57 36 B
LookupBoolTernary Main 12.217 ns 0.0022 ns 0.87 36 B
LookupIPAddressInlineArray Main 14.077 ns 0.0014 ns 1.00 48 B
LookupIPAddressTernary Main 12.776 ns 0.0046 ns 0.91 48 B
LookupBoolInlineArray PR 8.040 ns 0.0005 ns 0.57 36 B
LookupBoolTernary PR 12.220 ns 0.0024 ns 0.87 36 B
LookupIPAddressInlineArray PR 8.403 ns 0.0005 ns 0.60 48 B
LookupIPAddressTernary PR 13.106 ns 0.0020 ns 0.93 48 B

BDN_Artifacts.zip

@jakobbotsch jakobbotsch added this to the 9.0.0 milestone Aug 9, 2024
@jakobbotsch jakobbotsch modified the milestones: 9.0.0, 10.0.0 Aug 10, 2024
@dotnet-policy-service dotnet-policy-service bot removed this from the 10.0.0 milestone Sep 9, 2024
Copy link
Contributor

Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InlineArray in generic class
2 participants