By ref and by pointer kills performance.

Timon Gehr timon.gehr at gmx.ch
Wed Feb 14 11:43:31 UTC 2024


On 14.02.24 05:49, Walter Bright wrote:
> On 2/12/2024 7:31 PM, Richard (Rikki) Andrew Cattermole wrote:
>> dmd having bad codegen here isn't a surprise, that is to be expected.
> 
> I'm used to people saying that DMD doesn't do data flow analysis. It 
> does. In fact, it is based on my OptimumC, which was the first C 
> compiler on DOS to do DFA back in the 1980s.
> 
> This isn't a case of buggy DFA. It's a case of doing DFA correctly.
> 
> The issue is pointer aliasing. A pointer can point to anything, 
> including const data. Therefore, storing through a pointer can alter any 
> value that is reachable via a pointer. Therefore, storing through a 
> pointer invalidates any cached value already read.
> 
> This is what you're seeing.
> ...

Well, my understanding is that storing a value that was read from a 
`uint*` cannot invalidate a value read from the same `uint*` unless 
unaligned reads/writes are allowed or the pointer can point to itself.

Are unaligned reads/writes allowed in D? Can a `uint*` point to itself? 
Is there something else I missed?

How to make the following assertion fail by filling the `...` holes with 
code without invoking UB?

```d
void fillBP1(uint* value, uint* dest)pure{
     dest[0] = *value;
     dest[1] = *value;
     dest[2] = *value;
     dest[3] = *value;
}

void fillBP2(uint* value, uint* dest)pure{
     auto tmp = *value;
     dest[0] = tmp;
     dest[1] = tmp;
     dest[2] = tmp;
     dest[3] = tmp;
}

uint[4] distinguish(alias f)()pure{
     ...; // TODO
     uint[4] dest = ...; // TODO
     uint* value = ...;  // TODO
     f(value,dest.ptr);
     return dest;
}

void main(){
     import std.stdio;
     assert(distinguish!fillBP1()==distinguish!fillBP2());
     writeln(test!fillBP1);
     writeln(test!fillBP2);
}
```

> C99 tried to address this with __restrict, but few people use it or 
> understand it. D didn't bother with it because people will inevitably 
> misuse __restrict and get their data mysteriously corrupted.
> 

My understanding is the case in the OB does not require `__restrict`. 
`value` can point to any of the 4 fields of `dest`, it is okay to only 
read it once even in that case. Of course, maybe the data flow analysis 
is more conservative than that, but I wouldn't necessarily point to this 
case as one where data flow analysis is working "correctly".


More information about the Digitalmars-d mailing list