February 02, 2015
On 2/2/15 8:42 AM, Johannes Pfau wrote:
> Again the problem is not volatileLoad/Store which
> translate to single instructions it's wrappers.

So does the argument boil down to better inlining control and enforcement? -- Andrei
February 02, 2015
Am Mon, 02 Feb 2015 02:49:48 -0800
schrieb Walter Bright <newshound2@digitalmars.com>:

> On 2/2/2015 1:24 AM, Johannes Pfau wrote:
> > Usually those people just don't use
> > volatile as long as their code works. Once it breaks they add
> > volatile everywhere till it works again.
> 
> Having a volatile type is not going to make things better for such
> people. In fact, it may make things worse. It's harder to muck up
> volatileLoad() and volatileStore().
> 

Wrong: wrappers are provided by the library. Users simply do stuff like PORTB.pin0 = Level.high;

they never have to use volatile directly. And it's actually the same in C which provides macros.

I wrote this in reply to your statements that wrappers are not necessarily, of course you didn't quote that part. Without wrappers, end users do have to use volatileLoad/Store by themselves and now they do need to know what volatile is, where it's necessary, ...

> 
> >> The compiler intrinsics participate in all optimizations.
> > Not sure what that's supposed to mean. The backend can generate more efficient code if it knows that an address is a literal value. If you add wrappers (void f(void* p) {volatileLoad(p)}) the information that p is a constant is a literal is lost and needs to be recovered by the backend, which is only done with enabled backend optimizations.
> 
> Please try it before deciding it does not work.

I guess one ad hominem wasn't enough?
http://goo.gl/Y9OFgG

_Dmain:
	push   rbp
	mov    rbp,rsp
	sub    rsp,0x10
	mov    rax,0x5                      <==
	mov    QWORD PTR [rbp-0x8],rax
	mov    ecx,DWORD PTR [rax]          <== a register based load

The instruction it should generate is
mov ecx, [0x5]

Not sure if it's actually more efficient on X86 but it makes a huge difference on real microcontroller architectures.
February 02, 2015
Am Mon, 02 Feb 2015 08:55:59 -0800
schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:

> On 2/2/15 8:42 AM, Johannes Pfau wrote:
> > Again the problem is not volatileLoad/Store which
> > translate to single instructions it's wrappers.
> 
> So does the argument boil down to better inlining control and enforcement? -- Andrei

Mostyl that, but not only that. It's also necessary that the compiler knows after inlining that the address is a literal. Loading data from fixed literal addresses produces different, more efficient code than loading from an runtime address. As the function code will generally be written for runtime values the compiler must optimize after inlining to recognize the inlined code deals with literals.

The GCC backend performs these optimizations only if optimization is enabled. We could always do this in the dmd frontend inliner but LDC and GDC don't/can't use the frontend inliner.

That's lot of work given that pragma(address) is a simple, consistent solution and not even a real language change.
February 02, 2015
On Mon, Feb 02, 2015 at 08:55:59AM -0800, Andrei Alexandrescu via Digitalmars-d wrote:
> On 2/2/15 8:42 AM, Johannes Pfau wrote:
> >Again the problem is not volatileLoad/Store which
> >translate to single instructions it's wrappers.
> 
> So does the argument boil down to better inlining control and enforcement?  -- Andrei

FWIW, from the POV of a bystander, the point is that force-inline for certain things (namely wrappers around certain intrinsics, like operator overloads for atomics, what-have-you) is necessary in order to guarantee that function call overhead will not be incurred no matter what.

Walter seems to dislike forced inlining for various reasons, preferring inlining as a hint at the most, and he probably has a point in most cases (let the compiler make the judgment). But in other cases, such as the one in question, the user needs to override the compiler's decision. Currently there's no way to do that, and it's a showstopper for those users.

Unless we're proposing to flood the compiler with intrinsics, one for every possible operator overload of volatile loads/stores, which I think should be obviously infeasible. And even then, you still might miss one or two other obscure wrappers that users might discover that they need. It seems reasonable that instead of burdening the compiler (and compiler maintainers, and porters) to keep up with an ever-expanding set of intrinsics, making use of the language to express what is needed via forced-inline functions is a better way to do things.


T

-- 
If it's green, it's biology, If it stinks, it's chemistry, If it has numbers it's math, If it doesn't work, it's technology.
February 02, 2015
On 2 February 2015 at 17:06, Johannes Pfau via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> Am Mon, 02 Feb 2015 02:49:48 -0800
> schrieb Walter Bright <newshound2@digitalmars.com>:
>
>> On 2/2/2015 1:24 AM, Johannes Pfau wrote:
>> > Usually those people just don't use
>> > volatile as long as their code works. Once it breaks they add
>> > volatile everywhere till it works again.
>>
>> Having a volatile type is not going to make things better for such
>> people. In fact, it may make things worse. It's harder to muck up
>> volatileLoad() and volatileStore().
>>
>
> Wrong: wrappers are provided by the library. Users simply do stuff like PORTB.pin0 = Level.high;
>
> they never have to use volatile directly. And it's actually the same in C which provides macros.
>
> I wrote this in reply to your statements that wrappers are not necessarily, of course you didn't quote that part. Without wrappers, end users do have to use volatileLoad/Store by themselves and now they do need to know what volatile is, where it's necessary, ...
>
>>
>> >> The compiler intrinsics participate in all optimizations.
>> > Not sure what that's supposed to mean. The backend can generate more efficient code if it knows that an address is a literal value. If you add wrappers (void f(void* p) {volatileLoad(p)}) the information that p is a constant is a literal is lost and needs to be recovered by the backend, which is only done with enabled backend optimizations.
>>
>> Please try it before deciding it does not work.
>
> I guess one ad hominem wasn't enough?
> http://goo.gl/Y9OFgG
>

The error DMD gives when optimizations are turned on is comical at best too.

Iain.
February 02, 2015
On 2 February 2015 at 05:48, Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> On 2/1/2015 9:21 PM, Daniel Murphy wrote:
>>
>> "Walter Bright"  wrote in message news:mam6qe$15nu$1@digitalmars.com...
>>>
>>> > We also need a pragma(address) to complement pragma(mangle).
>>>
>>> What would that do?
>>
>>
>> It would allow naming a memory address, similar to using .org in assembly.
>>
>> eg
>> pragma(address, 0x0025)
>> shared ubyte PORTB;
>> static assert(&PORTB == cast(ubyte*)0x0025);
>>
>> This is a much nicer version of C's
>> #define PORTB (*(volatile unsigned char *)0x0025)
>
>
> That's what I suspected :-)
>
>   struct Ports {
>     static ubyte B() { return volatileLoad(cast(ubyte *)0x0025); }
>     static void B(ubyte value) { volatileStore(cast(ubyte *)0x0025, value);
> }
>   }
>
>   ...
>   Ports.B = 7;
>   foo(Ports.B);
>
> gets the job done. Of course, you could take it further and make a template out of it:
>
>   auto Ports = Port!(ubyte, 0x0025);

That code doesn't work with DMD.

http://goo.gl/hgsHg0

Iain.
February 02, 2015
On 2/2/15 12:06 PM, Johannes Pfau wrote:
> Am Mon, 02 Feb 2015 02:49:48 -0800
> schrieb Walter Bright <newshound2@digitalmars.com>:

>> Please try it before deciding it does not work.
>
> I guess one ad hominem wasn't enough?

Sorry, I'm not really vested in this discussion at all, but I don't think you realize what ad hominem means.

http://en.wikipedia.org/wiki/Ad_hominem

-Steve

February 02, 2015
On 2/2/15 9:06 AM, Johannes Pfau wrote:
> I guess one ad hominem wasn't enough?

Please cool it will you? That doesn't quite qualify. -- Andrei
February 02, 2015
On 2/2/15 9:15 AM, Johannes Pfau wrote:
> Am Mon, 02 Feb 2015 08:55:59 -0800
> schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
>
>> On 2/2/15 8:42 AM, Johannes Pfau wrote:
>>> Again the problem is not volatileLoad/Store which
>>> translate to single instructions it's wrappers.
>>
>> So does the argument boil down to better inlining control and
>> enforcement? -- Andrei
>
> Mostyl that, but not only that. It's also necessary that the compiler
> knows after inlining that the address is a literal. Loading data from
> fixed literal addresses produces different, more efficient code than
> loading from an runtime address. As the function code will generally be
> written for runtime values the compiler must optimize after inlining
> to recognize the inlined code deals with literals.
>
> The GCC backend performs these optimizations only if optimization is
> enabled. We could always do this in the dmd frontend inliner but LDC and
> GDC don't/can't use the frontend inliner.
>
> That's lot of work given that pragma(address) is a simple, consistent
> solution and not even a real language change.

I suggest we push forward with better inlining control and better optimizations, but not pragma(address). -- Andrei
February 02, 2015
On 2/2/15 9:23 AM, Iain Buclaw via Digitalmars-d wrote:
> That code doesn't work with DMD.
>
> http://goo.gl/hgsHg0

Has that been filed yet? -- Andrei