Esempio n. 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;
   }
}
Esempio n. 2
0
LLVMValueRef
lp_build_intrinsic_map(struct gallivm_state *gallivm,
                       const char *name,
                       LLVMTypeRef ret_type,
                       LLVMValueRef *args,
                       unsigned num_args)
{
   LLVMBuilderRef builder = gallivm->builder;
   LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type);
   unsigned n = LLVMGetVectorSize(ret_type);
   unsigned i, j;
   LLVMValueRef res;

   assert(num_args <= LP_MAX_FUNC_ARGS);

   res = LLVMGetUndef(ret_type);
   for(i = 0; i < n; ++i) {
      LLVMValueRef index = lp_build_const_int32(gallivm, i);
      LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS];
      LLVMValueRef res_elem;
      for(j = 0; j < num_args; ++j)
         arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, "");
      res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args, 0);
      res = LLVMBuildInsertElement(builder, res, res_elem, index, "");
   }

   return res;
}
Esempio n. 3
0
LLVMValueRef gen_name(struct node *ast)
{
	LLVMValueRef func, ptr, val;
	LLVMTypeRef type;

	ptr = lvalue(ast);
	type = LLVMTypeOf(ptr);

	if (LLVMGetTypeKind(type) == LLVMLabelTypeKind) {
		func = LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder));
		return LLVMBuildPtrToInt(builder,
				LLVMBlockAddress(func, (LLVMBasicBlockRef)ptr),
				TYPE_INT,
				"");
	}

	type = LLVMGetElementType(LLVMTypeOf(ptr));

	switch (LLVMGetTypeKind(type)) {
	case LLVMIntegerTypeKind:
		val = LLVMBuildLoad(builder, ptr, ast->val);

		if (LLVMIsAGlobalValue(ptr))
			val = LLVMBuildLShr(builder, val, CONST(WORDPOW), "");

		return val;

	default:
		generror("unexpected type '%s'", LLVMPrintTypeToString(type));
		return NULL;
	}
}
Esempio n. 4
0
File: Heap.c Progetto: YuKill/ftc
void registerHeap(SymbolTable *TyTable, LLVMContextRef Con) {
    char *Name, Buf[] = "struct.Heap", BufRA[] = "struct.RA";
    Name = (char*) malloc(strlen(Buf) * sizeof(char));
    strcpy(Name, Buf);

    RAType = symTableFindGlobal(TyTable, BufRA);

    HeapType = LLVMStructCreateNamed(Con, Name);
    symTableInsertGlobal(TyTable, Name, HeapType);

    LLVMTypeRef AttrTy[]  = {
        LLVMPointerType(RAType, 0),
        LLVMPointerType(HeapType, 0)
    };
    LLVMStructSetBody(HeapType, AttrTy, 2, 0);

    // Initializing Head of Heap.
    HeapHead = LLVMAddGlobal(Module, LLVMPointerType(HeapType, 0), "global.HeapHead");
    LLVMTypeRef HeapHeadConType = LLVMGetElementType(LLVMTypeOf(HeapHead));
    LLVMSetInitializer(HeapHead, LLVMConstPointerNull(HeapHeadConType));

    // Defining functions.
    createPushHeapFunction();
    createPopHeapFunction();
}
Esempio n. 5
0
unsigned
ac_count_scratch_private_memory(LLVMValueRef function)
{
	unsigned private_mem_vgprs = 0;

	/* Process all LLVM instructions. */
	LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(function);
	while (bb) {
		LLVMValueRef next = LLVMGetFirstInstruction(bb);

		while (next) {
			LLVMValueRef inst = next;
			next = LLVMGetNextInstruction(next);

			if (LLVMGetInstructionOpcode(inst) != LLVMAlloca)
				continue;

			LLVMTypeRef type = LLVMGetElementType(LLVMTypeOf(inst));
			/* No idea why LLVM aligns allocas to 4 elements. */
			unsigned alignment = LLVMGetAlignment(inst);
			unsigned dw_size = align(ac_get_type_size(type) / 4, alignment);
			private_mem_vgprs += dw_size;
		}
		bb = LLVMGetNextBasicBlock(bb);
	}

	return private_mem_vgprs;
}
Esempio n. 6
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;
	}
}
Esempio n. 7
0
static LLVMValueRef
translateRecordExpr(SymbolTable *TyTable, SymbolTable *ValTable, ASTNode *Node) {
  PtrVector *V = &(Node->Child);

  ASTNode *FieldNode = (ASTNode*) ptrVectorGet(V, 0);
  Type    *ThisType  = createType(IdTy, Node->Value);

  LLVMTypeRef RecordType = getLLVMTypeFromType(TyTable, ThisType);

  LLVMValueRef RecordVal = LLVMBuildMalloc(Builder, RecordType, "");
  unsigned FieldNumber   = LLVMCountStructElementTypes(RecordType),
           I;
  for (I = 0; I < FieldNumber; ++I) {
    LLVMValueRef ElemIdx[] = { getSConstInt(0), getSConstInt(I) };
    LLVMValueRef ElemI     = LLVMBuildInBoundsGEP(Builder, RecordVal, ElemIdx, 2, "");
    LLVMValueRef FieldPtr  = translateExpr(TyTable, ValTable, ptrVectorGet(&(FieldNode->Child), I));

    LLVMValueRef ValueFrom = NULL;
    switch (LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(FieldPtr)))) {
      case LLVMIntegerTypeKind:
      case LLVMFloatTypeKind:   ValueFrom = LLVMBuildLoad(Builder, FieldPtr, ""); break;
      case LLVMPointerTypeKind: ValueFrom = toDynamicMemory(FieldPtr); break;
      default: ValueFrom = FieldPtr;
    }
    LLVMBuildStore(Builder, ValueFrom, ElemI);
  }
  return RecordVal; 
}
Esempio n. 8
0
LLVMValueRef
lp_build_broadcast(struct gallivm_state *gallivm,
                   LLVMTypeRef vec_type,
                   LLVMValueRef scalar)
{
   LLVMValueRef res;

   if (LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) {
      /* scalar */
      assert(vec_type == LLVMTypeOf(scalar));
      res = scalar;
   } else {
      LLVMBuilderRef builder = gallivm->builder;
      const unsigned length = LLVMGetVectorSize(vec_type);
      LLVMValueRef undef = LLVMGetUndef(vec_type);
      /* The shuffle vector is always made of int32 elements */
      LLVMTypeRef i32_type = LLVMInt32TypeInContext(gallivm->context);
      LLVMTypeRef i32_vec_type = LLVMVectorType(i32_type, length);

      assert(LLVMGetElementType(vec_type) == LLVMTypeOf(scalar));

      res = LLVMBuildInsertElement(builder, undef, scalar, LLVMConstNull(i32_type), "");
      res = LLVMBuildShuffleVector(builder, res, undef, LLVMConstNull(i32_vec_type), "");
   }

   return res;
}
Esempio n. 9
0
LLVMValueRef gen_return(compile_t* c, ast_t* ast)
{
  ast_t* expr = ast_child(ast);
  LLVMValueRef value = gen_expr(c, expr);

  size_t clause;
  ast_t* try_expr = ast_try_clause(ast, &clause);

  // Do the then block only if we return in the body or else clause.
  // In the then block, return without doing the then block.
  if((try_expr != NULL) && (clause != 2))
    gen_expr(c, ast_childidx(try_expr, 2));

  LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(codegen_fun(c)));
  LLVMTypeRef r_type = LLVMGetReturnType(f_type);

  codegen_debugloc(c, ast);

  if(LLVMGetTypeKind(r_type) != LLVMVoidTypeKind)
  {
    LLVMValueRef ret = gen_assign_cast(c, r_type, value, ast_type(expr));
    codegen_scope_lifetime_end(c);
    LLVMBuildRet(c->builder, ret);
  } else {
    codegen_scope_lifetime_end(c);
    LLVMBuildRetVoid(c->builder);
  }

  codegen_debugloc(c, NULL);
  return GEN_NOVALUE;
}
Esempio n. 10
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type)
{
  // Add the function and set the calling convention.
  LLVMValueRef fun = LLVMAddFunction(c->module, name, type);
  LLVMSetFunctionCallConv(fun, c->callconv);

  LLVMValueRef arg = LLVMGetFirstParam(fun);
  uint32_t i = 1;

  while(arg != NULL)
  {
    LLVMTypeRef type = LLVMTypeOf(arg);

    if(LLVMGetTypeKind(type) == LLVMPointerTypeKind)
    {
      LLVMTypeRef elem = LLVMGetElementType(type);

      if(LLVMGetTypeKind(elem) == LLVMStructTypeKind)
      {
        size_t size = (size_t)LLVMABISizeOfType(c->target_data, elem);
        LLVMSetDereferenceable(fun, i, size);
      }
    }

    arg = LLVMGetNextParam(arg);
    i++;
  }

  return fun;
}
Esempio n. 11
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);
}
Esempio n. 12
0
static LLVMValueRef
translateFunCallExpr(SymbolTable *TyTable, SymbolTable *ValTable, ASTNode *Node) {
  PtrVector *V = &(Node->Child);

  ASTNode *ExprNode   = (ASTNode*) ptrVectorGet(V, 0),
          *ParamsNode = (ASTNode*) ptrVectorGet(V, 1);

  LLVMTypeRef ReturnType  = toTransitionType(getLLVMTypeFromType(TyTable, Node->Value)),
              *ParamsType = NULL, FunctionType;
  LLVMValueRef *ParamsValue = NULL;

  unsigned Count = 0;
  if (ParamsNode) {
    ParamsValue = (LLVMValueRef*) malloc(sizeof(LLVMValueRef) * ParamsNode->Child.Size);
    for (Count = 0; Count < ParamsNode->Child.Size; ++Count) {
      LLVMValueRef ExprVal = translateExpr(TyTable, ValTable, ptrVectorGet(&(ParamsNode->Child), Count));

      LLVMTypeRef ExprType = LLVMGetElementType(LLVMTypeOf(ExprVal));
      switch (LLVMGetTypeKind(ExprType)) {
        case LLVMIntegerTypeKind:
        case LLVMFloatTypeKind:
        case LLVMPointerTypeKind: ExprVal = LLVMBuildLoad(Builder, ExprVal, "load.4.call"); break;

        default: break;
      }

      ParamsValue[Count]  = ExprVal;

      if (!ParamsType) 
        ParamsType = (LLVMTypeRef*) malloc(sizeof(LLVMTypeRef) * ParamsNode->Child.Size);
      ParamsType[Count] = LLVMTypeOf(ExprVal);
    }
  }

  FunctionType = LLVMFunctionType(ReturnType, ParamsType, Count, 0);
  FunctionType = LLVMPointerType(FunctionType, 0);

  LLVMValueRef Closure   = translateExpr(TyTable, ValTable, ExprNode);
  LLVMValueRef CallValue = callClosure(FunctionType, Closure, ParamsValue, Count);

  switch (getLLVMValueTypeKind(CallValue)) {
    case LLVMIntegerTypeKind:
    case LLVMFloatTypeKind:
    case LLVMPointerTypeKind:
      {
        if (getLLVMValueTypeKind(CallValue) == LLVMPointerTypeKind &&
            getLLVMElementTypeKind(CallValue) == LLVMStructTypeKind) 
          break;
        LLVMValueRef PtrMem = LLVMBuildAlloca(Builder, LLVMTypeOf(CallValue), "");
        LLVMBuildStore(Builder, CallValue, PtrMem);
        return PtrMem;
      }
  }
  return CallValue;
}
Esempio n. 13
0
File: genfun.c Progetto: fydot/ponyc
static LLVMTypeRef send_message(compile_t* c, ast_t* fun, LLVMValueRef to,
  LLVMValueRef func, uint32_t index)
{
  // Get the parameter types.
  LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(func));
  int count = LLVMCountParamTypes(f_type) + 2;
  VLA(LLVMTypeRef, f_params, count);
  LLVMGetParamTypes(f_type, &f_params[2]);

  // The first one becomes the message size, the second the message ID.
  f_params[0] = c->i32;
  f_params[1] = c->i32;
  f_params[2] = c->void_ptr;
  LLVMTypeRef msg_type = LLVMStructTypeInContext(c->context, f_params, count,
    false);
  LLVMTypeRef msg_type_ptr = LLVMPointerType(msg_type, 0);

  // Allocate the message, setting its size and ID.
  size_t msg_size = LLVMABISizeOfType(c->target_data, msg_type);
  LLVMValueRef args[2];

  args[0] = LLVMConstInt(c->i32, pool_index(msg_size), false);
  args[1] = LLVMConstInt(c->i32, index, false);
  LLVMValueRef msg = gencall_runtime(c, "pony_alloc_msg", args, 2, "");
  LLVMValueRef msg_ptr = LLVMBuildBitCast(c->builder, msg, msg_type_ptr, "");

  // Trace while populating the message contents.
  LLVMValueRef start_trace = gencall_runtime(c, "pony_gc_send", NULL, 0, "");
  ast_t* params = ast_childidx(fun, 3);
  ast_t* param = ast_child(params);
  bool need_trace = false;

  for(int i = 3; i < count; i++)
  {
    LLVMValueRef arg = LLVMGetParam(func, i - 2);
    LLVMValueRef arg_ptr = LLVMBuildStructGEP(c->builder, msg_ptr, i, "");
    LLVMBuildStore(c->builder, arg, arg_ptr);

    need_trace |= gentrace(c, arg, ast_type(param));
    param = ast_sibling(param);
  }

  if(need_trace)
    gencall_runtime(c, "pony_send_done", NULL, 0, "");
  else
    LLVMInstructionEraseFromParent(start_trace);

  // Send the message.
  args[0] = LLVMBuildBitCast(c->builder, to, c->object_ptr, "");
  args[1] = msg;
  gencall_runtime(c, "pony_sendv", args, 2, "");

  // Return the type of the message.
  return msg_type_ptr;
}
Esempio n. 14
0
void gencall_lifetime_end(compile_t* c, LLVMValueRef ptr)
{
  LLVMValueRef func = LLVMLifetimeEnd(c->module);
  LLVMTypeRef type = LLVMGetElementType(LLVMTypeOf(ptr));
  size_t size = (size_t)LLVMABISizeOfType(c->target_data, type);

  LLVMValueRef args[2];
  args[0] = LLVMConstInt(c->i64, size, false);
  args[1] = LLVMBuildBitCast(c->builder, ptr, c->void_ptr, "");
  LLVMBuildCall(c->builder, func, args, 2, "");
}
Esempio n. 15
0
void
lp_build_array_set(struct gallivm_state *gallivm,
                   LLVMValueRef ptr,
                   LLVMValueRef index,
                   LLVMValueRef value)
{
   LLVMValueRef element_ptr;
   assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
   assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
   element_ptr = lp_build_array_get_ptr(gallivm, ptr, index);
   LLVMBuildStore(gallivm->builder, value, element_ptr);
}
Esempio n. 16
0
static LLVMValueRef make_unbox_function(compile_t* c, gentype_t* g,
  const char* name)
{
  LLVMValueRef fun = LLVMGetNamedFunction(c->module, name);

  if(fun == NULL)
    return LLVMConstNull(c->void_ptr);

  // Create a new unboxing function that forwards to the real function.
  LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(fun));
  int count = LLVMCountParamTypes(f_type);

  // If it takes no arguments, it's a special number constructor. Don't put it
  // in the vtable.
  if(count == 0)
    return LLVMConstNull(c->void_ptr);

  size_t buf_size = count *sizeof(LLVMTypeRef);
  LLVMTypeRef* params = (LLVMTypeRef*)pool_alloc_size(buf_size);
  LLVMGetParamTypes(f_type, params);
  LLVMTypeRef ret_type = LLVMGetReturnType(f_type);

  // It's the same type, but it takes the boxed type instead of the primitive
  // type as the receiver.
  params[0] = g->structure_ptr;

  const char* unbox_name = genname_unbox(name);
  LLVMTypeRef unbox_type = LLVMFunctionType(ret_type, params, count, false);
  LLVMValueRef unbox_fun = codegen_addfun(c, unbox_name, unbox_type);
  codegen_startfun(c, unbox_fun, false);

  // Extract the primitive type from element 1 and call the real function.
  LLVMValueRef this_ptr = LLVMGetParam(unbox_fun, 0);
  LLVMValueRef primitive_ptr = LLVMBuildStructGEP(c->builder, this_ptr, 1, "");
  LLVMValueRef primitive = LLVMBuildLoad(c->builder, primitive_ptr, "");

  LLVMValueRef* args = (LLVMValueRef*)pool_alloc_size(buf_size);
  args[0] = primitive;

  for(int i = 1; i < count; i++)
    args[i] = LLVMGetParam(unbox_fun, i);

  LLVMValueRef result = codegen_call(c, fun, args, count);
  LLVMBuildRet(c->builder, result);
  codegen_finishfun(c);

  pool_free_size(buf_size, params);
  pool_free_size(buf_size, args);
  return LLVMConstBitCast(unbox_fun, c->void_ptr);
}
Esempio n. 17
0
File: genfun.c Progetto: fydot/ponyc
LLVMTypeRef genfun_sig(compile_t* c, gentype_t* g, const char *name,
  ast_t* typeargs)
{
  // If the function already exists, return its type.
  const char* funname = genname_fun(g->type_name, name, typeargs);
  LLVMValueRef func = LLVMGetNamedFunction(c->module, funname);

  if(func != NULL)
    return LLVMGetElementType(LLVMTypeOf(func));

  ast_t* fun = get_fun(g, name, typeargs);
  LLVMTypeRef type = get_signature(c, g, fun);
  ast_free_unattached(fun);
  return type;
}
Esempio n. 18
0
static LLVMValueRef 
translateRecAccessLval(SymbolTable *TyTable, SymbolTable *ValTable, ASTNode *Node) {
  ASTNode *Lval = (ASTNode*) ptrVectorGet(&(Node->Child), 0);

  LLVMValueRef Record     = translateExpr(TyTable, ValTable, Lval);
  LLVMTypeRef  RecTypeRef = LLVMGetElementType(LLVMTypeOf(Record));

  if (LLVMGetTypeKind(RecTypeRef) == LLVMPointerTypeKind)
    RecTypeRef = LLVMGetElementType(RecTypeRef);

  /* Get struct's name. */
  const char *AliasName = LLVMGetStructName(RecTypeRef); 
  char TypeName[NAME_MAX];
  toRawName(TypeName, AliasName);

  /* Get struct's field. */
  Type      *RecType = (Type*) symTableFind(TyTable, TypeName);
  Hash      *Fields  = (Hash*) RecType->Val;
  PtrVector *V       = &(Fields->Pairs);

  /* Get the right struct's field. */
  unsigned Count = 0;
  for (Count = 0; Count < V->Size; ++Count) {
    Pair *P = (Pair*) ptrVectorGet(V, Count);
    if (!strcmp(P->first, Node->Value)) break;
  }

  LLVMValueRef Idx[] = { getSConstInt(0), getSConstInt(Count) };
  LLVMValueRef Field = LLVMBuildInBoundsGEP(Builder, Record, Idx, 2, "");

  LLVMTypeRef FieldElType = LLVMGetElementType(LLVMTypeOf(Field));
  if (LLVMGetTypeKind(FieldElType) == LLVMPointerTypeKind &&
      LLVMGetTypeKind(LLVMGetElementType(FieldElType)) == LLVMStructTypeKind)
    Field = LLVMBuildLoad(Builder, Field, "get.struct");
  return Field;
}
Esempio n. 19
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));
   }
}
Esempio n. 20
0
LLVMValueRef
lp_build_struct_get(struct gallivm_state *gallivm,
                    LLVMValueRef ptr,
                    unsigned member,
                    const char *name)
{
   LLVMValueRef member_ptr;
   LLVMValueRef res;
   assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
   assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind);
   member_ptr = lp_build_struct_get_ptr(gallivm, ptr, member, name);
   res = LLVMBuildLoad(gallivm->builder, member_ptr, "");
   lp_build_name(res, "%s.%s", LLVMGetValueName(ptr), name);
   return res;
}
Esempio n. 21
0
LLVMValueRef
lp_build_array_get(struct gallivm_state *gallivm,
                   LLVMValueRef ptr,
                   LLVMValueRef index)
{
   LLVMValueRef element_ptr;
   LLVMValueRef res;
   assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
   assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
   element_ptr = lp_build_array_get_ptr(gallivm, ptr, index);
   res = LLVMBuildLoad(gallivm->builder, element_ptr, "");
#ifdef DEBUG
   lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index));
#endif
   return res;
}
Esempio n. 22
0
static LLVMValueRef assign_one(compile_t* c, LLVMValueRef l_value,
  LLVMValueRef r_value, ast_t* r_type)
{
  LLVMValueRef result = LLVMBuildLoad(c->builder, l_value, "");

  // Cast the rvalue appropriately.
  LLVMTypeRef l_type = LLVMGetElementType(LLVMTypeOf(l_value));
  LLVMValueRef cast_value = gen_assign_cast(c, l_type, r_value, r_type);

  if(cast_value == NULL)
    return NULL;

  // Store to the field.
  LLVMBuildStore(c->builder, cast_value, l_value);
  return result;
}
Esempio n. 23
0
LLVMValueRef
lp_build_struct_get_ptr(struct gallivm_state *gallivm,
                        LLVMValueRef ptr,
                        unsigned member,
                        const char *name)
{
   LLVMValueRef indices[2];
   LLVMValueRef member_ptr;
   assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
   assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMStructTypeKind);
   indices[0] = lp_build_const_int32(gallivm, 0);
   indices[1] = lp_build_const_int32(gallivm, member);
   member_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), "");
   lp_build_name(member_ptr, "%s.%s_ptr", LLVMGetValueName(ptr), name);
   return member_ptr;
}
Esempio n. 24
0
static bool genfun_fun(compile_t* c, reachable_type_t* t,
  reachable_method_t* m)
{
  assert(m->func != NULL);

  AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error,
    body);

  if(m->name == c->str__final)
  {
    t->final_fn = m->func;
    LLVMSetFunctionCallConv(m->func, LLVMCCallConv);
  }

  codegen_startfun(c, m->func, m->di_file, m->di_method);
  name_params(c, t, m, params, m->func);

  LLVMValueRef value = gen_expr(c, body);

  if(value == NULL)
    return false;

  if(value != GEN_NOVALUE)
  {
    LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(m->func));
    LLVMTypeRef r_type = LLVMGetReturnType(f_type);

    // If the result type is known to be a tuple, do the correct assignment
    // cast even if the body type is not a tuple.
    ast_t* body_type = ast_type(body);

    if(ast_id(result) == TK_TUPLETYPE)
      body_type = result;

    LLVMValueRef ret = gen_assign_cast(c, r_type, value, body_type);

    if(ret == NULL)
      return false;

    codegen_debugloc(c, ast_childlast(body));
    LLVMBuildRet(c->builder, ret);
    codegen_debugloc(c, NULL);
  }

  codegen_finishfun(c);
  return true;
}
Esempio n. 25
0
LLVMValueRef
lp_build_array_get_ptr(struct gallivm_state *gallivm,
                       LLVMValueRef ptr,
                       LLVMValueRef index)
{
   LLVMValueRef indices[2];
   LLVMValueRef element_ptr;
   assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind);
   assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(ptr))) == LLVMArrayTypeKind);
   indices[0] = lp_build_const_int32(gallivm, 0);
   indices[1] = index;
   element_ptr = LLVMBuildGEP(gallivm->builder, ptr, indices, Elements(indices), "");
#ifdef DEBUG
   lp_build_name(element_ptr, "&%s[%s]",
                 LLVMGetValueName(ptr), LLVMGetValueName(index));
#endif
   return element_ptr;
}
Esempio n. 26
0
File: genfun.c Progetto: fydot/ponyc
static LLVMValueRef genfun_fun(compile_t* c, gentype_t* g, const char *name,
  ast_t* typeargs)
{
  ast_t* fun = get_fun(g, name, typeargs);
  LLVMValueRef func = get_prototype(c, g, name, typeargs, fun);

  if(func == NULL)
  {
    ast_free_unattached(fun);
    return NULL;
  }

  if(LLVMCountBasicBlocks(func) != 0)
  {
    ast_free_unattached(fun);
    return func;
  }

  codegen_startfun(c, func, ast_debug(fun));
  name_params(c, g->ast, ast_childidx(fun, 3), func);
  genfun_dwarf(c, g, name, typeargs, fun);

  ast_t* body = ast_childidx(fun, 6);
  LLVMValueRef value = gen_expr(c, body);

  if(value == NULL)
  {
    ast_free_unattached(fun);
    return NULL;
  } else if(value != GEN_NOVALUE) {
    genfun_dwarf_return(c, body);

    LLVMTypeRef f_type = LLVMGetElementType(LLVMTypeOf(func));
    LLVMTypeRef r_type = LLVMGetReturnType(f_type);

    LLVMValueRef ret = gen_assign_cast(c, r_type, value, ast_type(body));
    LLVMBuildRet(c->builder, ret);
  }

  codegen_finishfun(c);
  ast_free_unattached(fun);

  return func;
}
Esempio n. 27
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type,
  bool pony_abi)
{
  // Add the function and set the calling convention and the linkage type.
  LLVMValueRef fun = LLVMAddFunction(c->module, name, type);
  LLVMSetFunctionCallConv(fun, c->callconv);
  LLVMSetLinkage(fun, c->linkage);
  LLVMSetUnnamedAddr(fun, true);

  if(pony_abi)
  {
    LLVMValueRef md = LLVMMDNodeInContext(c->context, NULL, 0);
    LLVMSetMetadataStr(fun, "pony.abi", md);
  }

  LLVMValueRef arg = LLVMGetFirstParam(fun);
  uint32_t i = 1;

  while(arg != NULL)
  {
    LLVMTypeRef type = LLVMTypeOf(arg);

    if(LLVMGetTypeKind(type) == LLVMPointerTypeKind)
    {
      LLVMTypeRef elem = LLVMGetElementType(type);

      if(LLVMGetTypeKind(elem) == LLVMStructTypeKind)
      {
        size_t size = (size_t)LLVMABISizeOfType(c->target_data, elem);
#if PONY_LLVM >= 309
        LLVM_DECLARE_ATTRIBUTEREF(deref_attr, dereferenceable, size);
        LLVMAddAttributeAtIndex(fun, i, deref_attr);
#else
        LLVMSetDereferenceable(fun, i, size);
#endif
      }
    }

    arg = LLVMGetNextParam(arg);
    i++;
  }

  return fun;
}
Esempio n. 28
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);
   }
}
Esempio n. 29
0
void JITImpl::init()
{
  if (initialized)
    return;
  LLVMLinkInJIT();
  LLVMInitializeNativeTarget();
  LLVMMemoryBufferRef memBuffer =
    LLVMExtraCreateMemoryBufferWithPtr(instructionBitcode,
                                       instructionBitcodeSize);
  char *outMessage;
  if (LLVMParseBitcode(memBuffer, &module, &outMessage)) {
    std::cerr << "Error loading bitcode: " << outMessage << '\n';
    std::abort();
  }
  // TODO experiment with opt level.
  if (LLVMCreateJITCompilerForModule(&executionEngine, module, 1,
                                      &outMessage)) {
    std::cerr << "Error creating JIT compiler: " << outMessage << '\n';
    std::abort();
  }
  builder = LLVMCreateBuilder();
  LLVMValueRef callee = LLVMGetNamedFunction(module, "jitInstructionTemplate");
  assert(callee && "jitInstructionTemplate() not found in module");
  jitFunctionType = LLVMGetElementType(LLVMTypeOf(callee));
  functions.init(module);
  FPM = LLVMCreateFunctionPassManagerForModule(module);
  LLVMAddTargetData(LLVMGetExecutionEngineTargetData(executionEngine), FPM);
  LLVMAddBasicAliasAnalysisPass(FPM);
  LLVMAddJumpThreadingPass(FPM);
  LLVMAddGVNPass(FPM);
  LLVMAddJumpThreadingPass(FPM);
  LLVMAddCFGSimplificationPass(FPM);
  LLVMAddDeadStoreEliminationPass(FPM);
  LLVMAddInstructionCombiningPass(FPM);
  LLVMInitializeFunctionPassManager(FPM);
  if (DEBUG_JIT) {
    LLVMExtraRegisterJitDisassembler(executionEngine, LLVMGetTarget(module));
  }
  initialized = true;
}
Esempio n. 30
0
static LLVMValueRef assign_field(compile_t* c, LLVMValueRef l_value,
  LLVMValueRef r_value, ast_t* p_type, ast_t* r_type)
{
  LLVMValueRef result = LLVMBuildLoad(c->builder, l_value, "");

  // Cast the rvalue appropriately.
  LLVMTypeRef cast_type = LLVMGetElementType(LLVMTypeOf(l_value));
  LLVMValueRef cast_value = gen_assign_cast(c, cast_type, r_value, r_type);

  if(cast_value == NULL)
    return NULL;

  // Store to the field.
  LLVMValueRef store = LLVMBuildStore(c->builder, cast_value, l_value);

  LLVMValueRef metadata = tbaa_metadata_for_type(c, p_type);
  const char id[] = "tbaa";
  LLVMSetMetadata(result, LLVMGetMDKindID(id, sizeof(id) - 1), metadata);
  LLVMSetMetadata(store, LLVMGetMDKindID(id, sizeof(id) - 1), metadata);

  return result;
}