From 301bd70ef0b947154c4b39f8c4e434625ff271ac Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 23 Aug 2013 16:13:29 -0400 Subject: [PATCH 3/3] radeonsi: Don't preload constants Preloading constants was som shader to run out of SGPRs, because the shader compiler was not being aggressive enough when sinking instructions into successor blocks. --- src/gallium/drivers/radeonsi/radeonsi_shader.c | 58 ++++++++++++-------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c index 775d04f..843d3ad 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.c +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c @@ -457,8 +457,22 @@ static LLVMValueRef fetch_constant( } idx = reg->Register.Index * 4 + swizzle; - if (!reg->Register.Indirect) - return bitcast(bld_base, type, si_shader_ctx->constants[idx]); + if (!reg->Register.Indirect) { + /* We cannot cache the constant values and must re-emit them + * for every use. Otherwise we may generate invalid code + * if the cached constant first appears in a basic block that + * does not dominate its successors. For example: + * A + * | \ + * | B : Constant loaded + * | / + * C : Constant used + */ + LLVMValueRef c = build_constant_load(si_shader_ctx, + si_shader_ctx->const_resource, + lp_build_const_int32(bld_base->base.gallivm, 4 * idx)); + return bitcast(bld_base, type, c); + } addr = si_shader_ctx->radeon_bld.soa.addr[ireg->Index][ireg->Swizzle]; addr = LLVMBuildLoad(base->gallivm->builder, addr, "load addr reg"); @@ -1421,34 +1435,6 @@ static void create_function(struct si_shader_context *si_shader_ctx) #endif } -static void preload_constants(struct si_shader_context *si_shader_ctx) -{ - struct lp_build_tgsi_context * bld_base = &si_shader_ctx->radeon_bld.soa.bld_base; - struct gallivm_state * gallivm = bld_base->base.gallivm; - const struct tgsi_shader_info * info = bld_base->info; - - unsigned i, num_const = info->file_max[TGSI_FILE_CONSTANT] + 1; - - LLVMValueRef ptr; - - if (num_const == 0) - return; - - /* Allocate space for the constant values */ - si_shader_ctx->constants = CALLOC(num_const * 4, sizeof(LLVMValueRef)); - - /* Load the resource descriptor */ - ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST); - si_shader_ctx->const_resource = build_indexed_load(si_shader_ctx, ptr, bld_base->uint_bld.zero); - - /* Load the constants, we rely on the code sinking to do the rest */ - for (i = 0; i < num_const * 4; ++i) { - si_shader_ctx->constants[i] = build_constant_load(si_shader_ctx, - si_shader_ctx->const_resource, - lp_build_const_int32(gallivm, i * 4)); - } -} - static void preload_samplers(struct si_shader_context *si_shader_ctx) { struct lp_build_tgsi_context * bld_base = &si_shader_ctx->radeon_bld.soa.bld_base; @@ -1588,6 +1574,7 @@ int si_pipe_shader_create( LLVMModuleRef mod; bool dump; int r = 0; + LLVMValueRef ptr; dump = debug_get_bool_option("RADEON_DUMP_SHADERS", FALSE); @@ -1631,7 +1618,16 @@ int si_pipe_shader_create( create_meta_data(&si_shader_ctx); create_function(&si_shader_ctx); - preload_constants(&si_shader_ctx); + /* Allocate space for the constant values */ + si_shader_ctx.constants = CALLOC( + 4 * (shader_info.file_max[TGSI_FILE_CONSTANT] + 1), + sizeof(LLVMValueRef)); + + /* Load the resource descriptor */ + ptr = LLVMGetParam(si_shader_ctx.radeon_bld.main_fn, SI_PARAM_CONST); + si_shader_ctx.const_resource = build_indexed_load(&si_shader_ctx, ptr, + bld_base->uint_bld.zero); + preload_samplers(&si_shader_ctx); shader->shader.nr_cbufs = rctx->framebuffer.nr_cbufs; -- 1.8.1.5