Issue 24335 - Class Downcast
Summary: Class Downcast
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 enhancement
Assignee: No Owner
URL:
Keywords: industry, performance
Depends on:
Blocks:
 
Reported: 2024-01-12 01:37 UTC by Walter Bright
Modified: 2024-01-16 05:08 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Walter Bright 2024-01-12 01:37:25 UTC
deadalnix writes:

Currently, we use a linear algorithm to downcast and we reach this algorithm via a call int he runtime. This prevent the optimizer from doing anything about it, in addition to be slow. The problem is similar to 1/. The whole check can be made trivial if we let the compiler prebake some data for us, namely an array of primary parents. Let's see what it looks like in the first example, when b is not final.

class A {}
class B : A {}

auto foo(A a) {
    return cast(B) a;
}
Which we can do as follow:

auto foo(A a) {
    // The primaries generated by the compiler for us.
    auto tidA = typeid(A);
    assert(tidA.primaries = [tidA]);
    auto tidB = typeid(B);
    assert(tidB.primaries = [tidA, tidB]);

    auto t = typeid(a);
    auto depth = tidB.primaries.length - 1;

    if (t.primary.length <= depth) {
        return null;
    }

    if (t.primary[depth] == tidB) {
        return a;
    }

    return null;
}

This is starting to look good, now we have general downcast in a form that is not only really fast to perform, but also completely transparent to the optimizer.

https://forum.dlang.org/post/hteuczyclxajakrisxjd@forum.dlang.org
Comment 1 Walter Bright 2024-01-16 05:08:35 UTC
Partial implementation:

https://github.com/dlang/dmd/pull/16040

Does not include the table.