diff options
author | Connor Abbott <[email protected]> | 2017-06-05 14:16:43 -0700 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2017-09-08 04:06:47 +0100 |
commit | ac27fa72941a5f075530c7755215ba0ec63d2c1f (patch) | |
tree | 2d025105287a6b83df4d5e0b481530d4cd340f8c /src/amd | |
parent | c181d4f2b7875882ba41b62ad43dfe58c2f70ab1 (diff) |
radeonsi: move emit_optimization_barrier() to ac
Reviewed-by: Nicolai Hähnle <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/amd')
-rw-r--r-- | src/amd/common/ac_llvm_build.c | 43 | ||||
-rw-r--r-- | src/amd/common/ac_llvm_build.h | 2 |
2 files changed, 45 insertions, 0 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c index 2503608e26b..9045df7a0d9 100644 --- a/src/amd/common/ac_llvm_build.c +++ b/src/amd/common/ac_llvm_build.c @@ -36,6 +36,7 @@ #include "ac_exp_param.h" #include "util/bitscan.h" #include "util/macros.h" +#include "util/u_atomic.h" #include "sid.h" #include "shader_enums.h" @@ -200,6 +201,48 @@ void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize) } } +/* Prevent optimizations (at least of memory accesses) across the current + * point in the program by emitting empty inline assembly that is marked as + * having side effects. + * + * Optionally, a value can be passed through the inline assembly to prevent + * LLVM from hoisting calls to ReadNone functions. + */ +void +ac_build_optimization_barrier(struct ac_llvm_context *ctx, + LLVMValueRef *pvgpr) +{ + static int counter = 0; + + LLVMBuilderRef builder = ctx->builder; + char code[16]; + + snprintf(code, sizeof(code), "; %d", p_atomic_inc_return(&counter)); + + if (!pvgpr) { + LLVMTypeRef ftype = LLVMFunctionType(ctx->voidt, NULL, 0, false); + LLVMValueRef inlineasm = LLVMConstInlineAsm(ftype, code, "", true, false); + LLVMBuildCall(builder, inlineasm, NULL, 0, ""); + } else { + LLVMTypeRef ftype = LLVMFunctionType(ctx->i32, &ctx->i32, 1, false); + LLVMValueRef inlineasm = LLVMConstInlineAsm(ftype, code, "=v,0", true, false); + LLVMValueRef vgpr = *pvgpr; + LLVMTypeRef vgpr_type = LLVMTypeOf(vgpr); + unsigned vgpr_size = ac_get_type_size(vgpr_type); + LLVMValueRef vgpr0; + + assert(vgpr_size % 4 == 0); + + vgpr = LLVMBuildBitCast(builder, vgpr, LLVMVectorType(ctx->i32, vgpr_size / 4), ""); + vgpr0 = LLVMBuildExtractElement(builder, vgpr, ctx->i32_0, ""); + vgpr0 = LLVMBuildCall(builder, inlineasm, &vgpr0, 1, ""); + vgpr = LLVMBuildInsertElement(builder, vgpr, vgpr0, ctx->i32_0, ""); + vgpr = LLVMBuildBitCast(builder, vgpr, vgpr_type, ""); + + *pvgpr = vgpr; + } +} + LLVMValueRef ac_build_gather_values_extended(struct ac_llvm_context *ctx, LLVMValueRef *values, diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h index cbc938d5a0a..4466e2f3057 100644 --- a/src/amd/common/ac_llvm_build.h +++ b/src/amd/common/ac_llvm_build.h @@ -75,6 +75,8 @@ ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name, void ac_build_type_name_for_intr(LLVMTypeRef type, char *buf, unsigned bufsize); +void ac_build_optimization_barrier(struct ac_llvm_context *ctx, + LLVMValueRef *pvgpr); LLVMValueRef ac_build_gather_values_extended(struct ac_llvm_context *ctx, LLVMValueRef *values, |