Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2014 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
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23.  
  24. /**
  25.  * \file opt_conditional_discard.cpp
  26.  *
  27.  * Replace
  28.  *
  29.  *    if (cond) discard;
  30.  *
  31.  * with
  32.  *
  33.  *    (discard <condition>)
  34.  */
  35.  
  36. #include "glsl_types.h"
  37. #include "ir.h"
  38.  
  39. namespace {
  40.  
  41. class opt_conditional_discard_visitor : public ir_hierarchical_visitor {
  42. public:
  43.    opt_conditional_discard_visitor()
  44.    {
  45.       progress = false;
  46.    }
  47.  
  48.    ir_visitor_status visit_leave(ir_if *);
  49.  
  50.    bool progress;
  51. };
  52.  
  53. } /* anonymous namespace */
  54.  
  55. bool
  56. opt_conditional_discard(exec_list *instructions)
  57. {
  58.    opt_conditional_discard_visitor v;
  59.    v.run(instructions);
  60.    return v.progress;
  61. }
  62.  
  63. ir_visitor_status
  64. opt_conditional_discard_visitor::visit_leave(ir_if *ir)
  65. {
  66.    /* Look for "if (...) discard" with no else clause or extra statements. */
  67.    if (ir->then_instructions.is_empty() ||
  68.        !ir->then_instructions.head->next->is_tail_sentinel() ||
  69.        !((ir_instruction *) ir->then_instructions.head)->as_discard() ||
  70.        !ir->else_instructions.is_empty())
  71.       return visit_continue;
  72.  
  73.    /* Move the condition and replace the ir_if with the ir_discard. */
  74.    ir_discard *discard = (ir_discard *) ir->then_instructions.head;
  75.    discard->condition = ir->condition;
  76.    ir->replace_with(discard);
  77.  
  78.    progress = true;
  79.  
  80.    return visit_continue;
  81. }
  82.