On 27 April 2017 at 20:17, Marek Olšák <mar...@gmail.com> wrote: > > > On Apr 27, 2017 10:50 AM, "Juan A. Suarez Romero" <jasua...@igalia.com> > wrote: > > On Wed, 2017-04-26 at 09:12 +1000, Dave Airlie wrote: >> From: Dave Airlie <airl...@redhat.com> >> >> This code can be shared by radv, we bump the max to >> VARYING_SLOT_MAX here, but that shouldn't have too >> much fallout. >> >> Signed-off-by: Dave Airlie <airl...@redhat.com> >> --- >> src/amd/common/ac_exp_param.h | 40 ++++++ >> src/amd/common/ac_llvm_build.c | 156 >> +++++++++++++++++++++++- >> src/amd/common/ac_llvm_build.h | 6 + >> src/amd/common/ac_llvm_helper.cpp | 20 +++ >> src/amd/common/ac_llvm_util.h | 2 + >> src/gallium/drivers/radeonsi/si_shader.c | 152 >> ++--------------------- >> src/gallium/drivers/radeonsi/si_shader.h | 12 -- >> src/gallium/drivers/radeonsi/si_state_shaders.c | 13 +- >> 8 files changed, 237 insertions(+), 164 deletions(-) >> create mode 100644 src/amd/common/ac_exp_param.h >> >> diff --git a/src/amd/common/ac_exp_param.h b/src/amd/common/ac_exp_param.h >> new file mode 100644 >> index 0000000..b97ce81 >> --- /dev/null >> +++ b/src/amd/common/ac_exp_param.h >> @@ -0,0 +1,40 @@ >> +/* >> + * Copyright 2014 Advanced Micro Devices, Inc. >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining >> a >> + * copy of this software and associated documentation files (the >> + * "Software"), to deal in the Software without restriction, including >> + * without limitation the rights to use, copy, modify, merge, publish, >> + * distribute, sub license, and/or sell copies of the Software, and to >> + * permit persons to whom the Software is furnished to do so, subject to >> + * the following conditions: >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >> EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >> MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT >> SHALL >> + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY >> CLAIM, >> + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR >> + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR >> THE >> + * USE OR OTHER DEALINGS IN THE SOFTWARE. >> + * >> + * The above copyright notice and this permission notice (including the >> + * next paragraph) shall be included in all copies or substantial >> portions >> + * of the Software. >> + * >> + */ >> +#ifndef AC_EXP_PARAM_H >> +#define AC_EXP_PARAM_H >> + >> +enum { >> + /* SPI_PS_INPUT_CNTL_i.OFFSET[0:4] */ >> + AC_EXP_PARAM_OFFSET_0 = 0, >> + AC_EXP_PARAM_OFFSET_31 = 31, >> + /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL[0:1] */ >> + AC_EXP_PARAM_DEFAULT_VAL_0000 = 64, >> + AC_EXP_PARAM_DEFAULT_VAL_0001, >> + AC_EXP_PARAM_DEFAULT_VAL_1110, >> + AC_EXP_PARAM_DEFAULT_VAL_1111, >> + AC_EXP_PARAM_UNDEFINED = 255, >> +}; >> + >> +#endif >> diff --git a/src/amd/common/ac_llvm_build.c >> b/src/amd/common/ac_llvm_build.c >> index d45094c..f452f3e 100644 >> --- a/src/amd/common/ac_llvm_build.c >> +++ b/src/amd/common/ac_llvm_build.c >> @@ -33,11 +33,13 @@ >> #include <stdio.h> >> >> #include "ac_llvm_util.h" >> - >> +#include "ac_exp_param.h" >> #include "util/bitscan.h" >> #include "util/macros.h" >> #include "sid.h" >> >> +#include "shader_enums.h" >> + >> /* Initialize module-independent parts of the context. >> * >> * The caller is responsible for initializing ctx::module and >> ctx::builder. >> @@ -1244,3 +1246,155 @@ void ac_get_image_intr_name(const char *base_name, >> data_type_name, coords_type_name, >> rsrc_type_name); >> } >> } >> + >> +#define AC_EXP_TARGET (HAVE_LLVM >= 0x0500 ? 0 : 3) >> +#define AC_EXP_OUT0 (HAVE_LLVM >= 0x0500 ? 2 : 5) >> + >> +/* Return true if the PARAM export has been eliminated. */ >> +static bool ac_eliminate_const_output(uint8_t *vs_output_param_offset, >> + uint32_t num_outputs, >> + LLVMValueRef inst, unsigned offset) >> +{ >> + unsigned i, default_val; /* SPI_PS_INPUT_CNTL_i.DEFAULT_VAL */ >> + bool is_zero[4] = {}, is_one[4] = {}; >> + >> + for (i = 0; i < 4; i++) { >> + LLVMBool loses_info; >> + LLVMValueRef p = LLVMGetOperand(inst, AC_EXP_OUT0 + i); >> + >> + /* It's a constant expression. Undef outputs are eliminated >> too. */ >> + if (LLVMIsUndef(p)) { >> + is_zero[i] = true; >> + is_one[i] = true; >> + } else if (LLVMIsAConstantFP(p)) { >> + double a = LLVMConstRealGetDouble(p, &loses_info); >> + >> + if (a == 0) >> + is_zero[i] = true; >> + else if (a == 1) >> + is_one[i] = true; >> + else >> + return false; /* other constant */ >> + } else >> + return false; >> + } >> + >> + /* Only certain combinations of 0 and 1 can be eliminated. */ >> + if (is_zero[0] && is_zero[1] && is_zero[2]) >> + default_val = is_zero[3] ? 0 : 1; >> + else if (is_one[0] && is_one[1] && is_one[2]) >> + default_val = is_zero[3] ? 2 : 3; >> + else >> + return false; >> + >> + /* The PARAM export can be represented as DEFAULT_VAL. Kill it. */ >> + LLVMInstructionEraseFromParent(inst); >> + >> + /* Change OFFSET to DEFAULT_VAL. */ >> + for (i = 0; i < num_outputs; i++) { >> + if (vs_output_param_offset[i] == offset) { >> + vs_output_param_offset[i] = >> + AC_EXP_PARAM_DEFAULT_VAL_0000 + default_val; >> + break; >> + } >> + } >> + return true; >> +} >> + >> +struct ac_vs_exports { >> + unsigned num; >> + unsigned offset[VARYING_SLOT_MAX]; >> + LLVMValueRef inst[VARYING_SLOT_MAX]; >> +}; >> + >> +void ac_eliminate_const_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; >> + >> + assert(num_outputs < VARYING_SLOT_MAX); >> + 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); >> + >> + 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; >> + >> + /* Eliminate constant value PARAM exports. */ >> + if >> (ac_eliminate_const_output(vs_output_param_offset, >> + num_outputs, cur, >> target)) { >> + removed_any = true; >> + } else { >> + exports.offset[exports.num] = target; >> + exports.inst[exports.num] = cur; >> + exports.num++; >> + } >> + } >> + 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 current_offset[VARYING_SLOT_MAX]; >> + unsigned new_count = 0; >> + unsigned out, i; >> + >> + /* Make a copy of the offsets. We need the old version while >> + * we are modifying some of them. */ >> + memcpy(current_offset, vs_output_param_offset, >> + sizeof(current_offset)); >> + >> + for (i = 0; i < exports.num; i++) { >> + unsigned offset = exports.offset[i]; >> + >> + for (out = 0; out < num_outputs; out++) { >> + if (current_offset[out] != offset) >> + continue; >> + >> + LLVMSetOperand(exports.inst[i], >> AC_EXP_TARGET, >> + LLVMConstInt(ctx->i32, >> + >> V_008DFC_SQ_EXP_PARAM + new_count, 0)); >> + vs_output_param_offset[out] = new_count; >> + new_count++; >> + break; >> + } >> + } >> + *num_param_exports = new_count; >> + } >> +} >> diff --git a/src/amd/common/ac_llvm_build.h >> b/src/amd/common/ac_llvm_build.h >> index d6edcde..1c3610a 100644 >> --- a/src/amd/common/ac_llvm_build.h >> +++ b/src/amd/common/ac_llvm_build.h >> @@ -239,6 +239,12 @@ void ac_get_image_intr_name(const char *base_name, >> LLVMTypeRef coords_type, >> LLVMTypeRef rsrc_type, >> char *out_name, unsigned out_len); >> + >> +void ac_eliminate_const_vs_outputs(struct ac_llvm_context *ac, >> + LLVMValueRef main_fn, >> + uint8_t *vs_output_param_offset, >> + uint32_t num_outputs, >> + uint8_t *num_param_exports); >> #ifdef __cplusplus >> } >> #endif >> diff --git a/src/amd/common/ac_llvm_helper.cpp >> b/src/amd/common/ac_llvm_helper.cpp >> index 11fa809..582a8f7 100644 >> --- a/src/amd/common/ac_llvm_helper.cpp >> +++ b/src/amd/common/ac_llvm_helper.cpp >> @@ -61,3 +61,23 @@ bool ac_is_sgpr_param(LLVMValueRef arg) >> return AS.hasAttribute(ArgNo + 1, llvm::Attribute::ByVal) || >> AS.hasAttribute(ArgNo + 1, llvm::Attribute::InReg); >> } >> + >> +LLVMValueRef ac_llvm_get_called_value(LLVMValueRef call) >> +{ >> +#if HAVE_LLVM >= 0x0309 >> + return LLVMGetCalledValue(call); >> +#elif HAVE_LLVM >= 0x0305 >> + return >> llvm::wrap(llvm::CallSite(llvm::unwrap<llvm::Instruction>(call)).getCalledValue()); > > > This patch is breaking build when using LLVM 3.8.1. > >
> Can you share the build error with us? > > BTW, I have a patch that removes support for LLVM 3.8. I fixed it in master, was missing an include file, I also still had a 3.8 install to build against luckily. Dave. _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev