Ejemplo n.º 1
0
LLVMValueRef gen_string(compile_t* c, ast_t* ast)
{
  ast_t* type = ast_type(ast);
  const char* name = ast_name(ast);
  size_t len = ast_name_len(ast);

  LLVMValueRef args[4];
  args[0] = LLVMConstInt(c->i32, 0, false);
  args[1] = LLVMConstInt(c->i32, 0, false);

  LLVMValueRef str = LLVMConstStringInContext(c->context, name, (int)len,
    false);
  LLVMValueRef g_str = LLVMAddGlobal(c->module, LLVMTypeOf(str), "");
  LLVMSetLinkage(g_str, LLVMPrivateLinkage);
  LLVMSetInitializer(g_str, str);
  LLVMSetGlobalConstant(g_str, true);
  LLVMValueRef str_ptr = LLVMConstInBoundsGEP(g_str, args, 2);

  reach_type_t* t = reach_type(c->reach, type);

  args[0] = t->desc;
  args[1] = LLVMConstInt(c->intptr, len, false);
  args[2] = LLVMConstInt(c->intptr, len + 1, false);
  args[3] = str_ptr;

  LLVMValueRef inst = LLVMConstNamedStruct(t->structure, args, 4);
  LLVMValueRef g_inst = LLVMAddGlobal(c->module, t->structure, "");
  LLVMSetInitializer(g_inst, inst);
  LLVMSetGlobalConstant(g_inst, true);
  LLVMSetLinkage(g_inst, LLVMPrivateLinkage);

  return g_inst;
}
Ejemplo n.º 2
0
static void set_method_external_interface(reach_type_t* t, const char* name,
  uint32_t vtable_index)
{
  size_t i = HASHMAP_BEGIN;
  reach_type_t* sub;

  while((sub = reach_type_cache_next(&t->subtypes, &i)) != NULL)
  {
    reach_method_name_t* n = reach_method_name(sub, name);

    if(n == NULL)
      continue;

    size_t j = HASHMAP_BEGIN;
    reach_method_t* m;

    while((m = reach_mangled_next(&n->r_mangled, &j)) != NULL)
    {
      if(m->vtable_index == vtable_index)
      {
        compile_method_t* c_m = (compile_method_t*)m->c_method;
        LLVMSetFunctionCallConv(c_m->func, LLVMCCallConv);
        LLVMSetLinkage(c_m->func, LLVMExternalLinkage);
        break;
      }
    }
  }
}
Ejemplo n.º 3
0
void genprim_string_deserialise(compile_t* c, reach_type_t* t)
{
  // Generate the deserisalise function.
  t->deserialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->trace_type);

  codegen_startfun(c, t->deserialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->deserialise_fn, LLVMCCallConv);
  LLVMSetLinkage(t->deserialise_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->deserialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->deserialise_fn, 1);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  gendeserialise_typeid(c, t, object);

  // Deserialise the string contents.
  LLVMValueRef alloc = field_value(c, object, 2);
  LLVMValueRef ptr_offset = field_value(c, object, 3);
  ptr_offset = LLVMBuildPtrToInt(c->builder, ptr_offset, c->intptr, "");

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = ptr_offset;
  args[2] = alloc;
  LLVMValueRef ptr_addr = gencall_runtime(c, "pony_deserialise_block", args, 3,
    "");

  LLVMValueRef ptr = LLVMBuildStructGEP(c->builder, object, 3, "");
  LLVMBuildStore(c->builder, ptr_addr, ptr);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 4
0
void genprim_string_serialise_trace(compile_t* c, reach_type_t* t)
{
  // Generate the serialise_trace function.
  t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name),
    c->serialise_type);

  codegen_startfun(c, t->serialise_trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_trace_fn, LLVMCCallConv);
  LLVMSetLinkage(t->serialise_trace_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_trace_fn, 1);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");

  // Read the size.
  LLVMValueRef size = field_value(c, object, 1);
  LLVMValueRef alloc = LLVMBuildAdd(c->builder, size,
    LLVMConstInt(c->intptr, 1, false), "");

  // Reserve space for the contents.
  LLVMValueRef ptr = field_value(c, object, 3);

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = ptr;
  args[2] = alloc;
  gencall_runtime(c, "pony_serialise_reserve", args, 3, "");

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 5
0
static void make_serialise(compile_t* c, reach_type_t* t)
{
  // Use the trace function as the serialise_trace function.
  t->serialise_trace_fn = t->trace_fn;

  // Generate the serialise function.
  t->serialise_fn = codegen_addfun(c, genname_serialise(t->name),
    c->serialise_type);

  codegen_startfun(c, t->serialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_fn, LLVMCCallConv);
  LLVMSetLinkage(t->serialise_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_fn, 1);
  LLVMValueRef addr = LLVMGetParam(t->serialise_fn, 2);
  LLVMValueRef offset = LLVMGetParam(t->serialise_fn, 3);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");
  LLVMValueRef offset_addr = LLVMBuildInBoundsGEP(c->builder, addr, &offset, 1,
    "");

  serialise(c, t, ctx, object, offset_addr);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 6
0
static void make_dispatch(compile_t* c, reach_type_t* t)
{
  // Do nothing if we're not an actor.
  if(t->underlying != TK_ACTOR)
    return;

  // Create a dispatch function.
  const char* dispatch_name = genname_dispatch(t->name);
  t->dispatch_fn = codegen_addfun(c, dispatch_name, c->dispatch_type);
  LLVMSetFunctionCallConv(t->dispatch_fn, LLVMCCallConv);
  LLVMSetLinkage(t->dispatch_fn, LLVMExternalLinkage);
  codegen_startfun(c, t->dispatch_fn, NULL, NULL);

  LLVMBasicBlockRef unreachable = codegen_block(c, "unreachable");

  // Read the message ID.
  LLVMValueRef msg = LLVMGetParam(t->dispatch_fn, 2);
  LLVMValueRef id_ptr = LLVMBuildStructGEP(c->builder, msg, 1, "");
  LLVMValueRef id = LLVMBuildLoad(c->builder, id_ptr, "id");

  // Store a reference to the dispatch switch. When we build behaviours, we
  // will add cases to this switch statement based on message ID.
  t->dispatch_switch = LLVMBuildSwitch(c->builder, id, unreachable, 0);

  // Mark the default case as unreachable.
  LLVMPositionBuilderAtEnd(c->builder, unreachable);
  LLVMBuildUnreachable(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 7
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type)
{
  // 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);

  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;
}
Ejemplo n.º 8
0
static LLVMValueRef make_trait_list(compile_t* c, reach_type_t* t,
  uint32_t* final_count)
{
  // The list is an array of integers.
  uint32_t* tid;
  size_t tid_size;
  uint32_t count = trait_count(t, &tid, &tid_size);

  // If we have no traits, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0));

  // Create a constant array of trait identifiers.
  size_t list_size = count * sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)ponyint_pool_alloc_size(list_size);

  for(uint32_t i = 0; i < count; i++)
    list[i] = LLVMConstInt(c->i32, tid[i], false);

  LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count);

  // Create a global to hold the array.
  const char* name = genname_traitlist(t->name);
  LLVMTypeRef list_type = LLVMArrayType(c->i32, count);
  LLVMValueRef global = LLVMAddGlobal(c->module, list_type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMPrivateLinkage);
  LLVMSetInitializer(global, trait_array);

  ponyint_pool_free_size(tid_size, tid);
  ponyint_pool_free_size(list_size, list);

  *final_count = count;
  return global;
}
Ejemplo n.º 9
0
Archivo: gentype.c Proyecto: nunb/ponyc
static void make_global_instance(compile_t* c, gentype_t* g)
{
  // Not a primitive type.
  if(g->underlying != TK_PRIMITIVE)
    return;

  // No instance for base types.
  if(g->primitive != NULL)
    return;

  // Check for an existing instance.
  const char* inst_name = genname_instance(g->type_name);
  g->instance = LLVMGetNamedGlobal(c->module, inst_name);

  if(g->instance != NULL)
    return;

  // Create a unique global instance.
  LLVMValueRef args[1];
  args[0] = g->desc;
  LLVMValueRef value = LLVMConstNamedStruct(g->structure, args, 1);

  g->instance = LLVMAddGlobal(c->module, g->structure, inst_name);
  LLVMSetInitializer(g->instance, value);
  LLVMSetGlobalConstant(g->instance, true);
  LLVMSetLinkage(g->instance, LLVMInternalLinkage);
}
Ejemplo n.º 10
0
Archivo: hi2.c Proyecto: alexmavr/pzcc
int main (void) {
    LLVMModuleRef module = LLVMModuleCreateWithName("kal");
    LLVMBuilderRef builder = LLVMCreateBuilder();
//	LLVMInitializeNativeTarget();

	LLVMTypeRef funcType = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0);
	LLVMValueRef func = LLVMAddFunction(module, "main", funcType);
	LLVMSetLinkage(func, LLVMExternalLinkage);
	LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
	LLVMPositionBuilderAtEnd(builder, block);

	LLVMValueRef cond = LLVMBuildICmp(builder, LLVMIntNE, LLVMConstInt(LLVMInt32Type(), 2, 0), LLVMConstInt(LLVMInt32Type(), 1, 0), "ifcond");

	LLVMValueRef owning_block = LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder));	//TODO: WRONG??
	//LLVMValueRef owning_block = LLVMBasicBlockAsValue(LLVMGetPreviousBasicBlock(LLVMGetInsertBlock(builder)));
	// 2. Generate new blocks for cases.
	LLVMBasicBlockRef then_ref = LLVMAppendBasicBlock(owning_block, "then");
	LLVMBasicBlockRef else_ref = LLVMAppendBasicBlock(owning_block, "else");
	LLVMBasicBlockRef merge_ref = LLVMAppendBasicBlock(owning_block, "ifmerge");

	// 3. Branch conditionally on then or else.
	LLVMBuildCondBr(builder, cond, then_ref, else_ref);

	// 4. Build then branch prologue.
	LLVMPositionBuilderAtEnd(builder, then_ref);

	LLVMValueRef hi1 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp");

	// 5. Connect then branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	then_ref = LLVMGetInsertBlock(builder);

	// 6. Build else branch prologue.
	LLVMPositionBuilderAtEnd(builder, else_ref);

	LLVMValueRef hi2 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp2");

	// 7. Connect else branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	else_ref = LLVMGetInsertBlock(builder);
	// 8. Position ourselves after the merge block.
	LLVMPositionBuilderAtEnd(builder, merge_ref);
	// 9. Build the phi node.
//	LLVMValueRef phi = LLVMBuildPhi(builder, LLVMDoubleType(), "phi");
	// 10. Add incoming edges.
//	LLVMAddIncoming(phi, &hi1, &then_ref, 1);
//	LLVMAddIncoming(phi, &hi2, &else_ref, 1);

	LLVMDumpModule(module);
	LLVMDisposeBuilder(builder);
	LLVMDisposeModule(module);

	return 0;
}
Ejemplo n.º 11
0
static LLVMValueRef make_field_list(compile_t* c, gentype_t* g)
{
  // The list is an array of field descriptors.
  int count;

  if(g->underlying == TK_TUPLETYPE)
    count = g->field_count;
  else
    count = 0;

  LLVMTypeRef type = LLVMArrayType(c->field_descriptor, count);

  // If we aren't a tuple, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(type, 0));

  // Create a constant array of field descriptors.
  size_t buf_size = count *sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(buf_size);

  for(int i = 0; i < count; i++)
  {
    gentype_t fg;

    if(!gentype(c, g->fields[i], &fg))
      return NULL;

    LLVMValueRef fdesc[2];
    fdesc[0] = LLVMConstInt(c->i32,
      LLVMOffsetOfElement(c->target_data, g->primitive, i), false);

    if(fg.desc != NULL)
    {
      // We are a concrete type.
      fdesc[1] = LLVMConstBitCast(fg.desc, c->descriptor_ptr);
    } else {
      // We aren't a concrete type.
      fdesc[1] = LLVMConstNull(c->descriptor_ptr);
    }

    list[i] = LLVMConstStructInContext(c->context, fdesc, 2, false);
  }

  LLVMValueRef field_array = LLVMConstArray(c->field_descriptor, list, count);

  // Create a global to hold the array.
  const char* name = genname_fieldlist(g->type_name);
  LLVMValueRef global = LLVMAddGlobal(c->module, type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMInternalLinkage);
  LLVMSetInitializer(global, field_array);

  pool_free_size(buf_size, list);
  return global;
}
Ejemplo n.º 12
0
LLVMValueRef 
lp_build_const_string_variable(LLVMModuleRef module,
                               LLVMContextRef context,
                               const char *str, int len)
{
   LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8TypeInContext(context), len + 1), "");
   LLVMSetGlobalConstant(string, TRUE);
   LLVMSetLinkage(string, LLVMInternalLinkage);
   LLVMSetInitializer(string, LLVMConstStringInContext(context, str, len + 1, TRUE));
   return string;
}
Ejemplo n.º 13
0
void gendesc_type(compile_t* c, reach_type_t* t)
{
  switch(t->underlying)
  {
    case TK_TUPLETYPE:
    case TK_PRIMITIVE:
    case TK_STRUCT:
    case TK_CLASS:
    case TK_ACTOR:
      break;

    default:
      return;
  }

  const char* desc_name = genname_descriptor(t->name);
  uint32_t traits = trait_count(t, NULL, NULL);
  uint32_t fields = 0;
  uint32_t vtable_size = 0;

  if(t->underlying == TK_TUPLETYPE)
    fields = t->field_count;
  else
    vtable_size = t->vtable_size;

  t->desc_type = LLVMStructCreateNamed(c->context, desc_name);
  LLVMTypeRef params[DESC_LENGTH];

  params[DESC_ID] = c->i32;
  params[DESC_SIZE] = c->i32;
  params[DESC_TRAIT_COUNT] = c->i32;
  params[DESC_FIELD_COUNT] = c->i32;
  params[DESC_FIELD_OFFSET] = c->i32;
  params[DESC_INSTANCE] = c->object_ptr;
  params[DESC_TRACE] = c->trace_fn;
  params[DESC_SERIALISE_TRACE] = c->trace_fn;
  params[DESC_SERIALISE] = c->serialise_fn;
  params[DESC_DESERIALISE] = c->trace_fn;
  params[DESC_DISPATCH] = c->dispatch_fn;
  params[DESC_FINALISE] = c->final_fn;
  params[DESC_EVENT_NOTIFY] = c->i32;
  params[DESC_TRAITS] = LLVMPointerType(LLVMArrayType(c->i32, traits), 0);
  params[DESC_FIELDS] = LLVMPointerType(
    LLVMArrayType(c->field_descriptor, fields), 0);
  params[DESC_VTABLE] = LLVMArrayType(c->void_ptr, vtable_size);

  LLVMStructSetBody(t->desc_type, params, DESC_LENGTH, false);

  t->desc = LLVMAddGlobal(c->module, t->desc_type, desc_name);
  LLVMSetGlobalConstant(t->desc, true);
  LLVMSetLinkage(t->desc, LLVMPrivateLinkage);
}
Ejemplo n.º 14
0
static void set_method_external_nominal(reach_type_t* t, const char* name)
{
  reach_method_name_t* n = reach_method_name(t, name);
  if(n != NULL)
  {
    size_t i = HASHMAP_BEGIN;
    reach_method_t* m;
    while((m = reach_methods_next(&n->r_methods, &i)) != NULL)
    {
      LLVMSetFunctionCallConv(m->func, LLVMCCallConv);
      LLVMSetLinkage(m->func, LLVMExternalLinkage);
    }
  }
}
Ejemplo n.º 15
0
LLVMValueRef gen_string(compile_t* c, ast_t* ast)
{
  ast_t* type = ast_type(ast);
  const char* name = ast_name(ast);
  size_t len = strlen(name);

  LLVMValueRef args[4];
  args[0] = LLVMConstInt(c->i32, 0, false);
  args[1] = LLVMConstInt(c->i32, 0, false);

  LLVMValueRef str = LLVMConstStringInContext(c->context, name, (int)len,
    false);
  LLVMValueRef g_str = LLVMAddGlobal(c->module, LLVMTypeOf(str), "$strval");
  LLVMSetLinkage(g_str, LLVMInternalLinkage);
  LLVMSetInitializer(g_str, str);
  LLVMSetGlobalConstant(g_str, true);
  LLVMValueRef str_ptr = LLVMConstInBoundsGEP(g_str, args, 2);

  gentype_t g;

  if(!gentype(c, type, &g))
    return NULL;

  args[0] = g.desc;
  args[1] = LLVMConstInt(c->i64, len, false);
  args[2] = LLVMConstInt(c->i64, 0, false);
  args[3] = str_ptr;

  LLVMValueRef inst = LLVMConstNamedStruct(g.structure, args, 4);
  LLVMValueRef g_inst = LLVMAddGlobal(c->module, g.structure, "$string");
  LLVMSetInitializer(g_inst, inst);
  LLVMSetGlobalConstant(g_inst, true);
  LLVMSetLinkage(g_inst, LLVMInternalLinkage);

  return g_inst;
}
Ejemplo n.º 16
0
static LLVMValueRef make_trait_list(compile_t* c, gentype_t* g)
{
  // The list is an array of integers.
  uint32_t count = trait_count(c, g);

  // If we have no traits, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0));

  // Sort the trait identifiers.
  size_t tid_size = count * sizeof(uint32_t);
  uint32_t* tid = (uint32_t*)pool_alloc_size(tid_size);

  reachable_type_t* t = reach_type(c->reachable, g->type_name);
  assert(t != NULL);

  size_t i = HASHMAP_BEGIN;
  size_t index = 0;
  reachable_type_t* provide;

  while((provide = reachable_type_cache_next(&t->subtypes, &i)) != NULL)
    tid[index++] = provide->type_id;

  qsort(tid, index, sizeof(uint32_t), cmp_uint32);
  index = unique_uint32(tid, index);

  // Create a constant array of trait identifiers.
  size_t list_size = index * sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(list_size);

  for(i = 0; i < index; i++)
    list[i] = LLVMConstInt(c->i32, tid[i], false);

  count = (uint32_t)index;
  LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count);

  // Create a global to hold the array.
  const char* name = genname_traitlist(g->type_name);
  LLVMTypeRef type = LLVMArrayType(c->i32, count);
  LLVMValueRef global = LLVMAddGlobal(c->module, type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMInternalLinkage);
  LLVMSetInitializer(global, trait_array);

  pool_free_size(tid_size, tid);
  pool_free_size(list_size, list);
  return global;
}
Ejemplo n.º 17
0
static void make_global_descriptor(compile_t* c, gentype_t* g)
{
  // Fetch or create a descriptor type.
  if(g->underlying == TK_TUPLETYPE)
    g->field_count = (int)ast_childcount(g->ast);

  // Check for an existing descriptor.
  g->desc_type = gendesc_type(c, g);
  g->desc = LLVMGetNamedGlobal(c->module, g->desc_name);

  if(g->desc != NULL)
    return;

  g->desc = LLVMAddGlobal(c->module, g->desc_type, g->desc_name);
  LLVMSetGlobalConstant(g->desc, true);
  LLVMSetLinkage(g->desc, LLVMInternalLinkage);
}
Ejemplo n.º 18
0
/**
 * lp_build_assert.
 *
 * Build an assertion in LLVM IR by building a function call to the
 * lp_assert() function above.
 *
 * \param condition should be an 'i1' or 'i32' value
 * \param msg  a string to print if the assertion fails.
 */
LLVMValueRef
lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
                const char *msg)
{
   LLVMModuleRef module;
   LLVMTypeRef arg_types[2];
   LLVMValueRef msg_string, assert_func, params[2], r;

   module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
                            LLVMGetInsertBlock(builder)));

   msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1);

   arg_types[0] = LLVMInt32Type();
   arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);

   /* lookup the lp_assert function */
   assert_func = LLVMGetNamedFunction(module, "lp_assert");

   /* Create the assertion function if not found */
   if (!assert_func) {
      LLVMTypeRef func_type =
         LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0);

      assert_func = LLVMAddFunction(module, "lp_assert", func_type);
      LLVMSetFunctionCallConv(assert_func, LLVMCCallConv);
      LLVMSetLinkage(assert_func, LLVMExternalLinkage);
      LLVMAddGlobalMapping(lp_build_engine, assert_func,
                           func_to_pointer((func_pointer)lp_assert));
   }
   assert(assert_func);

   /* build function call param list */
   params[0] = LLVMBuildZExt(builder, condition, arg_types[0], "");
   params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], "");

   /* check arg types */
   assert(LLVMTypeOf(params[0]) == arg_types[0]);
   assert(LLVMTypeOf(params[1]) == arg_types[1]);

   r = LLVMBuildCall(builder, assert_func, params, 2, "");

   return r;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
LLVMValueRef gen_vecdef(struct node *ast)
{
	LLVMValueRef global, array, init, *ival_list;
	struct node *n;
	int size, initsize, i;

	initsize = count_chain(ast->three);

	if (ast->two)
		size = LLVMConstIntGetZExtValue(codegen(ast->two));
	else
		size = 0;

	if (initsize > size)
		size = initsize;

	ival_list = calloc(sizeof(LLVMValueRef), size);

	if (size > 0 && ival_list == NULL)
		generror("out of memory");

	for (i = 0, n = ast->three; i < initsize; i++, n = n->two)
		/* TODO: handle NAMES (convert global pointer to int) */
		ival_list[initsize - i - 1] = codegen(n->one);

	for (i = initsize; i < size; i++)
		ival_list[i] = CONST(0);

	global = find_or_add_global(ast->one->val);
	array = LLVMAddGlobal(module, TYPE_ARRAY(size), ".gvec");
	LLVMSetLinkage(array, LLVMPrivateLinkage);

	if (initsize)
		init = LLVMConstArray(TYPE_INT, ival_list, size);
	else
		init = LLVMConstNull(TYPE_ARRAY(size));

	LLVMSetInitializer(array, init);
	LLVMSetInitializer(global, LLVMBuildPtrToInt(builder, array, TYPE_INT, ""));

	return NULL;
}
Ejemplo n.º 21
0
static LLVMValueRef make_type_id(compile_t* c, const char* type_name)
{
  // Generate a named constant for the type that is set to a unique integer
  // value for that type.
  const char* name = genname_typeid(type_name);
  LLVMValueRef global = LLVMGetNamedGlobal(c->module, name);

  // Return the constant initialiser, not the global.
  if(global != NULL)
    return LLVMGetInitializer(global);

  global = LLVMAddGlobal(c->module, c->i32, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMInternalLinkage);

  LLVMValueRef id = LLVMConstInt(c->i32, c->next_type_id++, false);
  LLVMSetInitializer(global, id);

  return id;
}
Ejemplo n.º 22
0
static void set_method_external_interface(reach_type_t* t, const char* name)
{
  set_method_external_nominal(t, name);

  size_t i = HASHMAP_BEGIN;
  reach_type_t* sub;
  while((sub = reach_type_cache_next(&t->subtypes, &i)) != NULL)
  {
    reach_method_name_t* n = reach_method_name(sub, name);
    if(n == NULL)
      continue;
    size_t j = HASHMAP_BEGIN;
    reach_method_t* m;
    while((m = reach_methods_next(&n->r_methods, &j)) != NULL)
    {
      LLVMSetFunctionCallConv(m->func, LLVMCCallConv);
      LLVMSetLinkage(m->func, LLVMExternalLinkage);
    }
  }
}
Ejemplo n.º 23
0
static LLVMValueRef make_str(const char *str)
{
	LLVMValueRef global, strval, chars[MAX_STRSIZE];
	const char *p;
	int size = 0;

	/* Skip leading " */
	p = str + 1;
	while (p && size < MAX_STRSIZE - 1)
		chars[size++] = CONST(pack_char(&p));

	chars[size++] = CONST(EOT);

	global = LLVMAddGlobal(module, TYPE_ARRAY(size), ".gstr");
	LLVMSetLinkage(global, LLVMPrivateLinkage);

	strval = LLVMConstArray(TYPE_INT, chars, size);
	LLVMSetInitializer(global, strval);

	return lvalue_to_rvalue(global);
}
Ejemplo n.º 24
0
void genprim_array_serialise_trace(compile_t* c, reach_type_t* t)
{
  // Generate the serialise_trace function.
  t->serialise_trace_fn = codegen_addfun(c, genname_serialise_trace(t->name),
    c->trace_type);

  codegen_startfun(c, t->serialise_trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->serialise_trace_fn, LLVMCCallConv);
  LLVMSetLinkage(t->serialise_trace_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->serialise_trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->serialise_trace_fn, 1);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");

  // Read the size.
  LLVMValueRef size = field_value(c, object, 1);

  // Calculate the size of the element type.
  ast_t* typeargs = ast_childidx(t->ast, 2);
  ast_t* typearg = ast_child(typeargs);
  reach_type_t* t_elem = reach_type(c->reach, typearg);

  size_t abisize = (size_t)LLVMABISizeOfType(c->target_data, t_elem->use_type);
  LLVMValueRef l_size = LLVMConstInt(c->intptr, abisize, false);

  // Reserve space for the array elements.
  LLVMValueRef pointer = field_value(c, object, 3);

  LLVMValueRef args[3];
  args[0] = ctx;
  args[1] = pointer;
  args[2] = LLVMBuildMul(c->builder, size, l_size, "");
  gencall_runtime(c, "pony_serialise_reserve", args, 3, "");

  // Trace the array elements.
  trace_array_elements(c, t, ctx, object, pointer);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 25
0
LLVMValueRef gen_string(compile_t* c, ast_t* ast)
{
  const char* name = ast_name(ast);

  genned_string_t k;
  k.string = name;
  size_t index = HASHMAP_UNKNOWN;
  genned_string_t* string = genned_strings_get(&c->strings, &k, &index);

  if(string != NULL)
    return string->global;

  ast_t* type = ast_type(ast);
  pony_assert(is_literal(type, "String"));
  reach_type_t* t = reach_type(c->reach, type);
  compile_type_t* c_t = (compile_type_t*)t->c_type;

  size_t len = ast_name_len(ast);

  LLVMValueRef args[4];
  args[0] = c_t->desc;
  args[1] = LLVMConstInt(c->intptr, len, false);
  args[2] = LLVMConstInt(c->intptr, len + 1, false);
  args[3] = codegen_string(c, name, len);

  LLVMValueRef inst = LLVMConstNamedStruct(c_t->structure, args, 4);
  LLVMValueRef g_inst = LLVMAddGlobal(c->module, c_t->structure, "");
  LLVMSetInitializer(g_inst, inst);
  LLVMSetGlobalConstant(g_inst, true);
  LLVMSetLinkage(g_inst, LLVMPrivateLinkage);
  LLVMSetUnnamedAddr(g_inst, true);

  string = POOL_ALLOC(genned_string_t);
  string->string = name;
  string->global = g_inst;
  genned_strings_putindex(&c->strings, string, index);

  return g_inst;
}
Ejemplo n.º 26
0
LLVMValueRef
lp_declare_intrinsic(LLVMModuleRef module,
                     const char *name,
                     LLVMTypeRef ret_type,
                     LLVMTypeRef *arg_types,
                     unsigned num_args)
{
   LLVMTypeRef function_type;
   LLVMValueRef function;

   assert(!LLVMGetNamedFunction(module, name));

   function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0);
   function = LLVMAddFunction(module, name, function_type);

   LLVMSetFunctionCallConv(function, LLVMCCallConv);
   LLVMSetLinkage(function, LLVMExternalLinkage);

   assert(LLVMIsDeclaration(function));

   return function;
}
Ejemplo n.º 27
0
void genprim_array_trace(compile_t* c, reach_type_t* t)
{
  codegen_startfun(c, t->trace_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->trace_fn, LLVMCCallConv);
  LLVMSetLinkage(t->trace_fn, LLVMExternalLinkage);
  LLVMValueRef ctx = LLVMGetParam(t->trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->trace_fn, 1);

  // Read the base pointer.
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->use_type, "");
  LLVMValueRef pointer = field_value(c, object, 3);

  // Trace the base pointer.
  LLVMValueRef args[2];
  args[0] = ctx;
  args[1] = pointer;
  gencall_runtime(c, "pony_trace", args, 2, "");

  trace_array_elements(c, t, ctx, object, pointer);
  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 28
0
static void make_global_instance(compile_t* c, reach_type_t* t)
{
  // Not a primitive type.
  if(t->underlying != TK_PRIMITIVE)
    return;

  // No instance for machine word types.
  if(t->primitive != NULL)
    return;

  // Create a unique global instance.
  const char* inst_name = genname_instance(t->name);

  LLVMValueRef args[1];
  args[0] = t->desc;
  LLVMValueRef value = LLVMConstNamedStruct(t->structure, args, 1);

  t->instance = LLVMAddGlobal(c->module, t->structure, inst_name);
  LLVMSetInitializer(t->instance, value);
  LLVMSetGlobalConstant(t->instance, true);
  LLVMSetLinkage(t->instance, LLVMPrivateLinkage);
}
Ejemplo n.º 29
0
static void make_deserialise(compile_t* c, reach_type_t* t)
{
  // Generate the deserialise function.
  t->deserialise_fn = codegen_addfun(c, genname_deserialise(t->name),
    c->trace_type);

  codegen_startfun(c, t->deserialise_fn, NULL, NULL);
  LLVMSetFunctionCallConv(t->deserialise_fn, LLVMCCallConv);
  LLVMSetLinkage(t->deserialise_fn, LLVMExternalLinkage);

  LLVMValueRef ctx = LLVMGetParam(t->deserialise_fn, 0);
  LLVMValueRef arg = LLVMGetParam(t->deserialise_fn, 1);

  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, t->structure_ptr,
    "");

  // At this point, the serialised contents have been copied to the allocated
  // object.
  deserialise(c, t, ctx, object);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);
}
Ejemplo n.º 30
0
static LLVMValueRef make_trait_list(compile_t* c, gentype_t* g)
{
  // The list is an array of integers.
  uint32_t count = trait_count(c, g);
  LLVMTypeRef type = LLVMArrayType(c->i32, count);

  // If we have no traits, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(type, 0));

  // Create a constant array of trait identifiers.
  size_t buf_size = count *sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(buf_size);

  reachable_type_t* t = reach_type(c->reachable, g->type_name);
  assert(t != NULL);

  size_t i = HASHMAP_BEGIN;
  size_t index = 0;
  reachable_type_t* provide;

  while((provide = reachable_type_cache_next(&t->subtypes, &i)) != NULL)
    list[index++] = make_type_id(c, provide->name);

  LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count);

  // Create a global to hold the array.
  const char* name = genname_traitlist(g->type_name);
  LLVMValueRef global = LLVMAddGlobal(c->module, type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMInternalLinkage);
  LLVMSetInitializer(global, trait_array);

  pool_free_size(buf_size, list);
  return global;
}