[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