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