示例#1
0
LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast)
{
  ast_t* id = ast_child(ast);
  const char* name = ast_name(id);

  // If this local has already been generated, don't create another copy. This
  // can happen when the same ast node is generated more than once, such as
  // the condition block of a while expression.
  LLVMValueRef value = codegen_getlocal(c, name);

  if(value != NULL)
    return GEN_NOVALUE;

  ast_t* type = deferred_reify(c->frame->reify, ast_type(id), c->opt);
  reach_type_t* t = reach_type(c->reach, type);
  ast_free_unattached(type);
  compile_type_t* c_t = (compile_type_t*)t->c_type;

  // All alloca should happen in the entry block of a function.
  LLVMBasicBlockRef this_block = LLVMGetInsertBlock(c->builder);
  LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(codegen_fun(c));
  LLVMValueRef inst = LLVMGetFirstInstruction(entry_block);

  if(inst != NULL)
    LLVMPositionBuilderBefore(c->builder, inst);
  else
    LLVMPositionBuilderAtEnd(c->builder, entry_block);

  LLVMValueRef alloc = LLVMBuildAlloca(c->builder, c_t->mem_type, name);

  // Store the alloca to use when we reference this local.
  codegen_setlocal(c, name, alloc);

  LLVMMetadataRef file = codegen_difile(c);
  LLVMMetadataRef scope = codegen_discope(c);

#if PONY_LLVM >= 700
  uint32_t align_bytes = LLVMABIAlignmentOfType(c->target_data, c_t->mem_type);

  LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope,
    name, strlen(name), file, (unsigned)ast_line(ast), c_t->di_type,
    true, LLVMDIFlagZero, align_bytes * 8);
#else
  LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope, name,
    file, (unsigned)ast_line(ast), c_t->di_type);
#endif

  LLVMMetadataRef expr = LLVMDIBuilderCreateExpression(c->di, NULL, 0);

  LLVMDIBuilderInsertDeclare(c->di, alloc, info, expr,
    (unsigned)ast_line(ast), (unsigned)ast_pos(ast), scope,
    LLVMGetInsertBlock(c->builder));

  // Put the builder back where it was.
  LLVMPositionBuilderAtEnd(c->builder, this_block);
  return GEN_NOTNEEDED;
}
示例#2
0
文件: gentype.c 项目: Praetonus/ponyc
static LLVMMetadataRef make_debug_field(compile_t* c, reach_type_t* t,
  uint32_t i)
{
  const char* name;
  char buf[32];
  unsigned flags = 0;
  uint64_t offset = 0;
  ast_t* ast;

  if(t->underlying != TK_TUPLETYPE)
  {
    ast_t* def = (ast_t*)ast_data(t->ast);
    ast_t* members = ast_childidx(def, 4);
    ast = ast_childidx(members, i);
    name = ast_name(ast_child(ast));

    if(is_name_private(name))
      flags |= DW_FLAG_Private;

    uint32_t extra = 0;

    if(t->underlying != TK_STRUCT)
      extra++;

    if(t->underlying == TK_ACTOR)
      extra++;

    offset = LLVMOffsetOfElement(c->target_data, t->structure, i + extra);
  } else {
    snprintf(buf, 32, "_%d", i + 1);
    name = buf;
    ast = t->ast;
    offset = LLVMOffsetOfElement(c->target_data, t->primitive, i);
  }

  LLVMTypeRef type;
  LLVMMetadataRef di_type;

  if(t->fields[i].embed)
  {
    type = t->fields[i].type->structure;
    di_type = t->fields[i].type->di_type_embed;
  } else {
    type = t->fields[i].type->use_type;
    di_type = t->fields[i].type->di_type;
  }

  uint64_t size = LLVMABISizeOfType(c->target_data, type);
  uint64_t align = LLVMABIAlignmentOfType(c->target_data, type);

  return LLVMDIBuilderCreateMemberType(c->di, c->di_unit, name, t->di_file,
    (unsigned)ast_line(ast), 8 * size, 8 * align, 8 * offset, flags, di_type);
}
示例#3
0
文件: dwarf.c 项目: andymcn/ponyc
static void setup_dwarf(dwarf_t* dwarf, dwarf_meta_t* meta, gentype_t* g,
  bool opaque, bool field)
{
  memset(meta, 0, sizeof(dwarf_meta_t));

  ast_t* ast = g->ast;
  LLVMTypeRef type = g->primitive;

  if(is_machine_word(ast))
  {
    if(is_float(ast))
      meta->flags |= DWARF_FLOAT;
    else if(is_signed(dwarf->opt, ast))
      meta->flags |= DWARF_SIGNED;
    else if(is_bool(ast))
      meta->flags |= DWARF_BOOLEAN;
  }
  else if(is_pointer(ast) || is_maybe(ast) || !is_concrete(ast) ||
    (is_constructable(ast) && field))
  {
    type = g->use_type;
  }
  else if(is_constructable(ast))
  {
    type = g->structure;
  }

  bool defined_type = g->underlying != TK_TUPLETYPE &&
    g->underlying != TK_UNIONTYPE && g->underlying != TK_ISECTTYPE;

  source_t* source;

  if(defined_type)
    ast = (ast_t*)ast_data(ast);

  source = ast_source(ast);
  meta->file = source->file;
  meta->name = g->type_name;
  meta->line = ast_line(ast);
  meta->pos = ast_pos(ast);

  if(!opaque)
  {
    meta->size = LLVMABISizeOfType(dwarf->target_data, type) << 3;
    meta->align = LLVMABIAlignmentOfType(dwarf->target_data, type) << 3;
  }
}
示例#4
0
文件: gentype.c 项目: Praetonus/ponyc
static void make_debug_fields(compile_t* c, reach_type_t* t)
{
  LLVMMetadataRef fields = NULL;

  if(t->field_count > 0)
  {
    size_t buf_size = t->field_count * sizeof(LLVMMetadataRef);
    LLVMMetadataRef* data = (LLVMMetadataRef*)ponyint_pool_alloc_size(
      buf_size);

    for(uint32_t i = 0; i < t->field_count; i++)
      data[i] = make_debug_field(c, t, i);

    fields = LLVMDIBuilderGetOrCreateArray(c->di, data, t->field_count);
    ponyint_pool_free_size(buf_size, data);
  }

  LLVMTypeRef type;

  if(t->underlying != TK_TUPLETYPE)
    type = t->structure;
  else
    type = t->primitive;

  uint64_t size = 0;
  uint64_t align = 0;

  if(type != NULL)
  {
    size = LLVMABISizeOfType(c->target_data, type);
    align = LLVMABIAlignmentOfType(c->target_data, type);
  }

  LLVMMetadataRef di_type = LLVMDIBuilderCreateStructType(c->di, c->di_unit,
    t->name, t->di_file, (unsigned) ast_line(t->ast), 8 * size, 8 * align,
    fields);

  if(t->underlying != TK_TUPLETYPE)
  {
    LLVMMetadataReplaceAllUsesWith(t->di_type_embed, di_type);
    t->di_type_embed = di_type;
  } else {
    LLVMMetadataReplaceAllUsesWith(t->di_type, di_type);
    t->di_type = di_type;
  }
}
示例#5
0
文件: gentype.c 项目: Praetonus/ponyc
static void make_debug_basic(compile_t* c, reach_type_t* t)
{
  uint64_t size = LLVMABISizeOfType(c->target_data, t->primitive);
  uint64_t align = LLVMABIAlignmentOfType(c->target_data, t->primitive);
  unsigned encoding;

  if(is_bool(t->ast))
  {
    encoding = DW_ATE_boolean;
  } else if(is_float(t->ast)) {
    encoding = DW_ATE_float;
  } else if(is_signed(t->ast)) {
    encoding = DW_ATE_signed;
  } else {
    encoding = DW_ATE_unsigned;
  }

  t->di_type = LLVMDIBuilderCreateBasicType(c->di, t->name,
    8 * size, 8 * align, encoding);
}
/* TargetData.t -> Llvm.lltype -> int */
CAMLprim value llvm_abi_align(LLVMTargetDataRef TD, LLVMTypeRef Ty) {
    return Val_int(LLVMABIAlignmentOfType(TD, Ty));
}
示例#7
0
/* Llvm.lltype -> DataLayout.t -> int */
CAMLprim value llvm_datalayout_abi_align(LLVMTypeRef Ty, value DL) {
  return Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Ty));
}