Пример #1
0
/**
 * 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;
   }
}
Пример #2
0
static int llvm_type_index(LLVMTypeRef type)
{
  // LLVMDumpType(type);
  switch (LLVMGetTypeKind(type)) {
    case LLVMFloatTypeKind:
      return SCM_FOREIGN_TYPE_FLOAT;
    case LLVMDoubleTypeKind:
      return SCM_FOREIGN_TYPE_DOUBLE;
    case LLVMIntegerTypeKind:
      switch (LLVMGetIntTypeWidth(type)) {
        case 1:
          return SCM_FOREIGN_TYPE_BOOL;
        case 8:
          return SCM_FOREIGN_TYPE_INT8;
        case 16:
          return SCM_FOREIGN_TYPE_INT16;
        case 32:
          return SCM_FOREIGN_TYPE_INT32;
        case 64:
          return SCM_FOREIGN_TYPE_INT64;
        default:
          return SCM_FOREIGN_TYPE_VOID;
      };
    default:
      return SCM_FOREIGN_TYPE_VOID;
  };
}
Пример #3
0
/**
 * Given the i32 or vNi32 \p type, generate the textual name (e.g. for use with
 * intrinsic names).
 */
void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize)
{
	LLVMTypeRef elem_type = type;

	assert(bufsize >= 8);

	if (LLVMGetTypeKind(type) == LLVMVectorTypeKind) {
		int ret = snprintf(buf, bufsize, "v%u",
					LLVMGetVectorSize(type));
		if (ret < 0) {
			char *type_name = LLVMPrintTypeToString(type);
			fprintf(stderr, "Error building type name for: %s\n",
				type_name);
			return;
		}
		elem_type = LLVMGetElementType(type);
		buf += ret;
		bufsize -= ret;
	}
	switch (LLVMGetTypeKind(elem_type)) {
	default: break;
	case LLVMIntegerTypeKind:
		snprintf(buf, bufsize, "i%d", LLVMGetIntTypeWidth(elem_type));
		break;
	case LLVMFloatTypeKind:
		snprintf(buf, bufsize, "f32");
		break;
	case LLVMDoubleTypeKind:
		snprintf(buf, bufsize, "f64");
		break;
	}
}
Пример #4
0
/**
 * Print a LLVM value of any type
 */
LLVMValueRef
lp_build_print_value(struct gallivm_state *gallivm,
                     const char *msg,
                     LLVMValueRef value)
{
   LLVMBuilderRef builder = gallivm->builder;
   LLVMTypeKind type_kind;
   LLVMTypeRef type_ref;
   LLVMValueRef params[2 + LP_MAX_VECTOR_LENGTH];
   char type_fmt[4] = " %x";
   char format[2 + 3 * LP_MAX_VECTOR_LENGTH + 2] = "%s";
   unsigned length;
   unsigned i;

   type_ref = LLVMTypeOf(value);
   type_kind = LLVMGetTypeKind(type_ref);

   if (type_kind == LLVMVectorTypeKind) {
      length = LLVMGetVectorSize(type_ref);

      type_ref = LLVMGetElementType(type_ref);
      type_kind = LLVMGetTypeKind(type_ref);
   } else {
      length = 1;
   }

   if (type_kind == LLVMFloatTypeKind || type_kind == LLVMDoubleTypeKind) {
      type_fmt[2] = 'f';
   } else if (type_kind == LLVMIntegerTypeKind) {
      if (LLVMGetIntTypeWidth(type_ref) == 8) {
         type_fmt[2] = 'u';
      } else {
         type_fmt[2] = 'i';
      }
   } else {
      /* Unsupported type */
      assert(0);
   }

   /* Create format string and arguments */
   assert(strlen(format) + strlen(type_fmt) * length + 2 <= sizeof format);

   params[1] = lp_build_const_string(gallivm, msg);
   if (length == 1) {
      util_strncat(format, type_fmt, sizeof(format) - strlen(format) - 1);
      params[2] = value;
   } else {
      for (i = 0; i < length; ++i) {
         util_strncat(format, type_fmt, sizeof(format) - strlen(format) - 1);
         params[2 + i] = LLVMBuildExtractElement(builder, value, lp_build_const_int32(gallivm, i), "");
      }
   }

   util_strncat(format, "\n", sizeof(format) - strlen(format) - 1);

   params[0] = lp_build_const_string(gallivm, format);
   return lp_build_print_args(gallivm, 2 + length, params);
}
Пример #5
0
static LLVMValueRef gen_digestof_value(compile_t* c, LLVMValueRef value)
{
  LLVMTypeRef type = LLVMTypeOf(value);

  switch(LLVMGetTypeKind(type))
  {
    case LLVMFloatTypeKind:
      value = LLVMBuildBitCast(c->builder, value, c->i32, "");
      return LLVMBuildZExt(c->builder, value, c->i64, "");

    case LLVMDoubleTypeKind:
      return LLVMBuildBitCast(c->builder, value, c->i64, "");

    case LLVMIntegerTypeKind:
    {
      uint32_t width = LLVMGetIntTypeWidth(type);

      if(width < 64)
      {
        value = LLVMBuildZExt(c->builder, value, c->i64, "");
      } else if(width == 128) {
        LLVMValueRef shift = LLVMConstInt(c->i128, 64, false);
        LLVMValueRef high = LLVMBuildLShr(c->builder, value, shift, "");
        high = LLVMBuildTrunc(c->builder, high, c->i64, "");
        value = LLVMBuildTrunc(c->builder, value, c->i64, "");
        value = LLVMBuildXor(c->builder, value, high, "");
      }

      return value;
    }

    case LLVMStructTypeKind:
    {
      uint32_t count = LLVMCountStructElementTypes(type);
      LLVMValueRef result = LLVMConstInt(c->i64, 0, false);

      for(uint32_t i = 0; i < count; i++)
      {
        LLVMValueRef elem = LLVMBuildExtractValue(c->builder, value, i, "");
        elem = gen_digestof_value(c, elem);
        result = LLVMBuildXor(c->builder, result, elem, "");
      }

      return result;
    }

    case LLVMPointerTypeKind:
      return LLVMBuildPtrToInt(c->builder, value, c->i64, "");

    default: {}
  }

  assert(0);
  return NULL;
}
Пример #6
0
/**
 * Print an LLVMTypeRef.  Like LLVMDumpValue().  For debugging.
 */
void
lp_dump_llvmtype(LLVMTypeRef t)
{
   LLVMTypeKind k = LLVMGetTypeKind(t);

   if (k == LLVMVectorTypeKind) {
      LLVMTypeRef te = LLVMGetElementType(t);
      LLVMTypeKind ke = LLVMGetTypeKind(te);
      unsigned len = LLVMGetVectorSize(t);
      if (ke == LLVMIntegerTypeKind) {
         unsigned b = LLVMGetIntTypeWidth(te);
         debug_printf("Vector [%u] of %u-bit Integer\n", len, b);
      }
      else {
         debug_printf("Vector [%u] of %s\n", len, lp_typekind_name(ke));
      }
   }
   else if (k == LLVMArrayTypeKind) {
      LLVMTypeRef te = LLVMGetElementType(t);
      LLVMTypeKind ke = LLVMGetTypeKind(te);
      unsigned len = LLVMGetArrayLength(t);
      debug_printf("Array [%u] of %s\n", len, lp_typekind_name(ke));
   }
   else if (k == LLVMIntegerTypeKind) {
      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));
   }
}
Пример #7
0
/**
 * This function is a mirror of lp_build_elem_type() above.
 *
 * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
 * type and check for identity.
 */
boolean
lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type) 
{
   LLVMTypeKind elem_kind;

   assert(elem_type);
   if(!elem_type)
      return FALSE;

   elem_kind = LLVMGetTypeKind(elem_type);

   if (type.floating) {
      switch(type.width) {
      case 16:
         if(elem_kind != LLVMIntegerTypeKind)
            return FALSE;
         break;
      case 32:
         if(elem_kind != LLVMFloatTypeKind)
            return FALSE;
         break;
      case 64:
         if(elem_kind != LLVMDoubleTypeKind)
            return FALSE;
         break;
      default:
         assert(0);
         return FALSE;
      }
   }
   else {
      if(elem_kind != LLVMIntegerTypeKind)
         return FALSE;

      if(LLVMGetIntTypeWidth(elem_type) != type.width)
         return FALSE;
   }

   return TRUE; 
}
Пример #8
0
void
lp_format_intrinsic(char *name,
                    size_t size,
                    const char *name_root,
                    LLVMTypeRef type)
{
   unsigned length = 0;
   unsigned width;
   char c;

   LLVMTypeKind kind = LLVMGetTypeKind(type);
   if (kind == LLVMVectorTypeKind) {
      length = LLVMGetVectorSize(type);
      type = LLVMGetElementType(type);
      kind = LLVMGetTypeKind(type);
   }

   switch (kind) {
   case LLVMIntegerTypeKind:
      c = 'i';
      width = LLVMGetIntTypeWidth(type);
      break;
   case LLVMFloatTypeKind:
      c = 'f';
      width = 32;
      break;
   case LLVMDoubleTypeKind:
      c = 'f';
      width = 64;
      break;
   default:
      unreachable("unexpected LLVMTypeKind");
   }

   if (length) {
      util_snprintf(name, size, "%s.v%u%c%u", name_root, length, c, width);
   } else {
      util_snprintf(name, size, "%s.%c%u", name_root, c, width);
   }
}
Пример #9
0
static LLVMValueRef gen_digestof_value(compile_t* c, ast_t* type,
  LLVMValueRef value)
{
  LLVMTypeRef impl_type = LLVMTypeOf(value);

  switch(LLVMGetTypeKind(impl_type))
  {
    case LLVMFloatTypeKind:
      value = LLVMBuildBitCast(c->builder, value, c->i32, "");
      return LLVMBuildZExt(c->builder, value, c->intptr, "");

    case LLVMDoubleTypeKind:
      value = LLVMBuildBitCast(c->builder, value, c->i64, "");
      return gen_digestof_int64(c, value);

    case LLVMIntegerTypeKind:
    {
      uint32_t width = LLVMGetIntTypeWidth(impl_type);

      if(width < 64)
      {
        return LLVMBuildZExt(c->builder, value, c->intptr, "");
      } else if(width == 64) {
        return gen_digestof_int64(c, value);
      } else if(width == 128) {
        LLVMValueRef shift = LLVMConstInt(c->i128, 64, false);
        LLVMValueRef high = LLVMBuildLShr(c->builder, value, shift, "");
        high = LLVMBuildTrunc(c->builder, high, c->i64, "");
        value = LLVMBuildTrunc(c->builder, value, c->i64, "");
        high = gen_digestof_int64(c, high);
        value = gen_digestof_int64(c, value);
        return LLVMBuildXor(c->builder, value, high, "");
      }
      break;
    }

    case LLVMStructTypeKind:
    {
      uint32_t count = LLVMCountStructElementTypes(impl_type);
      LLVMValueRef result = LLVMConstInt(c->intptr, 0, false);
      ast_t* child = ast_child(type);

      for(uint32_t i = 0; i < count; i++)
      {
        LLVMValueRef elem = LLVMBuildExtractValue(c->builder, value, i, "");
        elem = gen_digestof_value(c, child, elem);
        result = LLVMBuildXor(c->builder, result, elem, "");
        child = ast_sibling(child);
      }

      pony_assert(child == NULL);

      return result;
    }

    case LLVMPointerTypeKind:
      if(!is_known(type))
      {
        reach_type_t* t = reach_type(c->reach, type);
        int sub_kind = subtype_kind(t);

        if((sub_kind & SUBTYPE_KIND_BOXED) != 0)
          return gen_digestof_box(c, t, value, sub_kind);
      }

      return LLVMBuildPtrToInt(c->builder, value, c->intptr, "");

    default: {}
  }

  pony_assert(0);
  return NULL;
}