Exemple #1
1
void gendesc_table(compile_t* c)
{
  uint32_t len = c->reach->next_type_id;
  size_t size = len * sizeof(LLVMValueRef);
  LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(size);

  reach_type_t* t;
  size_t i = HASHMAP_BEGIN;

  while((t = reach_types_next(&c->reach->types, &i)) != NULL)
  {
    LLVMValueRef desc;

    if(t->desc != NULL)
      desc = LLVMBuildBitCast(c->builder, t->desc, c->descriptor_ptr, "");
    else
      desc = LLVMConstNull(c->descriptor_ptr);

    args[t->type_id] = desc;
  }

  LLVMTypeRef type = LLVMArrayType(c->descriptor_ptr, len);
  LLVMValueRef table = LLVMAddGlobal(c->module, type, "__DescTable");
  LLVMValueRef value = LLVMConstArray(c->descriptor_ptr, args, len);
  LLVMSetInitializer(table, value);
  LLVMSetGlobalConstant(table, true);

  LLVMValueRef table_size = LLVMAddGlobal(c->module, c->intptr,
    "__DescTableSize");
  LLVMSetInitializer(table_size, LLVMConstInt(c->intptr, len, false));
  LLVMSetGlobalConstant(table_size, true);

  ponyint_pool_free_size(size, args);
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
0
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);
}
Exemple #5
0
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();
}
Exemple #6
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;
}
Exemple #7
0
static void *find_or_add_global(const char *name)
{
	LLVMValueRef global;

	global = LLVMGetNamedGlobal(module, name);

	if (global == NULL)
		global = LLVMAddGlobal(module, TYPE_INT, name);

	return global;
}
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;
}
Exemple #9
0
static LLVMValueRef 
translateStringLit(ASTNode *Node) {
  int Length = strlen(Node->Value);

  LLVMValueRef GlobVar = LLVMAddGlobal(Module, LLVMArrayType(LLVMInt8Type(), Length+1), "global.var");
  LLVMSetInitializer(GlobVar, LLVMConstString(Node->Value, Length, 0));

  LLVMValueRef LocalVar = LLVMBuildAlloca(Builder, LLVMArrayType(LLVMInt8Type(), Length+1), "local.string.");
  LLVMValueRef LocalI8  = LLVMBuildBitCast(Builder, LocalVar, LLVMPointerType(LLVMInt8Type(), 0), "");
  copyMemory(LocalI8, GlobVar, getSConstInt(Length+1));
  return wrapValue(LocalI8);
}
Exemple #10
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);
}
Exemple #11
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;
}
Exemple #12
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;
}
Exemple #13
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);
}
Exemple #14
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;
}
Exemple #15
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;
}
Exemple #16
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);
}
Exemple #17
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;
}
Exemple #18
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);
}
Exemple #19
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;
}
Exemple #20
0
  while(count < len)
  {
    t = reach_types_next(&c->reach->types, &i);
    pony_assert(t != NULL);

    if(t->is_trait || (t->underlying == TK_STRUCT))
      continue;

    uint32_t type_id = t->type_id;
    if((type_id % 4) == 0)
    {
      size_t type_size = (size_t)LLVMABISizeOfType(c->target_data, t->use_type);
      args[type_id >> 2] = LLVMConstInt(c->i32, type_size, false);
      count++;
    }
  }

  LLVMTypeRef type = LLVMArrayType(c->i32, len);
  LLVMValueRef table = LLVMAddGlobal(c->module, type, "__NumSizeTable");
  LLVMValueRef value = LLVMConstArray(c->i32, args, len);
  LLVMSetInitializer(table, value);
  LLVMSetGlobalConstant(table, true);
  LLVMSetAlignment(table, 4);
  LLVMSetLinkage(table, LLVMPrivateLinkage);

  ponyint_pool_free_size(size, args);

  return table;
}