コード例 #1
0
ファイル: genreference.c プロジェクト: dleonard0/ponyc
LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast)
{
  ast_t* id = ast_child(ast);
  ast_t* type = ast_type(id);
  gentype_t g;

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

  // 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);

  const char* name = ast_name(id);
  LLVMValueRef l_value = LLVMBuildAlloca(c->builder, g.use_type, name);

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

  // Emit debug info for local variable declaration.
  dwarf_local(&c->dwarf, ast, g.type_name, entry_block, inst, l_value);

  // Put the builder back where it was.
  LLVMPositionBuilderAtEnd(c->builder, this_block);
  return GEN_NOVALUE;
}
コード例 #2
0
ファイル: ac_llvm_util.c プロジェクト: daniel-schuermann/mesa
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;
}
コード例 #3
0
ファイル: attributes.c プロジェクト: Tauril/llvm
int llvm_test_callsite_attributes(void) {
  LLVMEnablePrettyStackTrace();

  LLVMModuleRef M = llvm_load_module(false, true);

  LLVMValueRef F = LLVMGetFirstFunction(M);
  while (F) {
    LLVMBasicBlockRef BB;
    for (BB = LLVMGetFirstBasicBlock(F); BB; BB = LLVMGetNextBasicBlock(BB)) {
      LLVMValueRef I;
      for (I = LLVMGetFirstInstruction(BB); I; I = LLVMGetNextInstruction(I)) {
        if (LLVMIsACallInst(I)) {
          // Read attributes
          int Idx, ParamCount;
          for (Idx = LLVMAttributeFunctionIndex,
              ParamCount = LLVMCountParams(F);
               Idx <= ParamCount; ++Idx) {
            int AttrCount = LLVMGetCallSiteAttributeCount(I, Idx);
            LLVMAttributeRef *Attrs = (LLVMAttributeRef *)malloc(
                AttrCount * sizeof(LLVMAttributeRef));
            assert(Attrs);
            LLVMGetCallSiteAttributes(I, Idx, Attrs);
            free(Attrs);
          }
        }
      }
    }

    F = LLVMGetNextFunction(F);
  }

  LLVMDisposeModule(M);

  return 0;
}
コード例 #4
0
ファイル: genreference.c プロジェクト: dipinhora/ponyc
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;
}
コード例 #5
0
ファイル: gencontrol.c プロジェクト: Sendence/ponyc
LLVMValueRef gen_break(compile_t* c, ast_t* ast)
{
  ast_t* body = ast_child(ast);

  LLVMBasicBlockRef target;

  if(ast_id(body) == TK_NONE)
  {
    target = c->frame->break_novalue_target;
  } else {
    ast_t* body_type = ast_type(body);

    // Get the break target.
    target = c->frame->break_target;

    // Get the phi node.
    LLVMValueRef post_phi = LLVMGetFirstInstruction(target);
    bool needed = (post_phi != NULL) && LLVMIsAPHINode(post_phi);

    // Build the break expression.
    LLVMValueRef value = gen_expr(c, body);

    if(needed)
    {
      // Cast it to the phi type if we need to.
      LLVMTypeRef phi_type = LLVMTypeOf(post_phi);
      value = gen_assign_cast(c, phi_type, value, body_type);
    }

    if(value == NULL)
      return NULL;

    // Add break value to the post block phi node.
    if(needed)
    {
      LLVMBasicBlockRef insert_block = LLVMGetInsertBlock(c->builder);
      LLVMAddIncoming(post_phi, &value, &insert_block, 1);
    }
  }

  // Jump to the break target.
  codegen_scope_lifetime_end(c);
  codegen_debugloc(c, ast);
  LLVMBuildBr(c->builder, target);
  codegen_debugloc(c, NULL);

  return GEN_NOVALUE;
}
コード例 #6
0
ファイル: genreference.c プロジェクト: Sendence/ponyc
LLVMValueRef gen_localdecl(compile_t* c, ast_t* ast)
{
  ast_t* id = ast_child(ast);
  ast_t* type = ast_type(id);
  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;

  reach_type_t* t = reach_type(c->reach, 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, t->use_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);

  LLVMMetadataRef info = LLVMDIBuilderCreateAutoVariable(c->di, scope, name,
    file, (unsigned)ast_line(ast), t->di_type);

  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_NOVALUE;
}
コード例 #7
0
ファイル: lp_bld_flow.c プロジェクト: ChristophHaag/mesa-mesa
static LLVMBuilderRef
create_builder_at_entry(struct gallivm_state *gallivm)
{
   LLVMBuilderRef builder = gallivm->builder;
   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);

   if (first_instr) {
      LLVMPositionBuilderBefore(first_builder, first_instr);
   } else {
      LLVMPositionBuilderAtEnd(first_builder, first_block);
   }

   return first_builder;
}
コード例 #8
0
ファイル: lp_bld_type.c プロジェクト: ChillyWillyGuru/RSXGL
/**
 * Count the number of instructions in a function.
 */
unsigned
lp_build_count_instructions(LLVMValueRef function)
{
   unsigned num_instrs = 0;
   LLVMBasicBlockRef block;

   block = LLVMGetFirstBasicBlock(function);
   while (block) {
      LLVMValueRef instr;
      instr = LLVMGetFirstInstruction(block);
      while (instr) {
         ++num_instrs;

         instr = LLVMGetNextInstruction(instr);
      }
      block = LLVMGetNextBasicBlock(block);
   }

   return num_instrs;
}
コード例 #9
0
ファイル: module.c プロジェクト: BlueRiverInteractive/llvm
int module_list_functions(void) {
  LLVMModuleRef M = load_module(false, false);
  LLVMValueRef f;

  f = LLVMGetFirstFunction(M);
  while (f) {
    if (LLVMIsDeclaration(f)) {
      printf("FunctionDeclaration: %s\n", LLVMGetValueName(f));
    } else {
      LLVMBasicBlockRef bb;
      LLVMValueRef isn;
      unsigned nisn = 0;
      unsigned nbb = 0;

      printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f),
             LLVMCountBasicBlocks(f));

      for (bb = LLVMGetFirstBasicBlock(f); bb;
           bb = LLVMGetNextBasicBlock(bb)) {
        nbb++;
        for (isn = LLVMGetFirstInstruction(bb); isn;
             isn = LLVMGetNextInstruction(isn)) {
          nisn++;
          if (LLVMIsACallInst(isn)) {
            LLVMValueRef callee =
                LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1);
            printf(" calls: %s\n", LLVMGetValueName(callee));
          }
        }
      }
      printf(" #isn: %u\n", nisn);
      printf(" #bb: %u\n\n", nbb);
    }
    f = LLVMGetNextFunction(f);
  }

  LLVMDisposeModule(M);

  return 0;
}
コード例 #10
0
ファイル: codegen.c プロジェクト: Perelandric/ponyc
LLVMValueRef codegen_ctx(compile_t* c)
{
  compile_frame_t* frame = c->frame;

  while(!frame->is_function)
    frame = frame->prev;

  if(frame->ctx == NULL)
  {
    LLVMBasicBlockRef this_block = LLVMGetInsertBlock(c->builder);
    LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(frame->fun);
    LLVMValueRef inst = LLVMGetFirstInstruction(entry_block);

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

    frame->ctx = gencall_runtime(c, "pony_ctx", NULL, 0, "");
    LLVMPositionBuilderAtEnd(c->builder, this_block);
  }

  return frame->ctx;
}
コード例 #11
0
ファイル: ac_llvm_build.c プロジェクト: ndesh26/Mesa
void ac_optimize_vs_outputs(struct ac_llvm_context *ctx,
			    LLVMValueRef main_fn,
			    uint8_t *vs_output_param_offset,
			    uint32_t num_outputs,
			    uint8_t *num_param_exports)
{
	LLVMBasicBlockRef bb;
	bool removed_any = false;
	struct ac_vs_exports exports;

	exports.num = 0;

	/* Process all LLVM instructions. */
	bb = LLVMGetFirstBasicBlock(main_fn);
	while (bb) {
		LLVMValueRef inst = LLVMGetFirstInstruction(bb);

		while (inst) {
			LLVMValueRef cur = inst;
			inst = LLVMGetNextInstruction(inst);
			struct ac_vs_exp_inst exp;

			if (LLVMGetInstructionOpcode(cur) != LLVMCall)
				continue;

			LLVMValueRef callee = ac_llvm_get_called_value(cur);

			if (!ac_llvm_is_function(callee))
				continue;

			const char *name = LLVMGetValueName(callee);
			unsigned num_args = LLVMCountParams(callee);

			/* Check if this is an export instruction. */
			if ((num_args != 9 && num_args != 8) ||
			    (strcmp(name, "llvm.SI.export") &&
			     strcmp(name, "llvm.amdgcn.exp.f32")))
				continue;

			LLVMValueRef arg = LLVMGetOperand(cur, AC_EXP_TARGET);
			unsigned target = LLVMConstIntGetZExtValue(arg);

			if (target < V_008DFC_SQ_EXP_PARAM)
				continue;

			target -= V_008DFC_SQ_EXP_PARAM;

			/* Parse the instruction. */
			memset(&exp, 0, sizeof(exp));
			exp.offset = target;
			exp.inst = cur;

			for (unsigned i = 0; i < 4; i++) {
				LLVMValueRef v = LLVMGetOperand(cur, AC_EXP_OUT0 + i);

				exp.chan[i].value = v;

				if (LLVMIsUndef(v)) {
					exp.chan[i].type = AC_IR_UNDEF;
				} else if (LLVMIsAConstantFP(v)) {
					LLVMBool loses_info;
					exp.chan[i].type = AC_IR_CONST;
					exp.chan[i].const_float =
						LLVMConstRealGetDouble(v, &loses_info);
				} else {
					exp.chan[i].type = AC_IR_VALUE;
				}
			}

			/* Eliminate constant and duplicated PARAM exports. */
			if (ac_eliminate_const_output(vs_output_param_offset,
						      num_outputs, &exp) ||
			    ac_eliminate_duplicated_output(vs_output_param_offset,
							   num_outputs, &exports,
							   &exp)) {
				removed_any = true;
			} else {
				exports.exp[exports.num++] = exp;
			}
		}
		bb = LLVMGetNextBasicBlock(bb);
	}

	/* Remove holes in export memory due to removed PARAM exports.
	 * This is done by renumbering all PARAM exports.
	 */
	if (removed_any) {
		uint8_t old_offset[VARYING_SLOT_MAX];
		unsigned out, i;

		/* Make a copy of the offsets. We need the old version while
		 * we are modifying some of them. */
		memcpy(old_offset, vs_output_param_offset,
		       sizeof(old_offset));

		for (i = 0; i < exports.num; i++) {
			unsigned offset = exports.exp[i].offset;

			/* Update vs_output_param_offset. Multiple outputs can
			 * have the same offset.
			 */
			for (out = 0; out < num_outputs; out++) {
				if (old_offset[out] == offset)
					vs_output_param_offset[out] = i;
			}

			/* Change the PARAM offset in the instruction. */
			LLVMSetOperand(exports.exp[i].inst, AC_EXP_TARGET,
				       LLVMConstInt(ctx->i32,
						    V_008DFC_SQ_EXP_PARAM + i, 0));
		}
		*num_param_exports = exports.num;
	}
}