On Thu, 2017-04-27 at 20:42 +1000, Dave Airlie wrote: > 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. >
Nice! Thank you. > Dave. > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev