1 /**************************************************************************
3 * Copyright 2009 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 #include "util/u_debug.h"
31 #include "lp_bld_type.h"
32 #include "lp_bld_const.h"
33 #include "lp_bld_init.h"
37 lp_build_elem_type(struct gallivm_state
*gallivm
, struct lp_type type
)
42 return LLVMIntTypeInContext(gallivm
->context
, 16);
45 return LLVMFloatTypeInContext(gallivm
->context
);
48 return LLVMDoubleTypeInContext(gallivm
->context
);
52 return LLVMFloatTypeInContext(gallivm
->context
);
56 return LLVMIntTypeInContext(gallivm
->context
, type
.width
);
62 lp_build_vec_type(struct gallivm_state
*gallivm
,struct lp_type type
)
64 LLVMTypeRef elem_type
= lp_build_elem_type(gallivm
, type
);
68 return LLVMVectorType(elem_type
, type
.length
);
73 * This function is a mirror of lp_build_elem_type() above.
75 * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
76 * type and check for identity.
79 lp_check_elem_type(struct lp_type type
, LLVMTypeRef elem_type
)
81 LLVMTypeKind elem_kind
;
87 elem_kind
= LLVMGetTypeKind(elem_type
);
92 if(elem_kind
!= LLVMIntegerTypeKind
)
96 if(elem_kind
!= LLVMFloatTypeKind
)
100 if(elem_kind
!= LLVMDoubleTypeKind
)
109 if(elem_kind
!= LLVMIntegerTypeKind
)
112 if(LLVMGetIntTypeWidth(elem_type
) != type
.width
)
121 lp_check_vec_type(struct lp_type type
, LLVMTypeRef vec_type
)
123 LLVMTypeRef elem_type
;
129 if (type
.length
== 1)
130 return lp_check_elem_type(type
, vec_type
);
132 if(LLVMGetTypeKind(vec_type
) != LLVMVectorTypeKind
)
135 if(LLVMGetVectorSize(vec_type
) != type
.length
)
138 elem_type
= LLVMGetElementType(vec_type
);
140 return lp_check_elem_type(type
, elem_type
);
145 lp_check_value(struct lp_type type
, LLVMValueRef val
)
147 LLVMTypeRef vec_type
;
153 vec_type
= LLVMTypeOf(val
);
155 return lp_check_vec_type(type
, vec_type
);
160 lp_build_int_elem_type(struct gallivm_state
*gallivm
, struct lp_type type
)
162 return LLVMIntTypeInContext(gallivm
->context
, type
.width
);
167 lp_build_int_vec_type(struct gallivm_state
*gallivm
, struct lp_type type
)
169 LLVMTypeRef elem_type
= lp_build_int_elem_type(gallivm
, type
);
170 if (type
.length
== 1)
173 return LLVMVectorType(elem_type
, type
.length
);
178 * Create element of vector type
181 lp_elem_type(struct lp_type type
)
183 struct lp_type res_type
;
185 assert(type
.length
> 1);
194 * Create unsigned integer type variation of given type.
197 lp_uint_type(struct lp_type type
)
199 struct lp_type res_type
;
201 assert(type
.length
<= LP_MAX_VECTOR_LENGTH
);
202 memset(&res_type
, 0, sizeof res_type
);
203 res_type
.width
= type
.width
;
204 res_type
.length
= type
.length
;
211 * Create signed integer type variation of given type.
214 lp_int_type(struct lp_type type
)
216 struct lp_type res_type
;
218 assert(type
.length
<= LP_MAX_VECTOR_LENGTH
);
219 memset(&res_type
, 0, sizeof res_type
);
220 res_type
.width
= type
.width
;
221 res_type
.length
= type
.length
;
229 * Return the type with twice the bit width (hence half the number of elements).
232 lp_wider_type(struct lp_type type
)
234 struct lp_type res_type
;
236 memcpy(&res_type
, &type
, sizeof res_type
);
238 res_type
.length
/= 2;
240 assert(res_type
.length
);
247 * Return the size of the LLVMType in bits.
248 * XXX this function doesn't necessarily handle all LLVM types.
251 lp_sizeof_llvm_type(LLVMTypeRef t
)
253 LLVMTypeKind k
= LLVMGetTypeKind(t
);
256 case LLVMIntegerTypeKind
:
257 return LLVMGetIntTypeWidth(t
);
258 case LLVMFloatTypeKind
:
259 return 8 * sizeof(float);
260 case LLVMDoubleTypeKind
:
261 return 8 * sizeof(double);
262 case LLVMVectorTypeKind
:
264 LLVMTypeRef elem
= LLVMGetElementType(t
);
265 unsigned len
= LLVMGetVectorSize(t
);
266 return len
* lp_sizeof_llvm_type(elem
);
269 case LLVMArrayTypeKind
:
271 LLVMTypeRef elem
= LLVMGetElementType(t
);
272 unsigned len
= LLVMGetArrayLength(t
);
273 return len
* lp_sizeof_llvm_type(elem
);
277 assert(0 && "Unexpected type in lp_get_llvm_type_size()");
284 * Return string name for a LLVMTypeKind. Useful for debugging.
287 lp_typekind_name(LLVMTypeKind t
)
290 case LLVMVoidTypeKind
:
291 return "LLVMVoidTypeKind";
292 case LLVMFloatTypeKind
:
293 return "LLVMFloatTypeKind";
294 case LLVMDoubleTypeKind
:
295 return "LLVMDoubleTypeKind";
296 case LLVMX86_FP80TypeKind
:
297 return "LLVMX86_FP80TypeKind";
298 case LLVMFP128TypeKind
:
299 return "LLVMFP128TypeKind";
300 case LLVMPPC_FP128TypeKind
:
301 return "LLVMPPC_FP128TypeKind";
302 case LLVMLabelTypeKind
:
303 return "LLVMLabelTypeKind";
304 case LLVMIntegerTypeKind
:
305 return "LLVMIntegerTypeKind";
306 case LLVMFunctionTypeKind
:
307 return "LLVMFunctionTypeKind";
308 case LLVMStructTypeKind
:
309 return "LLVMStructTypeKind";
310 case LLVMArrayTypeKind
:
311 return "LLVMArrayTypeKind";
312 case LLVMPointerTypeKind
:
313 return "LLVMPointerTypeKind";
314 case LLVMVectorTypeKind
:
315 return "LLVMVectorTypeKind";
316 case LLVMMetadataTypeKind
:
317 return "LLVMMetadataTypeKind";
319 return "unknown LLVMTypeKind";
325 * Print an LLVMTypeRef. Like LLVMDumpValue(). For debugging.
328 lp_dump_llvmtype(LLVMTypeRef t
)
330 LLVMTypeKind k
= LLVMGetTypeKind(t
);
332 if (k
== LLVMVectorTypeKind
) {
333 LLVMTypeRef te
= LLVMGetElementType(t
);
334 LLVMTypeKind ke
= LLVMGetTypeKind(te
);
335 unsigned len
= LLVMGetVectorSize(t
);
336 if (ke
== LLVMIntegerTypeKind
) {
337 unsigned b
= LLVMGetIntTypeWidth(te
);
338 debug_printf("Vector [%u] of %u-bit Integer\n", len
, b
);
341 debug_printf("Vector [%u] of %s\n", len
, lp_typekind_name(ke
));
344 else if (k
== LLVMArrayTypeKind
) {
345 LLVMTypeRef te
= LLVMGetElementType(t
);
346 LLVMTypeKind ke
= LLVMGetTypeKind(te
);
347 unsigned len
= LLVMGetArrayLength(t
);
348 debug_printf("Array [%u] of %s\n", len
, lp_typekind_name(ke
));
350 else if (k
== LLVMIntegerTypeKind
) {
351 unsigned b
= LLVMGetIntTypeWidth(t
);
352 debug_printf("%u-bit Integer\n", b
);
354 else if (k
== LLVMPointerTypeKind
) {
355 LLVMTypeRef te
= LLVMGetElementType(t
);
356 debug_printf("Pointer to ");
357 lp_dump_llvmtype(te
);
360 debug_printf("%s\n", lp_typekind_name(k
));
366 lp_build_context_init(struct lp_build_context
*bld
,
367 struct gallivm_state
*gallivm
,
370 bld
->gallivm
= gallivm
;
373 bld
->int_elem_type
= lp_build_int_elem_type(gallivm
, type
);
375 bld
->elem_type
= lp_build_elem_type(gallivm
, type
);
377 bld
->elem_type
= bld
->int_elem_type
;
379 if (type
.length
== 1) {
380 bld
->int_vec_type
= bld
->int_elem_type
;
381 bld
->vec_type
= bld
->elem_type
;
384 bld
->int_vec_type
= LLVMVectorType(bld
->int_elem_type
, type
.length
);
385 bld
->vec_type
= LLVMVectorType(bld
->elem_type
, type
.length
);
388 bld
->undef
= LLVMGetUndef(bld
->vec_type
);
389 bld
->zero
= LLVMConstNull(bld
->vec_type
);
390 bld
->one
= lp_build_one(gallivm
, type
);
395 * Count the number of instructions in a function.
398 lp_build_count_instructions(LLVMValueRef function
)
400 unsigned num_instrs
= 0;
401 LLVMBasicBlockRef block
;
403 block
= LLVMGetFirstBasicBlock(function
);
406 instr
= LLVMGetFirstInstruction(block
);
410 instr
= LLVMGetNextInstruction(instr
);
412 block
= LLVMGetNextBasicBlock(block
);
420 * Count the number of instructions in a module.
423 lp_build_count_ir_module(LLVMModuleRef module
)
426 unsigned num_instrs
= 0;
428 func
= LLVMGetFirstFunction(module
);
430 num_instrs
+= lp_build_count_instructions(func
);
431 func
= LLVMGetNextFunction(func
);