#include "lp_bld_type.h"
#include "lp_bld_const.h"
+#include "lp_bld_init.h"
LLVMTypeRef
-lp_build_elem_type(struct lp_type type)
+lp_build_elem_type(struct gallivm_state *gallivm, struct lp_type type)
{
if (type.floating) {
switch(type.width) {
+ case 16:
+ return LLVMIntTypeInContext(gallivm->context, 16);
+ break;
case 32:
- return LLVMFloatType();
+ return LLVMFloatTypeInContext(gallivm->context);
break;
case 64:
- return LLVMDoubleType();
+ return LLVMDoubleTypeInContext(gallivm->context);
break;
default:
assert(0);
- return LLVMFloatType();
+ return LLVMFloatTypeInContext(gallivm->context);
}
}
else {
- return LLVMIntType(type.width);
+ return LLVMIntTypeInContext(gallivm->context, type.width);
}
}
LLVMTypeRef
-lp_build_vec_type(struct lp_type type)
+lp_build_vec_type(struct gallivm_state *gallivm,struct lp_type type)
{
- LLVMTypeRef elem_type = lp_build_elem_type(type);
+ LLVMTypeRef elem_type = lp_build_elem_type(gallivm, type);
if (type.length == 1)
return elem_type;
else
if (type.floating) {
switch(type.width) {
+ case 16:
+ if(elem_kind != LLVMIntegerTypeKind)
+ return FALSE;
+ break;
case 32:
if(elem_kind != LLVMFloatTypeKind)
return FALSE;
LLVMTypeRef
-lp_build_int_elem_type(struct lp_type type)
+lp_build_int_elem_type(struct gallivm_state *gallivm, struct lp_type type)
{
- return LLVMIntType(type.width);
+ return LLVMIntTypeInContext(gallivm->context, type.width);
}
LLVMTypeRef
-lp_build_int_vec_type(struct lp_type type)
+lp_build_int_vec_type(struct gallivm_state *gallivm, struct lp_type type)
{
- LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+ LLVMTypeRef elem_type = lp_build_int_elem_type(gallivm, type);
if (type.length == 1)
return elem_type;
else
/**
- * Build int32[4] vector type
+ * Create element of vector type
*/
-LLVMTypeRef
-lp_build_int32_vec4_type(void)
+struct lp_type
+lp_elem_type(struct lp_type type)
{
- struct lp_type t;
- LLVMTypeRef type;
-
- memset(&t, 0, sizeof(t));
- t.floating = FALSE; /* floating point values */
- t.sign = TRUE; /* values are signed */
- t.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */
- t.width = 32; /* 32-bit int */
- t.length = 4; /* 4 elements per vector */
-
- type = lp_build_int_elem_type(t);
- return LLVMVectorType(type, t.length);
+ struct lp_type res_type;
+
+ assert(type.length > 1);
+ res_type = type;
+ res_type.length = 1;
+
+ return res_type;
}
{
struct lp_type res_type;
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
memset(&res_type, 0, sizeof res_type);
res_type.width = type.width;
res_type.length = type.length;
{
struct lp_type res_type;
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
memset(&res_type, 0, sizeof res_type);
res_type.width = type.width;
res_type.length = type.length;
}
+/**
+ * Return the size of the LLVMType in bits.
+ * XXX this function doesn't necessarily handle all LLVM types.
+ */
+unsigned
+lp_sizeof_llvm_type(LLVMTypeRef t)
+{
+ LLVMTypeKind k = LLVMGetTypeKind(t);
+
+ switch (k) {
+ case LLVMIntegerTypeKind:
+ return LLVMGetIntTypeWidth(t);
+ case LLVMFloatTypeKind:
+ return 8 * sizeof(float);
+ case LLVMDoubleTypeKind:
+ return 8 * sizeof(double);
+ case LLVMVectorTypeKind:
+ {
+ LLVMTypeRef elem = LLVMGetElementType(t);
+ unsigned len = LLVMGetVectorSize(t);
+ return len * lp_sizeof_llvm_type(elem);
+ }
+ break;
+ case LLVMArrayTypeKind:
+ {
+ LLVMTypeRef elem = LLVMGetElementType(t);
+ unsigned len = LLVMGetArrayLength(t);
+ return len * lp_sizeof_llvm_type(elem);
+ }
+ break;
+ default:
+ assert(0 && "Unexpected type in lp_get_llvm_type_size()");
+ return 0;
+ }
+}
+
+
/**
* Return string name for a LLVMTypeKind. Useful for debugging.
*/
return "LLVMArrayTypeKind";
case LLVMPointerTypeKind:
return "LLVMPointerTypeKind";
- case LLVMOpaqueTypeKind:
- return "LLVMOpaqueTypeKind";
case LLVMVectorTypeKind:
return "LLVMVectorTypeKind";
case LLVMMetadataTypeKind:
return "LLVMMetadataTypeKind";
- /* Only in LLVM 2.7 and later???
- case LLVMUnionTypeKind:
- return "LLVMUnionTypeKind";
- */
default:
return "unknown LLVMTypeKind";
}
unsigned b = LLVMGetIntTypeWidth(t);
debug_printf("%u-bit Integer\n", b);
}
+ else if (k == LLVMPointerTypeKind) {
+ LLVMTypeRef te = LLVMGetElementType(t);
+ debug_printf("Pointer to ");
+ lp_dump_llvmtype(te);
+ }
else {
debug_printf("%s\n", lp_typekind_name(k));
}
void
lp_build_context_init(struct lp_build_context *bld,
- LLVMBuilderRef builder,
+ struct gallivm_state *gallivm,
struct lp_type type)
{
- bld->builder = builder;
+ bld->gallivm = gallivm;
bld->type = type;
- bld->undef = lp_build_undef(type);
- bld->zero = lp_build_zero(type);
- bld->one = lp_build_one(type);
+
+ bld->int_elem_type = lp_build_int_elem_type(gallivm, type);
+ if (type.floating)
+ bld->elem_type = lp_build_elem_type(gallivm, type);
+ else
+ bld->elem_type = bld->int_elem_type;
+
+ if (type.length == 1) {
+ bld->int_vec_type = bld->int_elem_type;
+ bld->vec_type = bld->elem_type;
+ }
+ else {
+ bld->int_vec_type = LLVMVectorType(bld->int_elem_type, type.length);
+ bld->vec_type = LLVMVectorType(bld->elem_type, type.length);
+ }
+
+ bld->undef = LLVMGetUndef(bld->vec_type);
+ bld->zero = LLVMConstNull(bld->vec_type);
+ bld->one = lp_build_one(gallivm, type);
+}
+
+
+/**
+ * Count the number of instructions in a function.
+ */
+static unsigned
+lp_build_count_instructions(LLVMValueRef function)
+{
+ unsigned num_instrs = 0;
+ LLVMBasicBlockRef block;
+
+ block = LLVMGetFirstBasicBlock(function);
+ while (block) {
+ LLVMValueRef instr;
+ instr = LLVMGetFirstInstruction(block);
+ while (instr) {
+ ++num_instrs;
+
+ instr = LLVMGetNextInstruction(instr);
+ }
+ block = LLVMGetNextBasicBlock(block);
+ }
+
+ return num_instrs;
+}
+
+
+/**
+ * Count the number of instructions in a module.
+ */
+unsigned
+lp_build_count_ir_module(LLVMModuleRef module)
+{
+ LLVMValueRef func;
+ unsigned num_instrs = 0;
+
+ func = LLVMGetFirstFunction(module);
+ while (func) {
+ num_instrs += lp_build_count_instructions(func);
+ func = LLVMGetNextFunction(func);
+ }
+ return num_instrs;
}