[llvm-commits] [vector_llvm] CVS: llvm/docs/SIMDCReference.txt VectorCReference.txt

Robert Bocchino bocchino at cs.uiuc.edu
Fri Oct 21 14:33:25 PDT 2005



Changes in directory llvm/docs:

SIMDCReference.txt added (r1.1.2.1)
VectorCReference.txt added (r1.1.2.1)
---
Log message:

Initial commit of reference docs for Vector C and SIMD C backends.


---
Diffs of the changes:  (+588 -0)

 SIMDCReference.txt   |  149 +++++++++++++++++
 VectorCReference.txt |  439 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 588 insertions(+)


Index: llvm/docs/SIMDCReference.txt
diff -c /dev/null llvm/docs/SIMDCReference.txt:1.1.2.1
*** /dev/null	Fri Oct 21 16:33:23 2005
--- llvm/docs/SIMDCReference.txt	Fri Oct 21 16:33:13 2005
***************
*** 0 ****
--- 1,149 ----
+ SIMD C BACKEND REFERENCE
+ Vector LLVM
+ Rob Bocchino
+ October 21, 2005
+ ========================
+ 
+ Overview
+ ========
+ 
+ Vector LLVM extends the LLVM C backend to provide rudimentary support
+ for SIMD (fixed vector) code generation on PowerPC/AltiVec and
+ Intel/SSE2, via the AltiVec and SSE2 C APIs supported by gcc.  This
+ document describes the features and limitations of the AltiVec and
+ SSE2 code generators.  Note that the limitations are considerable!
+ This is a research prototype and a work in progress.
+ 
+ In the discusssion below, $(LLVMSRCDIR) means the "normal" (mainline)
+ LLVM top-level source directory, and $(VLLVMSRCDIR) means the
+ top-level source directory for Vector LLVM.
+ 
+ Backend Source Code
+ ===================
+ 
+ Instruction selection for AltiVec and SSE is done via the LLVM-to-LLVM
+ transformation passes opt -altivec and opt -sse, defined in
+ $(VLLVMSRCDIR)/lib/Transforms/Vector/AltiVec.cpp and SSE.cpp.  These
+ passes perform pattern matching on Vector LLVM expressions written
+ with fixed vectors, and insert LLVM functions that can be written out
+ by the AltiVec and SSE C writers as C API functions, then fed through
+ gcc with the altivec or sse2 flag enabled.
+ 
+ The AltiVec and SSE writers subclass the CWriter class defined in
+ $(LLVMSRCDIR)/lib/Target/CBackend/Writer.cpp in mainline LLVM.  To
+ enable this, Vector LLVM pulls out the class definition for CWriter
+ into a separate file CWriter.h and makes some functions in CWriter
+ virtual, so they can be overridden by the SIMD backends.  Otherwise,
+ the functionality of the C backend itself is unchanged (i.e., any
+ scalar LLVM code will be converted to C by the C backend in the same
+ way as in mainline LLVM).  The SIMD backends themselves are defined in
+ TargetMachine and Writer files located in
+ $(VLLVMSRCDIR)/lib/Target/CBackend.  They define options
+ -march=altivec-c and -march=sse-c that can be invoked with llc to
+ write out C code with gcc vector functions.
+ 
+ Running the Backends
+ ====================
+ 
+ As an example, code generation for AltiVec (on a PowerPC platform)
+ might look like this, where foo.vectorc.c is a Vector C program (q.v.)
+ that uses fixed vectors:
+ 
+   llvm-gcc -I$(VLLVMSRCDIR)/include/VectorC foo.vectorc.c -o foo 
+   opt -raisevectors -altivec < foo.bc | llc -march=altivec-c \
+     > foo.altivec.cbe.c
+   gcc -faltivec -O2 foo.cbe.c -o foo.altivec
+ 
+ Code generation for SSE on X86 might look like this:
+ 
+   llvm-gcc -I$(VLLVMSRCDIR)/include/VectorC foo.vectorc.c -o foo 
+   opt -raisevectors -sse < foo.bc | llc -march=sse-c > foo.sse.cbe.c
+   gcc -msse2 -O2 foo.cbe.c -o foo.sse
+ 
+ Note that the -altivec and -sse passes must be explicitly invoked
+ before the C backend passes.  Setting up things
+ this way makes code generation easier to debug and develop;
+ unfortunately, it means that if the C backends are run on "raw" Vector
+ LLVM code (without the appropriate -altivec or -sse transformation
+ first), they will break.
+ 
+ What Works
+ ==========
+ 
+ Don't expect to run arbitrary Vector LLVM code through the code
+ generation process described above and have it work.  Any legal Vector
+ LLVM code can be run through the -altivec or -sse passes to produce
+ more legal Vector LLVM (inapplicable constructs, such as variable
+ vectors, are just ignored).  However, unless the result is in a form
+ that the AltiVec or SSE backend can understand, the backend will choke
+ when it tries to write out the C file.  For example, if your Vector
+ LLVM program contains variable vectors, those vectors will be ignored
+ by the -altivec or -sse passes, but will cause the AltiVec or SSE C
+ writer to break.
+ 
+ Ideally, there would be a pass that scalarizes any vector patterns
+ that cannot be pattern matched and code generated by the -sse and
+ -altivec passes, but I haven't written that pass yet.  The point of
+ this experiment is to make high performance code, and I am not
+ interested in running code that I cannot vectorize anyway.  The
+ following sections describe what patterns of code can be successfully
+ recognized and translated by the AltiVec and SSE code generators.
+ 
+ Types
+ -----
+ 
+ The AltiVec and SSE2 writers understand the following vector types:
+ 
+ 1. [vector of 4 int], [vector of 4 uint], [vector of 8 short], 
+    [vector of 8 ushort], [vector of 16 sbyte], and 
+    [vector of 16 ubyte].
+ 
+ 2. Pointers to the types listed in (1).
+ 
+ In particular, this means you must block all loops manually on the
+ correct vector length.  I do not yet have a pass that will take
+ variable (long) vectors and block them to fixed vectors.
+ 
+ I have not tried to make arrays of vectors, put vectors in structs,
+ etc.  Such code may work, but I haven't tried it.  Any other vector
+ types (e.g., [vector of int] or [vector of 8 int]) will cause the
+ writers to break.  Any legal LLVM type with no vectors in it is, of
+ course, allowed, and will be handled by the normal C backend.
+ 
+ If your code is written with the types listed above only, and uses
+ patterns that the -altivec or -sse pass recognizes (as discussed
+ below), then it should go through the writer and produce correct code.
+ However, if your vector code uses patterns of operations that -altivec
+ or -sse passes cannot recognize, these passes can introduce types that
+ will break the writers.
+ 
+ Instructions
+ ------------
+ 
+ fixed vimm
+ 
+ You should be able to use any fixed vimm instruction with AltiVec or
+ SSE, so long as it generates one of the types listed above.  Variable
+ vimm will not work.  For AltiVec, a fixed vimm instruction becomes
+ either a cast (in the case of a constant) or an altivec_splat
+ intrinsic (in the case of a nonconstant).  For SSE, a fixed vimm
+ becomes an _mm_splat macro, which expands to a _mm_set intrinsic.
+ 
+ extract
+ 
+ The AltiVec backend will convert the following pattern
+ 
+    %lo = extract [vector of 16 sbyte] %val, uint 0, uint 1, uint 8
+    %hi = extract [vecotr of 16 sbyte] %val, uint 8, uint 1, uint 8
+    %unpklo = cast [vector of 16 sbyte] %lo to [vector of short]
+    %unpkhi = cast [vector of 16 sbyte] %hi to [vector of short]
+ 
+ to the altivec_unpack_lo and altivec_unpack_hi intrinsics.  This only
+ works for the types stated above, and it only works on AltiVec.
+ 
+ combine
+ 
+ vselect
+ 
+ vsetcc
+ 


Index: llvm/docs/VectorCReference.txt
diff -c /dev/null llvm/docs/VectorCReference.txt:1.1.2.1
*** /dev/null	Fri Oct 21 16:33:25 2005
--- llvm/docs/VectorCReference.txt	Fri Oct 21 16:33:13 2005
***************
*** 0 ****
--- 1,439 ----
+ VECTOR C REFERENCE
+ Vector LLVM
+ Rob Bocchino
+ October 20, 2005
+ ==================
+ 
+ Overview
+ ========
+ 
+ Vector C is an API that allows you to embed Vector LLVM instructions
+ in a C program compiled through llvm-gcc.  (Without this API, we would
+ have to either write all the Vector LLVM by hand, or extend llvm-gcc
+ itself to support Vector LLVM.)  The API is similar to the APIs for
+ AltiVec and SSE provided by gcc.  It provides a set of C functions,
+ each of which corresponds to one or more (but at most a few) LLVM
+ values (usually instructions).  The C functions are compiled to LLVM
+ functions by llvm-gcc, then converted to Vector LLVM instructions by
+ an LLVM transformation pass, opt -raisevectors.
+ 
+ Using the API
+ =============
+ 
+ Let $(LLVMSRCDIR) equal the root of your LLVM source tree.  To use the
+ API, put $(LLVMSRCDIR)/include/VectorC in your include path and put
+ #include "VectorC.h" in your source file.  Write the program as
+ directed in the next section.  Compile your program through llvm-gcc
+ to generate a bytecode file, say foo.vectorc.bc.  Run the program
+ through opt -raisevectors (i.e., opt -raisevectors < foo.vectorc.bc >
+ foo.raised.bc).  The result will be a program with the Vector C
+ functions replaced by the corresponding Vector LLVM instructions.  The
+ raisevectors transformation is defined in
+ $(LLVMSRCDIR)/lib/Transforms/RaiseVector.cpp.
+ 
+ Writing Vector C Programs
+ =========================
+ 
+ Writing Vector C code consists of writing vector source values (vector
+ loads or constants), using those values in vector operations, using
+ those uses in operations, etc., and finally storing values to memory.
+ Vector values are represented in C as scalar types and raised to
+ vectors in the LLVM representation according to the following simple
+ rule: a value is raised to a vector if and only if it is produced by a
+ Vector C function or at least one of its operands must be raised to a
+ vector.  In vector LLVM, a vector type consists of an element type and
+ (for fixed vectors) a length.  The element type is provided by the C
+ scalar type declaration.  The programmer must supply the vector length
+ explicitly for vector loads, vector immediates, and fixed combine
+ instructions.  Otherwise, the raise pass can infer the vector length
+ of the result (or the fact that the vector is variable, and has no
+ explicit length) from the length of the operands; the programmer need
+ only supply the scalar type.
+ 
+ For example, consider the following C code, which uses fixed vectors:
+ 
+     short x_vec = vllvm_load_short(x, 8, i);
+     short y_vec = vllvm_load_short(y, 8, i);
+     short a_vec = vllvm_fixed_vimm_short(a, 8);
+     short z_vec = a_vec * x_vec + y_vec;
+     vllvm_store_short(z_vec, z, i);
+ 
+ The raise pass produces the following Vector LLVM code:
+ 
+     %tmp0 = cast short* %x to [vector of 8 short]
+     %tmp1 = getelementptr [vector of 8 short]* %tmp0, int %i
+     %x_vec = load [vector of 8 short]* %tmp1
+     %tmp2 = cast short *%y to [vector of 8 short]
+     %tmp3 = getelementptr [vector of 8 short]* %tmp2, int %i
+     %y_vec = load [vector of 8 short]* %tmp3
+     %a_vec = fixed vimm short %a, uint 8
+     %tmp4 = mul [vector of 8 short] %x_vec, %a_vec
+     %z_vec = add [vector of 8 short] %tmp4, %y_vec
+     %tmp6 = cast short* %z to [vector of 8 short]*
+     %tmp7 = getelementptr [vector of 8 short]* %cast1, int %i
+     store [vector of 8 short] %z_vec, [vector of 8 short]* %tmp7
+ 
+ The type [vector of 8 short] is specified explicitly for the load and
+ vimm instructions (through the C type short and the argument 8), and
+ propagated to the other instructions by the chain of defs and uses.
+ 
+ Note that the vector source values must all be Vector C functions, but
+ the operations may be either Vector C functions or normal scalar C
+ operations (as in the above example, where we have used the normal C
+ operators * and +).  In the case of normal C operations, the raise
+ pass will see that the operands are vectors and raise the operation to
+ a vector operation.  It is illegal, however, to attempt to combine
+ scalar and vector values.  For example, the following would be
+ illegal:
+ 
+     short x_vec = vllvm_load_short(x, 8, i);
+     short y_vec = 2 * x_vec;
+ 
+ Instead, we must write
+ 
+     short x_vec = vllvm_load_short(x, 8, i);
+     short y_vec = vllvm_vimm_short(2, 8) * x_vec;
+ 
+ Note also that the types must match.  If we write
+ 
+     short x_vec = vllvm_load_short(x, 8, i);
+     short y_vec = vllvm_vimm_short(2, 16) * x_vec;
+ 
+ then the raise pass will crash horribly.
+ 
+ API Reference
+ =============
+ 
+ The following reference describes the functions making up the Vector C
+ API.  It uses the following conventions:
+ 
+  * CTYPE is one of the C scalar types { char, unsigned uchar (uchar),
+    short, unsigned short (ushort), int, unsigned int (uint), long,
+    unsigned long (ulong), float, double }, where the types in
+    parentheses are optional shorter forms (defined via typedef).
+ 
+  * LLVMTYPE is one of { sbyte, ubyte, short, ushort, int, uint, long,
+    ulong, float, double }.
+ 
+  * If CTYPE is the nth C type listed above, then LLVMTYPE is the nth
+    LLVM type listed above.
+ 
+  * CTYPE~ means CTYPE with any spaces replaced by _.  For instance, if
+    CTYPE = unsigned int, then CTYPE~ = unsigned_int.  Note that for
+    the shorter forms (such as uint), CTYPE~ = CTYPE.  The shorter
+    forms are also easier to type and help the API function names from
+    getting unduly long.
+ 
+ All function declarations in the API follow the pattern
+ vllvm_OP-NAME_CTYPE~, where FN-NAME is the name of the operation
+ (which usually corresponds to a Vector LLVM instruction or intrinsic).
+ 
+ vllvm_vimm_CTYPE~
+ -----------------
+ 
+ Purpose: Produce a vimm instruction
+ 
+ C Declaration: CTYPE vllvm_vimm_CTYPE~(CTYPE, uint)
+ 
+ C Use: CTYPE res = vllvm_vimm_CTYPE~(val, len)
+ 
+ Raised To: %res = vimm LLVMTYPE %val, uint len
+ 
+ Notes: vllvm_vloadi_CTYPE~ is also allowed, for compatibility with an
+        older form of this instruction.
+ 
+ vllvm_fixed_vimm_CTYPE~
+ -----------------------
+ 
+ Purpose: Produce a fixed vimm instruction
+ 
+ C Declaration:  CTYPE vllvm_fixed_vimm_CTYPE~(CTYPE val, uint len)
+ 
+ C Use:  CTYPE res = vllvm_fixed_vimm_CTYPE~(val, len)
+ 
+ Raised To:  %res = fixed vimm LLVMTYPE %val, uint %len
+ 
+ Notes: len must be a constant, otherwise the raise pass will crash.
+ 
+ vllvm_vgather_CTYPE~
+ --------------------
+ 
+ Purpose: Produce a vgather instruction
+ 
+ C Declaration:  CTYPE vllvm_vgather_CTYPE~(const CTYPE*, ...)
+ 
+ C Use:  CTYPE res = vllvm_vgather_CTYPE~(ptr, start, end, stride, mult)
+ 
+ Raised To: %res = vgather LLVMTYPE* %ptr, long %start, long %end, long
+              %stride, long %mult
+ 
+ Notes:  An arbitrary number of (start, end, stride, mult) groups are
+         allowed, and the values must be integers.  If the arguments do
+         not follow this pattern, the raise pass will crash.
+ 
+ 	vllvm_vload_CTYPE~ is also allowed, for compatibility with an
+ 	older form of this instruction.
+ 
+ vllvm_vscatter_CTYPE~
+ ---------------------
+ 
+ Purpose: Produce a vscatter instruction
+ 
+ C Declaration:  void vllvm_vscatter_CTYPE~(CTYPE, CTYPE*, ...)
+ 
+ C Use:  vllvm_vscatter_CTYPE~(val, ptr, start, end, stride, mult)
+ 
+ Raised To: vscatter [vector of LLVMTYPE] %val, LLVMTYPE* %ptr, long
+              %start, long %end, long %stride, long %mult
+ 	
+ Notes:  An arbitrary number of (start, end, stride, mult) groups are
+         allowed, and the values must be integers.  If the arguments do
+         not follow this pattern, the raise pass will crash.
+ 
+ 	vllvm_vstore_CTYPE~ is also allowed, for compatibility with an
+ 	older form of this instruction.
+ 
+ vllvm_load_CTYPE~
+ -----------------
+ 
+ Purpose: Produce a vector load instruction for a specified pointer and
+          offset.
+ 
+ C Declaration: CTYPE vllvm_load_CTYPE~(const CTYPE*, uint, int)
+ 
+ C Use: CTYPE res = vllvm_load_CTYPE~(ptr, len, idx)
+ 
+ Raised To: %tmp0 = cast LLVMTYPE* %ptr to [vector of len LLVMTYPE]*
+ 	   %tmp1 = getelementptr [vector of len LLVMTYPE]* %tmp0, 
+   	     int %idx
+ 	   %res = load [vector of len LLVMTYPE]* %tmp1
+ 
+ vllvm_store_CTYPE~
+ ------------------
+ 
+ Purpose: Produce a vector store instruction for a specified value,
+          pointer, and offset.
+ 
+ C Declaration: void vllvm_store_CTYPE~(CTYPE, CTYPE*, int)
+ 
+ C Use: vllvm_store_CTYPE~(val, ptr, idx)
+ 
+ Raised To: %tmp0 = cast LLVMTYPE* %ptr to [vector of len LLVMTYPE]*
+ 	   %tmp1 = getelementptr [vector of len LLVMTYPE]* %tmp0,
+ 	     int %idx 
+ 	   store LLVMTYPE %val, [vector of len LLVMTYPE]* %tmp1
+ 
+ vllvm_vselect_CTYPE~
+ --------------------
+ 
+ Purpose: Produce a vselect instruction.
+ 
+ C Declaration: CTYPE vllvm_vselect_CTYPE~(int, CTYPE, CTYPE)
+ 
+ C Use: CTYPE res = vllvm_vselect_CTYPE~(mask, val1, val2)
+ 
+ Raised To: %res = vselect [vector of bool] %mask, TY %val1, TY %val2
+ 
+            where TY = [vector of LLVMTYPE] or [vector of n LLVMTYPE],
+            and the type is inferred from the instructions producing
+            %val1 and %val2.
+ 
+ Notes: If %val1 and %val2 have incompatible lengths (i.e., are not
+        both variable vectors or both fixed vectors with the same
+        length), the raise pass will crash.
+ 
+ vllvm_extract_CTYPE~
+ --------------------
+ 
+ Purpose: Produce an extract instruction.
+ 
+ C Declaration: CTYPE vllvm_extract_CTYPE~(CTYPE, unsigned, unsigned,
+                unsigned)
+ 
+ C Use: CTYPE res = vllvm_extract_CTYPE~(val, start, stride, len)
+ 
+ Raised To: %res = extract TY %val, uint %start, uint %stride,
+            uint %len
+ 
+            where TY = [vector of LLVMTYPE] or [vector of n LLVMTYPE],
+            and the type is inferred from the instruction producing
+            %val
+ 
+ Notes: In Vector LLVM currently, the result type of the extract is a
+        fixed vector if and only if TY is a fixed vector and len is a
+        constant.  We will probably add a fixed extract (like fixed
+        vimm) and a corresponding vimm_fixed_extract_CTYPE~ function.
+ 
+ vllvm_combine_CTYPE~
+ --------------------
+ 
+ Purpose: Produce a combine instruction of variable vector type.
+ 
+ C Declaration: CTYPE vllvm_combine_CTYPE~(CTYPE, CTYPE, unsigned,
+                unsigned)
+ 
+ C Use: CTYPE res = vllvm_combine_CTYPE~(val1, val2, start, stride)
+ 
+ Raised To: %res = combine [vector of LLVMTYPE] %val1, [vector of
+            LLVMTYPE] %val2, uint %start, uint %stride
+ 
+ Notes: %val1 and %val2 must be variable vectors; otherwise the raise
+        pass will crash.  For fixed vectors, use fixed_combine.
+ 
+ vllvm_fixed_combine_CTYPE~
+ --------------------------
+ 
+ Purpose: Produce a combine instruction of fixed vector type.
+ 
+ C Declaration: CTYPE vllvm_fixed_combine_CTYPE~(CTYPE, unsigned, CTYPE,
+                unsigned, unsigned, unsigned)
+ 
+ C Use: CTYPE res = vllvm_fixed_combine_CTYPE~(val1, len1, val2, len2,
+        start, stride)
+ 
+ Raised To: %res = combine [vector of len1 LLVMTYPE] %val1, [vector of
+            len2 LLVMTYPE] %val2, uint %start, uint %stride
+ 
+ 	   except that len1 and len2 may both be 0, in which case
+ 	   %val1 and %val2 are both raised to [vector of LLVMTYPE]
+ 	   (i.e., this function behaves like combine when len1 = len2
+ 	   = 0).
+ 
+ Notes: %val1 and %val2 must have compatible lengths, otherwise the
+        raise pass will crash
+ 
+ vllvm_extractelement_CTYPE~
+ ---------------------------
+ 
+ Purpose: Produce an extractelement instruction.
+ 
+ C Declaration: CTYPE vllvm_extractelement_CTYPE~(CTYPE, unsigned)
+ 
+ C Use: CTYPE res = vllvm_extractelement_CTYPE~(val, idx)
+ 
+ Raised To: %res = extractelement TY %val, uint idx
+ 
+            where TY = [vector of LLVMTYPE] or [vector of n LLVMTYPE],
+            depending on the type to which %val is raised
+ 
+ vllvm_combineelement_CTYPE~
+ ---------------------------
+ 
+ Purpose: Produce a combineelement instruction.
+ 
+ C Declaration: CTYPE vllvm_combineelement_CTYPE~(CTYPE, CTYPE,
+                unsigned)
+ 
+ C Use: CTYPE res = vllvm_combineelement_CTYPE~(val, elt, idx)
+ 
+ Raised To: %res = combineelement TY %val, LLVMTYPE elt, uint idx
+ 
+            where TY = [vector of LLVMTYPE] or [vector of n LLVMTYPE],
+            depending on the type to which %val is raised
+ 
+ vllvm_constant_CTYPE~
+ ---------------------
+ 
+ Purpose: Produce a vector constant.
+ 
+ C Declaration: CTYPE vllvm_constant_CTYPE~(CTYPE,...)
+ 
+ C Use: vllvm_constant_CTYPE~(val1, val2, ... valn)
+ 
+ Raised To: <val1, val2, ..., valn>
+ 
+ vllvm_permute_CTYPE~
+ --------------------
+ 
+ Purpose: Produce a permute intrinsic with variable vector type.
+ 
+ C Declaration: CTYPE vllvm_permute_CTYPE~(CTYPE, unsigned,
+                CTYPE, unsigned)
+ 
+ C Use: CTYPE res = vllvm_permute_CTYPE~(val, val_len, idx,
+        idx_len)
+ 
+ Raised To: %res = call %permute_CTYPE~_vector([vector of LLVMTYPE]
+            %val, [vector of LLVMTYPE] %idx)
+ 
+ Notes: This function is raised to an LLVM function with vector
+        arguments (rather than an LLVM instruction) because there is
+        not yet an LLVM instruction for permute.
+ 
+ vllvm_fixed_permute_CTYPE~
+ --------------------------
+ 
+ Purpose: Produce a permute intrinsic with fixed vector type.
+ 
+ C Declaration: CTYPE vllvm_fixed_permute_CTYPE~(CTYPE, unsigned,
+                CTYPE, unsigned)
+ 
+ C Use: CTYPE res = vllvm_fixed_permute_CTYPE~(val, val_len, idx,
+        idx_len)
+ 
+ Raised To: %res = call %fixed_permute_CTYPE~_vector([vector of val_len
+            LLVMTYPE] %val, [vector of idx_len LLVMTYPE] %idx)
+ 
+ Notes: The result type is [vector of idx_len LLVMTYPE]
+ 
+        This function is raised to an LLVM function with vector
+        arguments (rather than an LLVM instruction) because there is
+        not yet an LLVM instruction for permute.
+ 
+ Extending the API
+ =================
+ 
+ The API is easy to extend in two ways:
+ 
+ 1. Add a new type for an existing Vector C function.  If your program
+    has renamed a scalar type foo (e.g. typedef foo int), and you want
+    to use the Vector C functions on vectors of foo, you can declare a
+    function vllvm_OP-NAME_foo, following the pattern given above for
+    OP-NAME.  As long as OP-NAME and the pattern of parameter types is
+    legal, the raise pass will correctly raise the function.  This is
+    useful, e.g., in media benchmarks, which often have
+    platform-specific typedefs for basic types.
+ 
+ 2. Add a new Vector C intrinsic.  vllvm_permute and
+    vllvm_fixed_permute provide examples of how to do this.  Simply
+    declare a function vllvm_NAME, where NAME is any intrinsic name you
+    want (and can include any type mangling, such as CTYPE~).  Whenever
+    this function is used with an argument that has been raised to a
+    vector type, the entire function will be raised to
+    vllvm_NAME_vector, with all non-constant arguments replaced by
+    vectors.  Constant arguments remain scalars.  Thus
+    vllvm_foo_int(int x, int y) is raised to
+ 
+ 	     %vllvm_foo_int_vector([vector of int] %x, [vector of int]
+ 	     %y)
+  
+    if called with arguments that are raised to [vector of int], while
+    it is raised to
+ 
+ 	     %vllvm_foo_int_vector([vector of int] %x, int %y)
+ 
+    if called with first argument that is raised to [vector of int] and
+    second argument a constant scalar.  The raise pass will break if a
+    vllvm_... function is called with one vector argument and another
+    variable argument that is not a vector, or if any function that
+    does not begin with vllvm_... is called with a vector argument.
+ 
+ Limitations
+ -----------
+ 
+  * You must run mem2reg (normally run automatically by llvm-gcc)
+    before the raise pass.  Any loads and stores of scalar values that
+    are to be raised (other than vector loads and stores indicated with
+    Vector C function calls) will break the pass.
+ 
+  * There is currently no way to represent passing vectors to functions
+    or returning vectors from functions in Vector C (although these
+    operations are supported in Vector LLVM).
+ 
+  * As indicated above, the raise pass is not very robust to errors.
+    It sometimes gives meaningful error messages, but mostly just
+    breaks when the Vector C program is incorrect.  For example, if the
+    two operands of an add instruction are raised to different vector
+    types, the raise pass will crash and assert something not
+    particularly helpful -- for instance, that an illegal add
+    instruction was created or illegal ReplaceAllUses was performed.






More information about the llvm-commits mailing list