start on SIMD documentation
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Jan 16 08:38:26 PST 2012
On 1/13/12 11:02 PM, Walter Bright wrote:
> On 1/13/2012 8:52 PM, Andrei Alexandrescu wrote:
>> On 1/13/12 10:03 PM, Walter Bright wrote:
>>> On 1/13/2012 7:03 PM, Andrei Alexandrescu wrote:
>>>> How is that possibly different from what you have now?
>>>
>>> Intrinsic functions are today just a table lookup in the compiler.
>>
>> They're a table lookup if the operation is a compile-time constant. So
>> this
>> argument does not apply.
>>
>>> Template intrinsics currently do not exist, so more code needs to be
>>> written for them.
>>
>> The same table lookup could be done, except in this case it would be more
>> principled.
>
> You and I are talking about different things.
No. Please hear me out.
> The current compiler looks for intrinsics after all template functions
> are converted into real functions. The mangled name is looked up in a
> table to see if:
>
> 1. it is an intrinsic function
>
> 2. what is the corresponding expression node operator
>
> Doing it for intrinsic functions would require either:
>
> 1. adding hundreds of function signatures to the table
>
> 2. moving the intrinsic detection to the template instantiation logic
So this is an implementation issue that has nothing to do with doing the
right thing. That's no reason to do the wrong thing. The real problem
with the current approach is as follows.
Defining an intrinsic function is cheating. It means the language's
facilities are unable to expose computation to the compiler in a manner
that makes it able to translate it to efficient code. This in turn
points to problems in either the language or the compiler technology.
To a good extent these are known issues of the state of the art. There
are advantages to e.g. making integers intrinsic types and imbuing the
compiler with understanding of basic arithmetic identities. Or it makes
sense to define integral rotation as an intrinsic function (or devise a
peephole optimization that detects the pattern) because it's one
assembler operation deriving from a rather involved algorithm. So
intrinsics are a necessary evil.
On to your implementation of simd, which is
simd(opcode, op1, op2)
This is a lie - it's cheating twice. The expression looks like a
function but does not feel like a function. The first argument, the
opcode, is NOT a function parameter. It's part of the function. Passing
a variable in there does not work as a matter of design - the generated
code depends on that so opcode must be known during compilation.
So what do we have to integrate the cheating operation within the
current language semantics? I can think of two. First, make the operand
part of the function name:
simdOPCODE(op1, op2)
This is reasonable because it acknowledges what really happens - each
function has its identity and its generated code.
The second, spaceship-era approach (and closer to the current
implementation) is to make the first argument a template parameter. This
is because template parameters must be known during compilation, which
is exactly opcode's requirement:
simd!opcode(op1, op2)
Either approach should work perfectly fine; it "cheats in style" by
using an existing language construct that exactly matches the
special-cased capability. The current approach cheats badly - it messes
with the language's fabric by defining a construct that's not a function
but looks like one.
I'd be in your debt if you could at least do the right thing when
defining new intrinsics.
Thanks,
Andrei
More information about the Digitalmars-d
mailing list