Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2013 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "brw_fs.h"
  25. #include "brw_fs_live_variables.h"
  26. #include "brw_cfg.h"
  27.  
  28. /** @file brw_fs_saturate_propagation.cpp
  29.  *
  30.  * Implements a pass that propagates the SAT modifier from a MOV.SAT into the
  31.  * instruction that produced the source of the MOV.SAT, thereby allowing the
  32.  * MOV's src and dst to be coalesced and the MOV removed.
  33.  *
  34.  * For instance,
  35.  *
  36.  *    ADD     tmp, src0, src1
  37.  *    MOV.SAT dst, tmp
  38.  *
  39.  * would be transformed into
  40.  *
  41.  *    ADD.SAT tmp, src0, src1
  42.  *    MOV     dst, tmp
  43.  */
  44.  
  45. static bool
  46. opt_saturate_propagation_local(fs_visitor *v, bblock_t *block)
  47. {
  48.    bool progress = false;
  49.    int ip = block->end_ip + 1;
  50.  
  51.    foreach_inst_in_block_reverse(fs_inst, inst, block) {
  52.       ip--;
  53.  
  54.       if (inst->opcode != BRW_OPCODE_MOV ||
  55.           inst->dst.file != GRF ||
  56.           inst->src[0].file != GRF ||
  57.           inst->src[0].abs ||
  58.           inst->src[0].negate ||
  59.           !inst->saturate)
  60.          continue;
  61.  
  62.       int src_var = v->live_intervals->var_from_reg(inst->src[0]);
  63.       int src_end_ip = v->live_intervals->end[src_var];
  64.  
  65.       bool interfered = false;
  66.       foreach_inst_in_block_reverse_starting_from(fs_inst, scan_inst, inst, block) {
  67.          if (scan_inst->overwrites_reg(inst->src[0])) {
  68.             if (scan_inst->is_partial_write())
  69.                break;
  70.  
  71.             if (scan_inst->saturate) {
  72.                inst->saturate = false;
  73.                progress = true;
  74.             } else if (src_end_ip <= ip || inst->dst.equals(inst->src[0])) {
  75.                if (scan_inst->can_do_saturate()) {
  76.                   scan_inst->saturate = true;
  77.                   inst->saturate = false;
  78.                   progress = true;
  79.                }
  80.             }
  81.             break;
  82.          }
  83.          for (int i = 0; i < scan_inst->sources; i++) {
  84.             if (scan_inst->src[i].file == GRF &&
  85.                 scan_inst->src[i].reg == inst->src[0].reg &&
  86.                 scan_inst->src[i].reg_offset == inst->src[0].reg_offset) {
  87.                if (scan_inst->opcode != BRW_OPCODE_MOV ||
  88.                    !scan_inst->saturate ||
  89.                    scan_inst->src[0].abs ||
  90.                    scan_inst->src[0].negate) {
  91.                   interfered = true;
  92.                   break;
  93.                }
  94.             }
  95.          }
  96.  
  97.          if (interfered)
  98.             break;
  99.       }
  100.    }
  101.  
  102.    return progress;
  103. }
  104.  
  105. bool
  106. fs_visitor::opt_saturate_propagation()
  107. {
  108.    bool progress = false;
  109.  
  110.    calculate_live_intervals();
  111.  
  112.    foreach_block (block, cfg) {
  113.       progress = opt_saturate_propagation_local(this, block) || progress;
  114.    }
  115.  
  116.    /* Live intervals are still valid. */
  117.  
  118.    return progress;
  119. }
  120.