3 days ago

This week I have completed the transition from _adEq2 to __equals + memcmp[1] for array comparison.

There are a few changes in how the lowering is done:

  • Comparison between arrays of the same struct type, when the structs can be directly compared using memcmp:

Example with dynamic arrays:

struct A {
    char[256] x = 1;

    this(this){}
}
A[] a = new A[2];
A[] b = new A[2];
assert(a == b);

Before: lowered to __equals(which did not use memcmp).
Now: lowered to memcmp directly.

Example with static arrays:

struct A {
    char[256] x = 1;

    this(this){}
}
A[2] a = new A[2];
A[2] b = new A[2];
assert(a == b);

Before: lowered to _adEq2.
Now: lowered to memcmp directly.

  • Comparison between static arrays, with elements that cannot be compared using memcmp:

Examples:

double[2] a = new double[2];
double[2] b = new double[2];
assert(a == b);
class A {
    int a;

    this(){ this.a = 1; }
}

A[2] a = new A[2];
A[2] b = new A[2];
assert(a == b);

Before: lowered to _adEq2.
Now: lowered to __equals.

I have also noticed a slight reduction in libphobos and libdruntime sizes (around 0.5% when compiled with dmd), which is probably due to the attribute stripping that occurs before the lowering to __equals is performed.

[1] https://github.com/dlang/dmd/pull/21513