mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 13:00:09 +01:00
llvmpipe: Annotate functions with debug information
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28613>
This commit is contained in:
parent
95a68076a7
commit
d6ca378f1b
12 changed files with 178 additions and 1 deletions
|
|
@ -1633,6 +1633,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
|
|||
if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
|
||||
lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS);
|
||||
|
||||
lp_function_add_debug_info(gallivm, variant_func, func_type);
|
||||
|
||||
if (gallivm->cache && gallivm->cache->data_size) {
|
||||
gallivm_stub_func(gallivm, variant_func);
|
||||
return;
|
||||
|
|
@ -2365,6 +2367,8 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
|
|||
if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
|
||||
lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS);
|
||||
|
||||
lp_function_add_debug_info(gallivm, variant_func, func_type);
|
||||
|
||||
if (gallivm->cache && gallivm->cache->data_size) {
|
||||
gallivm_stub_func(gallivm, variant_func);
|
||||
return;
|
||||
|
|
@ -2958,6 +2962,9 @@ draw_tcs_llvm_generate(struct draw_llvm *llvm,
|
|||
}
|
||||
}
|
||||
|
||||
lp_function_add_debug_info(gallivm, variant_func, func_type);
|
||||
lp_function_add_debug_info(gallivm, variant_coro, coro_func_type);
|
||||
|
||||
if (gallivm->cache && gallivm->cache->data_size) {
|
||||
gallivm_stub_func(gallivm, variant_func);
|
||||
gallivm_stub_func(gallivm, variant_coro);
|
||||
|
|
@ -3521,6 +3528,8 @@ draw_tes_llvm_generate(struct draw_llvm *llvm,
|
|||
if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
|
||||
lp_add_function_attr(variant_func, i + 1, LP_FUNC_ATTR_NOALIAS);
|
||||
|
||||
lp_function_add_debug_info(gallivm, variant_func, func_type);
|
||||
|
||||
if (gallivm->cache && gallivm->cache->data_size) {
|
||||
gallivm_stub_func(gallivm, variant_func);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -47,13 +47,16 @@
|
|||
#include "util/u_debug.h"
|
||||
|
||||
#include "lp_bld_debug.h"
|
||||
#include "lp_bld_intr.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <llvm/BinaryFormat/Dwarf.h>
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
/**
|
||||
* Check alignment.
|
||||
|
|
@ -279,3 +282,121 @@ lp_profile(LLVMValueRef func, const void *code)
|
|||
(void)code;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
LLVMMetadataRef
|
||||
lp_bld_debug_info_type(gallivm_state *gallivm, LLVMTypeRef type)
|
||||
{
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
|
||||
if (kind == LLVMHalfTypeKind)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "float16_t", strlen("float16_t"), 16, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
|
||||
if (kind == LLVMFloatTypeKind)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "float", strlen("float"), 32, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
|
||||
if (kind == LLVMDoubleTypeKind)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "double", strlen("double"), 64, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
|
||||
|
||||
if (kind == LLVMIntegerTypeKind) {
|
||||
uint32_t bit_size = LLVMGetIntTypeWidth(type);
|
||||
if (bit_size == 1)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "bool", strlen("bool"), 1, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
|
||||
if (bit_size == 8)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "int8_t", strlen("int8_t"), 8, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
|
||||
if (bit_size == 16)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "int16_t", strlen("int16_t"), 16, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
|
||||
if (bit_size == 32)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "int32_t", strlen("int32_t"), 32, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
|
||||
if (bit_size == 64)
|
||||
return LLVMDIBuilderCreateBasicType(
|
||||
gallivm->di_builder, "int64_t", strlen("int64_t"), 64, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
|
||||
}
|
||||
|
||||
if (kind == LLVMFunctionTypeKind) {
|
||||
uint32_t num_params = LLVMCountParamTypes(type);
|
||||
|
||||
LLVMTypeRef *param_types = (LLVMTypeRef *)calloc(num_params, sizeof(LLVMTypeRef));
|
||||
LLVMMetadataRef *di_param_types = (LLVMMetadataRef *)calloc(num_params + 1, sizeof(LLVMMetadataRef));
|
||||
|
||||
LLVMGetParamTypes(type, param_types);
|
||||
|
||||
di_param_types[0] = lp_bld_debug_info_type(gallivm, LLVMGetReturnType(type));
|
||||
for (uint32_t i = 0; i < num_params; i++)
|
||||
di_param_types[i + 1] = lp_bld_debug_info_type(gallivm, param_types[i]);
|
||||
|
||||
LLVMMetadataRef function = LLVMDIBuilderCreateSubroutineType(
|
||||
gallivm->di_builder, gallivm->file, di_param_types, num_params + 1, LLVMDIFlagZero);
|
||||
|
||||
free(param_types);
|
||||
free(di_param_types);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
if (kind == LLVMArrayTypeKind) {
|
||||
uint32_t count = LLVMGetArrayLength(type);
|
||||
LLVMMetadataRef subrange = LLVMDIBuilderGetOrCreateSubrange(gallivm->di_builder, 0, count);
|
||||
LLVMMetadataRef element_type = lp_bld_debug_info_type(gallivm, LLVMGetElementType(type));
|
||||
return LLVMDIBuilderCreateArrayType(
|
||||
gallivm->di_builder, count, 0, element_type, &subrange, 1);
|
||||
}
|
||||
|
||||
if (kind == LLVMPointerTypeKind) {
|
||||
return LLVMDIBuilderCreatePointerType(
|
||||
gallivm->di_builder, NULL, sizeof(void *) * 8, 0, 0, "", 0);
|
||||
}
|
||||
|
||||
if (kind == LLVMVectorTypeKind) {
|
||||
uint32_t count = LLVMGetVectorSize(type);
|
||||
LLVMMetadataRef subrange = LLVMDIBuilderGetOrCreateSubrange(gallivm->di_builder, 0, count);
|
||||
LLVMMetadataRef element_type = lp_bld_debug_info_type(gallivm, LLVMGetElementType(type));
|
||||
return LLVMDIBuilderCreateVectorType(
|
||||
gallivm->di_builder, count, 0, element_type, &subrange, 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t global_shader_index = 0;
|
||||
|
||||
|
||||
void
|
||||
lp_function_add_debug_info(gallivm_state *gallivm, LLVMValueRef func, LLVMTypeRef func_type)
|
||||
{
|
||||
if (!gallivm->di_builder)
|
||||
return;
|
||||
|
||||
if (!gallivm->file) {
|
||||
uint32_t shader_index = p_atomic_add_return(&global_shader_index, 1);
|
||||
|
||||
std::filesystem::create_directory(LP_NIR_SHADER_DUMP_DIR);
|
||||
|
||||
asprintf(&gallivm->file_name, "%s/%u.nir", LP_NIR_SHADER_DUMP_DIR, shader_index);
|
||||
|
||||
gallivm->file = LLVMDIBuilderCreateFile(gallivm->di_builder, gallivm->file_name, strlen(gallivm->file_name), ".", 1);
|
||||
|
||||
LLVMDIBuilderCreateCompileUnit(
|
||||
gallivm->di_builder, LLVMDWARFSourceLanguageC11, gallivm->file, gallivm->file_name, strlen(gallivm->file_name),
|
||||
0, NULL, 0, 0, NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
|
||||
}
|
||||
|
||||
LLVMMetadataRef di_function_type = lp_bld_debug_info_type(gallivm, func_type);
|
||||
const char *func_name = LLVMGetValueName(func);
|
||||
LLVMMetadataRef di_function = LLVMDIBuilderCreateFunction(
|
||||
gallivm->di_builder, NULL, func_name, strlen(func_name), func_name, strlen(func_name),
|
||||
gallivm->file, 1, di_function_type, true, true, 1, LLVMDIFlagZero, false);
|
||||
|
||||
LLVMSetSubprogram(func, di_function);
|
||||
|
||||
lp_add_function_attr(func, -1, LP_FUNC_ATTR_NOINLINE);
|
||||
lp_add_function_attr(func, -1, LP_FUNC_ATTR_OPTNONE);
|
||||
|
||||
gallivm->di_function = di_function;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#define LP_BLD_DEBUG_H
|
||||
|
||||
|
||||
#include "gallivm/lp_bld.h"
|
||||
#include "gallivm/lp_bld_init.h"
|
||||
|
||||
#include "util/compiler.h"
|
||||
#include "util/u_string.h"
|
||||
|
|
@ -95,6 +95,17 @@ void
|
|||
lp_profile(LLVMValueRef func, const void *code);
|
||||
|
||||
|
||||
LLVMMetadataRef
|
||||
lp_bld_debug_info_type(struct gallivm_state *gallivm, LLVMTypeRef type);
|
||||
|
||||
|
||||
void
|
||||
lp_function_add_debug_info(struct gallivm_state *gallivm, LLVMValueRef func, LLVMTypeRef func_type);
|
||||
|
||||
|
||||
#define LP_NIR_SHADER_DUMP_DIR "/tmp/nir_shaders"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ gallivm_free_ir(struct gallivm_state *gallivm)
|
|||
free(gallivm->cache->data);
|
||||
}
|
||||
FREE(gallivm->module_name);
|
||||
FREE(gallivm->file_name);
|
||||
|
||||
if (gallivm->target) {
|
||||
LLVMDisposeTargetData(gallivm->target);
|
||||
|
|
@ -123,6 +124,7 @@ gallivm_free_ir(struct gallivm_state *gallivm)
|
|||
gallivm->target = NULL;
|
||||
gallivm->module = NULL;
|
||||
gallivm->module_name = NULL;
|
||||
gallivm->file_name = NULL;
|
||||
gallivm->passmgr = NULL;
|
||||
gallivm->context = NULL;
|
||||
gallivm->builder = NULL;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ struct lp_cached_code;
|
|||
struct gallivm_state
|
||||
{
|
||||
char *module_name;
|
||||
char *file_name;
|
||||
LLVMModuleRef module;
|
||||
LLVMTargetDataRef target;
|
||||
#if GALLIVM_USE_ORCJIT
|
||||
|
|
@ -75,6 +76,9 @@ struct gallivm_state
|
|||
LLVMTypeRef coro_malloc_hook_type;
|
||||
LLVMTypeRef coro_free_hook_type;
|
||||
|
||||
LLVMMetadataRef di_function;
|
||||
LLVMMetadataRef file;
|
||||
|
||||
LLVMValueRef get_time_hook;
|
||||
|
||||
LLVMValueRef texture_descriptor;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ static const char *attr_to_str(enum lp_func_attr attr)
|
|||
case LP_FUNC_ATTR_NOUNWIND: return "nounwind";
|
||||
case LP_FUNC_ATTR_CONVERGENT: return "convergent";
|
||||
case LP_FUNC_ATTR_PRESPLITCORO: return "presplitcoroutine";
|
||||
case LP_FUNC_ATTR_NOINLINE: return "noinline";
|
||||
case LP_FUNC_ATTR_OPTNONE: return "optnone";
|
||||
default:
|
||||
_debug_printf("Unhandled function attribute: %x\n", attr);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@
|
|||
#include "gallivm/lp_bld.h"
|
||||
#include "gallivm/lp_bld_init.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct lp_type;
|
||||
|
||||
/**
|
||||
|
|
@ -55,6 +59,8 @@ enum lp_func_attr {
|
|||
LP_FUNC_ATTR_NOUNWIND = (1 << 4),
|
||||
LP_FUNC_ATTR_CONVERGENT = (1 << 5),
|
||||
LP_FUNC_ATTR_PRESPLITCORO = (1 << 6),
|
||||
LP_FUNC_ATTR_NOINLINE = (1 << 7),
|
||||
LP_FUNC_ATTR_OPTNONE = (1 << 8),
|
||||
};
|
||||
|
||||
void
|
||||
|
|
@ -135,4 +141,8 @@ lp_build_intrinsic_map_binary(struct gallivm_state *gallivm,
|
|||
LLVMValueRef b);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !LP_BLD_INTR_H */
|
||||
|
|
|
|||
|
|
@ -573,6 +573,8 @@ generate_compute(struct llvmpipe_context *lp,
|
|||
LLVMValueRef vec_length = lp_build_const_int32(gallivm, cs_type.length);
|
||||
|
||||
if (use_coro) {
|
||||
lp_function_add_debug_info(gallivm, function, func_type);
|
||||
|
||||
block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry");
|
||||
builder = gallivm->builder;
|
||||
assert(builder);
|
||||
|
|
@ -704,6 +706,8 @@ generate_compute(struct llvmpipe_context *lp,
|
|||
output_array = LLVMGetParam(coro, CS_ARG_CORO_OUTPUTS);
|
||||
}
|
||||
|
||||
lp_function_add_debug_info(gallivm, coro, coro_func_type);
|
||||
|
||||
block = LLVMAppendBasicBlockInContext(gallivm->context, coro, "entry");
|
||||
builder = gallivm->builder;
|
||||
LLVMPositionBuilderAtEnd(builder, block);
|
||||
|
|
|
|||
|
|
@ -3271,6 +3271,8 @@ generate_fragment(struct llvmpipe_context *lp,
|
|||
if (LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
|
||||
lp_add_function_attr(function, i + 1, LP_FUNC_ATTR_NOALIAS);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, func_type);
|
||||
|
||||
if (variant->gallivm->cache->data_size) {
|
||||
gallivm_stub_func(gallivm, function);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -288,6 +288,8 @@ llvmpipe_fs_variant_linear_llvm(struct llvmpipe_context *lp,
|
|||
LLVMAddFunction(gallivm->module, func_name, func_type);
|
||||
LLVMSetFunctionCallConv(function, LLVMCCallConv);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, func_type);
|
||||
|
||||
variant->linear_function = function;
|
||||
variant->linear_function_name = MALLOC(strlen(func_name)+1);
|
||||
strcpy(variant->linear_function_name, func_name);
|
||||
|
|
|
|||
|
|
@ -695,6 +695,8 @@ generate_setup_variant(struct lp_setup_variant_key *key,
|
|||
|
||||
LLVMSetFunctionCallConv(variant->function, LLVMCCallConv);
|
||||
|
||||
lp_function_add_debug_info(gallivm, variant->function, func_type);
|
||||
|
||||
struct lp_setup_args args;
|
||||
args.vec4f_type = vec4f_type;
|
||||
args.v0 = LLVMGetParam(variant->function, 0);
|
||||
|
|
|
|||
|
|
@ -342,6 +342,8 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
|
|||
|
||||
LLVMValueRef function = LLVMAddFunction(gallivm->module, "image", function_type);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, function_type);
|
||||
|
||||
uint32_t arg_index = 0;
|
||||
|
||||
gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
|
||||
|
|
@ -487,6 +489,8 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s
|
|||
LLVMTypeRef function_type = lp_build_sample_function_type(gallivm, sample_key);
|
||||
LLVMValueRef function = LLVMAddFunction(gallivm->module, "sample", function_type);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, function_type);
|
||||
|
||||
uint32_t arg_index = 0;
|
||||
|
||||
gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
|
||||
|
|
@ -629,6 +633,8 @@ compile_jit_sample_function(struct llvmpipe_context *ctx, uint32_t sample_key)
|
|||
LLVMTypeRef function_type = lp_build_sample_function_type(gallivm, sample_key);
|
||||
LLVMValueRef function = LLVMAddFunction(gallivm->module, "sample", function_type);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, function_type);
|
||||
|
||||
uint32_t arg_index = 0;
|
||||
LLVMValueRef texture_descriptor = LLVMGetParam(function, arg_index++);
|
||||
LLVMValueRef sampler_descriptor = LLVMGetParam(function, arg_index++);
|
||||
|
|
@ -757,6 +763,8 @@ compile_size_function(struct llvmpipe_context *ctx, struct lp_static_texture_sta
|
|||
LLVMTypeRef function_type = lp_build_size_function_type(gallivm, ¶ms);
|
||||
LLVMValueRef function = LLVMAddFunction(gallivm->module, "size", function_type);
|
||||
|
||||
lp_function_add_debug_info(gallivm, function, function_type);
|
||||
|
||||
uint32_t arg_index = 0;
|
||||
|
||||
gallivm->texture_descriptor = LLVMGetParam(function, arg_index++);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue