예제 #1
0
LLVMModuleRef radeon_llvm_get_kernel_module(LLVMContextRef ctx, unsigned index,
		const char *bitcode, unsigned bitcode_len)
{
	LLVMModuleRef mod;
	unsigned num_kernels;
	LLVMValueRef *kernel_metadata;
	unsigned i;

	mod = radeon_llvm_parse_bitcode(ctx, bitcode, bitcode_len);
	num_kernels = LLVMGetNamedMetadataNumOperands(mod, "opencl.kernels");
	kernel_metadata = MALLOC(num_kernels * sizeof(LLVMValueRef));
	LLVMGetNamedMetadataOperands(mod, "opencl.kernels", kernel_metadata);
	for (i = 0; i < num_kernels; i++) {
		LLVMValueRef kernel_signature, *kernel_function;
		unsigned num_kernel_md_operands;
		if (i == index) {
			continue;
		}
		kernel_signature = kernel_metadata[i];
		num_kernel_md_operands = LLVMGetMDNodeNumOperands(kernel_signature);
		kernel_function = MALLOC(num_kernel_md_operands * sizeof (LLVMValueRef));
		LLVMGetMDNodeOperands(kernel_signature, kernel_function);
		LLVMDeleteFunction(*kernel_function);
		FREE(kernel_function);
	}
	FREE(kernel_metadata);
	radeon_llvm_optimize(mod);
	return mod;
}
예제 #2
0
void
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
   struct lp_fragment_shader *shader = fs;
   struct lp_fragment_shader_variant *variant;

   assert(fs != llvmpipe->fs);

   variant = shader->variants;
   while(variant) {
      struct lp_fragment_shader_variant *next = variant->next;

      if(variant->function) {
         if(variant->jit_function)
            LLVMFreeMachineCodeForFunction(screen->engine, variant->function);
         LLVMDeleteFunction(variant->function);
      }

      FREE(variant);

      variant = next;
   }

   FREE((void *) shader->base.tokens);
   FREE(shader);
}
예제 #3
0
static void
remove_shader_variant(struct llvmpipe_context *lp,
                      struct lp_fragment_shader_variant *variant)
{
   struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
   unsigned i;

   if (gallivm_debug & GALLIVM_DEBUG_IR) {
      debug_printf("llvmpipe: del fs #%u var #%u v created #%u v cached #%u v total cached #%u\n",
                    variant->shader->no, variant->no, variant->shader->variants_created,
                    variant->shader->variants_cached, lp->nr_fs_variants);
   }
   for (i = 0; i < Elements(variant->function); i++) {
      if (variant->function[i]) {
         if (variant->jit_function[i])
            LLVMFreeMachineCodeForFunction(screen->engine,
                                           variant->function[i]);
         LLVMDeleteFunction(variant->function[i]);
      }
   }
   remove_from_list(&variant->list_item_local);
   variant->shader->variants_cached--;
   remove_from_list(&variant->list_item_global);
   lp->nr_fs_variants--;
   FREE(variant);
}
예제 #4
0
파일: gentype.c 프로젝트: nunb/ponyc
static bool make_trace(compile_t* c, gentype_t* g)
{
  // Do nothing if we have no fields.
  if(g->field_count == 0)
    return true;

  if(g->underlying == TK_CLASS)
  {
    // Special case the array trace function.
    AST_GET_CHILDREN(g->ast, pkg, id);
    const char* package = ast_name(pkg);
    const char* name = ast_name(id);

    if((package == c->str_builtin) && (name == c->str_Array))
    {
      genprim_array_trace(c, g);
      return true;
    }
  }

  // Create a trace function.
  const char* trace_name = genname_trace(g->type_name);
  LLVMValueRef trace_fn = codegen_addfun(c, trace_name, c->trace_type);

  codegen_startfun(c, trace_fn, false);
  LLVMSetFunctionCallConv(trace_fn, LLVMCCallConv);

  LLVMValueRef ctx = LLVMGetParam(trace_fn, 0);
  LLVMValueRef arg = LLVMGetParam(trace_fn, 1);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, g->structure_ptr,
    "object");

  // If we don't ever trace anything, delete this function.
  int extra = 0;

  // Non-structs have a type descriptor.
  if(g->underlying != TK_STRUCT)
    extra++;

  // Actors have a pad.
  if(g->underlying == TK_ACTOR)
    extra++;

  bool need_trace = trace_fields(c, g, ctx, object, extra);

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);

  if(!need_trace)
    LLVMDeleteFunction(trace_fn);

  return true;
}
/**
 * Free the function (and its machine code).
 */
void
gallivm_free_function(struct gallivm_state *gallivm,
                      LLVMValueRef func,
                      const void *code)
{
#if !USE_MCJIT
   if (code) {
      LLVMFreeMachineCodeForFunction(gallivm->engine, func);
   }

   LLVMDeleteFunction(func);
#endif
}
예제 #6
0
파일: JIT.cpp 프로젝트: hoangt/tool_axe
void JITImpl::reclaimUnreachableFunctions(JITCoreInfo &coreInfo)
{
  std::vector<uint32_t> &unreachableFunctions = coreInfo.unreachableFunctions;
  std::map<uint32_t,JITFunctionInfo*> &functionMap = coreInfo.functionMap;
  for (std::vector<uint32_t>::iterator it = unreachableFunctions.begin(),
       e = unreachableFunctions.end(); it != e; ++it) {
    std::map<uint32_t,JITFunctionInfo*>::iterator entry = functionMap.find(*it);
    if (entry == functionMap.end())
      continue;
    LLVMValueRef value = entry->second->value;
    LLVMFreeMachineCodeForFunction(executionEngine, value);
    LLVMReplaceAllUsesWith(value, LLVMGetUndef(LLVMTypeOf(value)));
    LLVMDeleteFunction(value);
    delete entry->second;
    functionMap.erase(entry);
  }
  unreachableFunctions.clear();
}
예제 #7
0
void
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
   struct lp_fragment_shader *shader = fs;
   struct lp_fragment_shader_variant *variant;

   assert(fs != llvmpipe->fs);
   (void) llvmpipe;

   /*
    * XXX: we need to flush the context until we have some sort of reference
    * counting in fragment shaders as they may still be binned
    */
   draw_flush(llvmpipe->draw);
   lp_setup_flush(llvmpipe->setup, 0);

   variant = shader->variants;
   while(variant) {
      struct lp_fragment_shader_variant *next = variant->next;
      unsigned i;

      for (i = 0; i < Elements(variant->function); i++) {
         if (variant->function[i]) {
            if (variant->jit_function[i])
               LLVMFreeMachineCodeForFunction(screen->engine,
                                              variant->function[i]);
            LLVMDeleteFunction(variant->function[i]);
         }
      }

      FREE(variant);

      variant = next;
   }

   FREE((void *) shader->base.tokens);
   FREE(shader);
}
예제 #8
0
파일: gentype.c 프로젝트: volth/ponyc
static bool make_trace(compile_t* c, gentype_t* g)
{
  // Do nothing if we have no fields.
  if(g->field_count == 0)
    return true;

  if(g->underlying == TK_CLASS)
  {
    // Special case the array trace function.
    AST_GET_CHILDREN(g->ast, pkg, id);
    const char* package = ast_name(pkg);
    const char* name = ast_name(id);

    if((package == c->str_1) && (name == c->str_Array))
    {
      genprim_array_trace(c, g);
      return true;
    }
  }

  // Create a trace function.
  const char* trace_name = genname_trace(g->type_name);
  LLVMValueRef trace_fn = codegen_addfun(c, trace_name, c->trace_type);

  codegen_startfun(c, trace_fn, false);
  LLVMSetFunctionCallConv(trace_fn, LLVMCCallConv);

  LLVMValueRef arg = LLVMGetParam(trace_fn, 0);
  LLVMValueRef object = LLVMBuildBitCast(c->builder, arg, g->structure_ptr,
    "object");

  // If we don't ever trace anything, delete this function.
  bool need_trace;

  if(g->underlying == TK_TUPLETYPE)
  {
    // Create another function that traces the tuple members.
    const char* trace_tuple_name = genname_tracetuple(g->type_name);
    LLVMTypeRef trace_tuple_type = LLVMFunctionType(c->void_type,
      &g->primitive, 1, false);
    LLVMValueRef trace_tuple_fn = codegen_addfun(c, trace_tuple_name,
      trace_tuple_type);

    codegen_startfun(c, trace_tuple_fn, false);
    LLVMSetFunctionCallConv(trace_tuple_fn, LLVMCCallConv);

    LLVMValueRef arg = LLVMGetParam(trace_tuple_fn, 0);
    need_trace = trace_elements(c, g, arg);

    LLVMBuildRetVoid(c->builder);
    codegen_finishfun(c);

    if(need_trace)
    {
      // Get the tuple primitive.
      LLVMValueRef tuple_ptr = LLVMBuildStructGEP(c->builder, object, 1, "");
      LLVMValueRef tuple = LLVMBuildLoad(c->builder, tuple_ptr, "");

      // Call the tuple trace function with the unboxed primitive type.
      LLVMBuildCall(c->builder, trace_tuple_fn, &tuple, 1, "");
    } else {
      LLVMDeleteFunction(trace_tuple_fn);
    }
  } else {
    int extra = 1;

    // Actors have a pad.
    if(g->underlying == TK_ACTOR)
      extra++;

    need_trace = trace_fields(c, g, object, extra);
  }

  LLVMBuildRetVoid(c->builder);
  codegen_finishfun(c);

  if(!need_trace)
    LLVMDeleteFunction(trace_fn);

  return true;
}
예제 #9
0
파일: function.c 프로젝트: dasfaha/sky
// Generates the function prototype but overrides the name. This is used by
// the metadata to create external APIs to C.
//
// node          - The node.
// module        - The compilation unit this node is a part of.
// function_name - The name of the function to generate.
// is_external   - A flag stating if this is an external prototype.
// value         - A pointer to where the LLVM value should be returned to.
//
// Returns 0 if successful, otherwise returns -1.
int qip_ast_function_codegen_prototype_with_name(qip_ast_node *node,
                                                 qip_module *module,
                                                 bstring function_name,
                                                 bool is_external,
                                                 LLVMValueRef *value)
{
    int rc;
    unsigned int i;
    LLVMValueRef func = NULL;
    bstring arg_type_name = NULL;
    bstring return_type_name = NULL;

    LLVMContextRef context = LLVMGetModuleContext(module->llvm_module);

    // Determine the number of arguments. External calls always have an
    // additional first argument that is the module reference.
    unsigned int offset = (is_external ? 1 : 0);
    unsigned int total_arg_count = node->function.arg_count + offset;

    // Check for an existing prototype.
    func = LLVMGetNamedFunction(module->llvm_module, bdata(function_name));
    
    // If a prototype exists then simply verify it matches and return it.
    if(func != NULL) {
        check(LLVMCountBasicBlocks(func) == 0, "Illegal function redefinition");
        check(LLVMCountParams(func) == total_arg_count, "Function prototype already exists with different arguments");
    }
    // If there is no prototype then create one.
    else {
        // Dynamically generate the return type of the function if it is missing.
        if(node->function.return_type == NULL) {
            rc = qip_ast_function_generate_return_type(node, module);
            check(rc == 0, "Unable to generate return type for function");
        }

        // Create a list of function argument types.
        qip_ast_node *arg;
        LLVMTypeRef *params = malloc(sizeof(LLVMTypeRef) * total_arg_count);

        // Create module argument for external calls.
        if(is_external) {
            params[0] = LLVMPointerType(LLVMInt8TypeInContext(context), 0);
        }

        // Create arguments.
        for(i=0; i<node->function.arg_count; i++) {
            qip_ast_node *arg = node->function.args[i];
            LLVMTypeRef param = NULL;
            rc = qip_module_get_type_ref(module, arg->farg.var_decl->var_decl.type, NULL, &param);
            check(rc == 0, "Unable to determine function argument type");
        
            // Pass argument as reference if this is a complex type.
            if(qip_module_is_complex_type(module, param)) {
                params[i+offset] = LLVMPointerType(param, 0);
            }
            // Otherwise pass it by value.
            else {
                params[i+offset] = param;
            }
        }

        // Determine return type.
        LLVMTypeRef return_type;
        rc = qip_module_get_type_ref(module, node->function.return_type, NULL, &return_type);
        check(rc == 0, "Unable to determine function return type");

        if(qip_module_is_complex_type(module, return_type)) {
            return_type = LLVMPointerType(return_type, 0);
        }

        // Create function type.
        LLVMTypeRef funcType = LLVMFunctionType(return_type, params, total_arg_count, false);
        check(funcType != NULL, "Unable to create function type");

        // Create function.
        func = LLVMAddFunction(module->llvm_module, bdata(function_name), funcType);
        check(func != NULL, "Unable to create function");
    
        // Assign module argument name.
        if(is_external) {
            LLVMSetValueName(LLVMGetParam(func, 0), "module");
        }
    
        // Assign names to function arguments.
        for(i=0; i<node->function.arg_count; i++) {
            arg = node->function.args[i];
            LLVMValueRef param = LLVMGetParam(func, i+offset);
            LLVMSetValueName(param, bdata(arg->farg.var_decl->var_decl.name));
        }
    }
    
    // Return function prototype;
    *value = func;
    
    bdestroy(arg_type_name);
    bdestroy(return_type_name);
    return 0;

error:
    bdestroy(arg_type_name);
    bdestroy(return_type_name);
    if(func) LLVMDeleteFunction(func);
    *value = NULL;
    return -1;
}