Implementing Altivec vector support questions

  1. In implementing vector and __vector, which is better?:

A. Don’t make it a keyword, but if LangOptions::AltiVec is set and a kw_identifier with the name “vector” or “__vector” is followed by a numeric type keyword, make the type a vector type.

B. Make vector and __vector a keyword if LangOptions::AltiVec is set, and if not followed by a numeric type keyword, treat it as an identifier.

My guess is that A is better as it involves less fixing up of cases where an identifier with the name of “vector” can occur.

  1. Regarding the typing, I’m thinking internally it would be treated just as if attribute((vector_size(16)) were applied to the type, right?

  2. With attribute((vector_size(16)), does the Clang code generation already output everything LLVM needs to support the Altivec vectors?

For example, in looking at the code generated for some code using an “attribute((vector_size(16)) float” variable or return type, the .ll file uses “<4 x float>”. On a PowerPC platform supporting Altivec, does LLVM automatically know to map that to a vector register?

  1. I’m guessing the Altivec functions can be implemented as Clang built-in functions that map to calls to LLVM’s altivec intrinsic functions, right? I haven’t researched this much yet.

  2. Any suggestions or other things I ought to know at this early point?

Thanks.

-John

1. In implementing vector and __vector, which is better?:

I'm not familiar with the intricacies of this extension, so I don't know the technical feasibility of the different approaches, but here's MHO:

A. Don't make it a keyword, but if LangOptions::AltiVec is set and a kw_identifier with the name "vector" or "__vector" is followed by a numeric type keyword, make the type a vector type.

This would be the "context sensitive keyword" approach I guess. I tend to not like this because it can be fragile / unpredictable.

B. Make vector and __vector a keyword if LangOptions::AltiVec is set, and if not followed by a numeric type keyword, treat it as an identifier.
My guess is that A is better as it involves less fixing up of cases where an identifier with the name of "vector" can occur.

I don't know how much magic is inherent in this language extension. Would it be bad to to make __vector *always* be on when AltiVec is enabled (whether or not it is followed by a 'numeric type keyword')? We could then make 'vector' be fuzzier. I'm still vaguely uncomfortable with 'vector' changing semantics depending on its lexical context, but understand that you probably don't have a choice here :slight_smile:

2. Regarding the typing, I'm thinking internally it would be treated just as if __attribute__((vector_size(16)) were applied to the type, right?

Sure, if that works! I don't know what __vector does.

3. With __attribute__((vector_size(16)), does the Clang code generation already output everything LLVM needs to support the Altivec vectors?

I think so, though we also need an 'altivec.h' for clang to use, in a similar spirit to 'xmmintrin.h' for sse.

For example, in looking at the code generated for some code using an "__attribute__((vector_size(16)) float" variable or return type, the .ll file uses "<4 x float>". On a PowerPC platform supporting Altivec, does LLVM automatically know to map that to a vector register?

Yes. However, noone has done any ABI compatibility testing on PowerPC, even for simple types. It is likely that there are a bunch of bugs passing structures by value etc. Daniel has a nice randomized testcase generator for finding cases that need to be improved.

4. I'm guessing the Altivec functions can be implemented as Clang built-in functions that map to calls to LLVM's altivec intrinsic functions, right? I haven't researched this much yet.

Yes, we support the 'unusual' altivec builtins in llvm-gcc by mapping them onto the LLVM intrinsics in llvm/include/llvm/IntrinsicsPowerPC.td. The simple ones make directly onto llvm IR vector instructions.

-Chris

Thanks, Chris.

I don’t know how much magic is inherent in this language extension. Would it be bad to to make __vector always be on when AltiVec is enabled (whether or not it is followed by a ‘numeric type keyword’)? We could then make ‘vector’ be fuzzier. I’m still vaguely uncomfortable with ‘vector’ changing semantics depending on its lexical context, but understand that you probably don’t have a choice here :slight_smile:

I think I see. Treat “__vector” as a normal keyword token, and if “vector” is encountered, I still do the context check and effectively treat it as “__vector”?

Sure, if that works! I don’t know what __vector does.

My understanding is that “__vector” (or “vector”) in this context is always followed by a numeric type, i.e. “_vector unsigned int”. My guess was that this would be effecticvely equivalent to “attribute((vector_size(16))) unsigned int”, so the plan would then be to have the resulting type for these two be the same after the semantic action.

I think so, though we also need an ‘altivec.h’ for clang to use, in a similar spirit to ‘xmmintrin.h’ for sse.

Yes, probably, if nothing else just to be compatible with gcc. (It’s mentioned in the Altivec standard in section 2.6 of http://www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPIM.pdf). I was told it was orginally deprecated, but then left in to help with early implementation. Looking at the one we have for the PS3 gcc compiler, it seems to be the PowerPC version, and mostly just maps Altivec names to the “_builtin*” functions.

Yes. However, noone has done any ABI compatibility testing on PowerPC, even for simple types. It is likely that there are a bunch of bugs passing structures by value etc. Daniel has a nice randomized testcase generator for finding cases that need to be improved.

I guess we’ll have to cross that bridge when we get to it.

-John

Thanks, Chris.

I don’t know how much magic is inherent in this language extension. Would it be bad to to make __vector always be on when AltiVec is enabled (whether or not it is followed by a ‘numeric type keyword’)? We could then make ‘vector’ be fuzzier. I’m still vaguely uncomfortable with ‘vector’ changing semantics depending on its lexical context, but understand that you probably don’t have a choice here :slight_smile:

I think I see. Treat “__vector” as a normal keyword token, and if “vector” is encountered, I still do the context check and effectively treat it as “__vector”?

Right.

Sure, if that works! I don’t know what __vector does.

My understanding is that “__vector” (or “vector”) in this context is always followed by a numeric type, i.e. “_vector unsigned int”. My guess was that this would be effecticvely equivalent to “attribute((vector_size(16))) unsigned int”, so the plan would then be to have the resulting type for these two be the same after the semantic action.

so ‘vector’ doesn’t work as a type qualifier? For others type qualifiers, you can arrange them, e.g. “const int” == “int const” etc.

I think so, though we also need an ‘altivec.h’ for clang to use, in a similar spirit to ‘xmmintrin.h’ for sse.

Yes, probably, if nothing else just to be compatible with gcc. (It’s mentioned in the Altivec standard in section 2.6 of http://www.freescale.com/files/32bit/doc/ref_manual/ALTIVECPIM.pdf). I was told it was orginally deprecated, but then left in to help with early implementation. Looking at the one we have for the PS3 gcc compiler, it seems to be the PowerPC version, and mostly just maps Altivec names to the “_builtin*” functions.

Right. Be aware that you can’t just use the GCC version of the header (afaik). The terms of the license I’ve seen are something to the effect of “this header is GPL unless it is compiled with GCC”. In any case, you wouldn’t want to reuse it directly anyway, because you’d want to implement the ‘simple’ operations in terms of generic vector operations instead of builtins.

-Chris

In GCC with -faltivec, vector does not work as a type qualifier, but __vector does.

#include <altivec.h> // warning: ignoring <altivec.h> because "-faltivec" specified

int main (int argc, const char * argv[])
{
    vector int a; // warning: unused variable 'a'
    int vector; // warning: unused variable 'vector'
    int vector b; // error: nested functions are disabled (thanks, gcc)
    
    __vector int c; // warning: unused variable 'c'
    int __vector; // warning: useless type name in empty declaration
    int __vector d; // warning: unused variable 'd'
    
    return 0;
}

Without -faltivec, vector is defined as __vector and acts as a qualifier (so the above code compiles with six warnings).

The Altivec standard specifies that __vector comes first as a type specifier, and is a keyword. It also says that vector can be either a macro or a context-sensitive keyword. Having it be a macro, of course, is not a good idea. Which is probably why gcc (at least the PS3 version) does it the context-sensitive way. Thus __vector cannot be a declaration name, but vector can.