Path: blob/21.2-virgl/src/broadcom/compiler/vir_opt_small_immediates.c
4564 views
/*1* Copyright © 2014 Broadcom2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223/**24* @file v3d_opt_small_immediates.c25*26* Turns references to small constant uniform values into small immediates27* fields.28*/2930#include "v3d_compiler.h"3132static bool debug;3334bool35vir_opt_small_immediates(struct v3d_compile *c)36{37bool progress = false;3839vir_for_each_inst_inorder(inst, c) {40if (inst->qpu.type != V3D_QPU_INSTR_TYPE_ALU)41continue;4243/* The small immediate value sits in the raddr B field, so we44* can't have 2 small immediates in one instruction (unless45* they're the same value, but that should be optimized away46* elsewhere).47*/48bool uses_small_imm = false;49for (int i = 0; i < vir_get_nsrc(inst); i++) {50if (inst->src[i].file == QFILE_SMALL_IMM)51uses_small_imm = true;52}53if (uses_small_imm)54continue;5556for (int i = 0; i < vir_get_nsrc(inst); i++) {57if (inst->src[i].file != QFILE_TEMP)58continue;5960/* See if it's a uniform load. */61struct qinst *src_def = c->defs[inst->src[i].index];62if (!src_def || !src_def->qpu.sig.ldunif)63continue;64int uniform = src_def->uniform;6566if (c->uniform_contents[uniform] != QUNIFORM_CONSTANT)67continue;6869/* Check if the uniform is suitable as a small70* immediate.71*/72uint32_t imm = c->uniform_data[uniform];73uint32_t packed;74if (!v3d_qpu_small_imm_pack(c->devinfo, imm, &packed))75continue;7677/* Check that we don't have any other signals already78* that would be incompatible with small_imm.79*/80struct v3d_qpu_sig new_sig = inst->qpu.sig;81uint32_t sig_packed;82new_sig.small_imm = true;83if (!v3d_qpu_sig_pack(c->devinfo, &new_sig, &sig_packed))84continue;8586if (debug) {87fprintf(stderr, "opt_small_immediate() from: ");88vir_dump_inst(c, inst);89fprintf(stderr, "\n");90}91inst->qpu.sig.small_imm = true;92inst->qpu.raddr_b = packed;9394inst->src[i].file = QFILE_SMALL_IMM;95inst->src[i].index = imm;96if (debug) {97fprintf(stderr, "to: ");98vir_dump_inst(c, inst);99fprintf(stderr, "\n");100}101progress = true;102break;103}104}105106return progress;107}108109110