Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2010 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. #include "ir.h"
  25.  
  26. /**
  27.  * \file ir_hv_accept.cpp
  28.  * Implementations of all hierarchical visitor accept methods for IR
  29.  * instructions.
  30.  */
  31.  
  32. /**
  33.  * Process a list of nodes using a hierarchical vistor
  34.  *
  35.  * \warning
  36.  * This function will operate correctly if a node being processed is removed
  37.  * from the list.  However, if nodes are added to the list after the node being
  38.  * processed, some of the added nodes may not be processed.
  39.  */
  40. ir_visitor_status
  41. visit_list_elements(ir_hierarchical_visitor *v, exec_list *l)
  42. {
  43.    ir_instruction *prev_base_ir = v->base_ir;
  44.  
  45.    foreach_list_safe(n, l) {
  46.       ir_instruction *const ir = (ir_instruction *) n;
  47.       v->base_ir = ir;
  48.       ir_visitor_status s = ir->accept(v);
  49.  
  50.       if (s != visit_continue)
  51.          return s;
  52.    }
  53.    v->base_ir = prev_base_ir;
  54.  
  55.    return visit_continue;
  56. }
  57.  
  58.  
  59. ir_visitor_status
  60. ir_variable::accept(ir_hierarchical_visitor *v)
  61. {
  62.    return v->visit(this);
  63. }
  64.  
  65.  
  66. ir_visitor_status
  67. ir_loop::accept(ir_hierarchical_visitor *v)
  68. {
  69.    ir_visitor_status s = v->visit_enter(this);
  70.  
  71.    if (s != visit_continue)
  72.       return (s == visit_continue_with_parent) ? visit_continue : s;
  73.  
  74.    s = visit_list_elements(v, &this->body_instructions);
  75.    if (s == visit_stop)
  76.       return s;
  77.  
  78.    if (s != visit_continue_with_parent) {
  79.       if (this->from) {
  80.          s = this->from->accept(v);
  81.          if (s != visit_continue)
  82.             return (s == visit_continue_with_parent) ? visit_continue : s;
  83.       }
  84.  
  85.       if (this->to) {
  86.          s = this->to->accept(v);
  87.          if (s != visit_continue)
  88.             return (s == visit_continue_with_parent) ? visit_continue : s;
  89.       }
  90.  
  91.       if (this->increment) {
  92.          s = this->increment->accept(v);
  93.          if (s != visit_continue)
  94.             return (s == visit_continue_with_parent) ? visit_continue : s;
  95.       }
  96.    }
  97.  
  98.    return v->visit_leave(this);
  99. }
  100.  
  101.  
  102. ir_visitor_status
  103. ir_loop_jump::accept(ir_hierarchical_visitor *v)
  104. {
  105.    return v->visit(this);
  106. }
  107.  
  108.  
  109. ir_visitor_status
  110. ir_function_signature::accept(ir_hierarchical_visitor *v)
  111. {
  112.    ir_visitor_status s = v->visit_enter(this);
  113.    if (s != visit_continue)
  114.       return (s == visit_continue_with_parent) ? visit_continue : s;
  115.  
  116.    s = visit_list_elements(v, &this->parameters);
  117.    if (s == visit_stop)
  118.       return s;
  119.  
  120.    s = visit_list_elements(v, &this->body);
  121.    return (s == visit_stop) ? s : v->visit_leave(this);
  122. }
  123.  
  124.  
  125. ir_visitor_status
  126. ir_function::accept(ir_hierarchical_visitor *v)
  127. {
  128.    ir_visitor_status s = v->visit_enter(this);
  129.    if (s != visit_continue)
  130.       return (s == visit_continue_with_parent) ? visit_continue : s;
  131.  
  132.    s = visit_list_elements(v, &this->signatures);
  133.    return (s == visit_stop) ? s : v->visit_leave(this);
  134. }
  135.  
  136.  
  137. ir_visitor_status
  138. ir_expression::accept(ir_hierarchical_visitor *v)
  139. {
  140.    ir_visitor_status s = v->visit_enter(this);
  141.  
  142.    if (s != visit_continue)
  143.       return (s == visit_continue_with_parent) ? visit_continue : s;
  144.  
  145.    for (unsigned i = 0; i < this->get_num_operands(); i++) {
  146.       switch (this->operands[i]->accept(v)) {
  147.       case visit_continue:
  148.          break;
  149.  
  150.       case visit_continue_with_parent:
  151.          // I wish for Java's labeled break-statement here.
  152.          goto done;
  153.  
  154.       case visit_stop:
  155.          return s;
  156.       }
  157.    }
  158.  
  159. done:
  160.    return v->visit_leave(this);
  161. }
  162.  
  163. ir_visitor_status
  164. ir_texture::accept(ir_hierarchical_visitor *v)
  165. {
  166.    ir_visitor_status s = v->visit_enter(this);
  167.    if (s != visit_continue)
  168.       return (s == visit_continue_with_parent) ? visit_continue : s;
  169.  
  170.    s = this->sampler->accept(v);
  171.    if (s != visit_continue)
  172.       return (s == visit_continue_with_parent) ? visit_continue : s;
  173.  
  174.    s = this->coordinate->accept(v);
  175.    if (s != visit_continue)
  176.       return (s == visit_continue_with_parent) ? visit_continue : s;
  177.  
  178.    if (this->projector) {
  179.       s = this->projector->accept(v);
  180.       if (s != visit_continue)
  181.          return (s == visit_continue_with_parent) ? visit_continue : s;
  182.    }
  183.  
  184.    if (this->shadow_comparitor) {
  185.       s = this->shadow_comparitor->accept(v);
  186.       if (s != visit_continue)
  187.          return (s == visit_continue_with_parent) ? visit_continue : s;
  188.    }
  189.  
  190.    switch (this->op) {
  191.    case ir_tex:
  192.       break;
  193.    case ir_txb:
  194.       s = this->lod_info.bias->accept(v);
  195.       if (s != visit_continue)
  196.          return (s == visit_continue_with_parent) ? visit_continue : s;
  197.       break;
  198.    case ir_txl:
  199.    case ir_txf:
  200.       s = this->lod_info.lod->accept(v);
  201.       if (s != visit_continue)
  202.          return (s == visit_continue_with_parent) ? visit_continue : s;
  203.       break;
  204.    case ir_txd:
  205.       s = this->lod_info.grad.dPdx->accept(v);
  206.       if (s != visit_continue)
  207.          return (s == visit_continue_with_parent) ? visit_continue : s;
  208.  
  209.       s = this->lod_info.grad.dPdy->accept(v);
  210.       if (s != visit_continue)
  211.          return (s == visit_continue_with_parent) ? visit_continue : s;
  212.       break;
  213.    }
  214.  
  215.    return (s == visit_stop) ? s : v->visit_leave(this);
  216. }
  217.  
  218.  
  219. ir_visitor_status
  220. ir_swizzle::accept(ir_hierarchical_visitor *v)
  221. {
  222.    ir_visitor_status s = v->visit_enter(this);
  223.    if (s != visit_continue)
  224.       return (s == visit_continue_with_parent) ? visit_continue : s;
  225.  
  226.    s = this->val->accept(v);
  227.    return (s == visit_stop) ? s : v->visit_leave(this);
  228. }
  229.  
  230.  
  231. ir_visitor_status
  232. ir_dereference_variable::accept(ir_hierarchical_visitor *v)
  233. {
  234.    return v->visit(this);
  235. }
  236.  
  237.  
  238. ir_visitor_status
  239. ir_dereference_array::accept(ir_hierarchical_visitor *v)
  240. {
  241.    ir_visitor_status s = v->visit_enter(this);
  242.    if (s != visit_continue)
  243.       return (s == visit_continue_with_parent) ? visit_continue : s;
  244.  
  245.    /* The array index is not the target of the assignment, so clear the
  246.     * 'in_assignee' flag.  Restore it after returning from the array index.
  247.     */
  248.    const bool was_in_assignee = v->in_assignee;
  249.    v->in_assignee = false;
  250.    s = this->array_index->accept(v);
  251.    v->in_assignee = was_in_assignee;
  252.  
  253.    if (s != visit_continue)
  254.       return (s == visit_continue_with_parent) ? visit_continue : s;
  255.  
  256.    s = this->array->accept(v);
  257.    return (s == visit_stop) ? s : v->visit_leave(this);
  258. }
  259.  
  260.  
  261. ir_visitor_status
  262. ir_dereference_record::accept(ir_hierarchical_visitor *v)
  263. {
  264.    ir_visitor_status s = v->visit_enter(this);
  265.    if (s != visit_continue)
  266.       return (s == visit_continue_with_parent) ? visit_continue : s;
  267.  
  268.    s = this->record->accept(v);
  269.    return (s == visit_stop) ? s : v->visit_leave(this);
  270. }
  271.  
  272.  
  273. ir_visitor_status
  274. ir_assignment::accept(ir_hierarchical_visitor *v)
  275. {
  276.    ir_visitor_status s = v->visit_enter(this);
  277.    if (s != visit_continue)
  278.       return (s == visit_continue_with_parent) ? visit_continue : s;
  279.  
  280.    v->in_assignee = true;
  281.    s = this->lhs->accept(v);
  282.    v->in_assignee = false;
  283.    if (s != visit_continue)
  284.       return (s == visit_continue_with_parent) ? visit_continue : s;
  285.  
  286.    s = this->rhs->accept(v);
  287.    if (s != visit_continue)
  288.       return (s == visit_continue_with_parent) ? visit_continue : s;
  289.  
  290.    if (this->condition)
  291.       s = this->condition->accept(v);
  292.  
  293.    return (s == visit_stop) ? s : v->visit_leave(this);
  294. }
  295.  
  296.  
  297. ir_visitor_status
  298. ir_constant::accept(ir_hierarchical_visitor *v)
  299. {
  300.    return v->visit(this);
  301. }
  302.  
  303.  
  304. ir_visitor_status
  305. ir_call::accept(ir_hierarchical_visitor *v)
  306. {
  307.    ir_visitor_status s = v->visit_enter(this);
  308.    if (s != visit_continue)
  309.       return (s == visit_continue_with_parent) ? visit_continue : s;
  310.  
  311.    s = visit_list_elements(v, &this->actual_parameters);
  312.    if (s == visit_stop)
  313.       return s;
  314.  
  315.    return v->visit_leave(this);
  316. }
  317.  
  318.  
  319. ir_visitor_status
  320. ir_return::accept(ir_hierarchical_visitor *v)
  321. {
  322.    ir_visitor_status s = v->visit_enter(this);
  323.    if (s != visit_continue)
  324.       return (s == visit_continue_with_parent) ? visit_continue : s;
  325.  
  326.    ir_rvalue *val = this->get_value();
  327.    if (val) {
  328.       s = val->accept(v);
  329.       if (s != visit_continue)
  330.          return (s == visit_continue_with_parent) ? visit_continue : s;
  331.    }
  332.  
  333.    return v->visit_leave(this);
  334. }
  335.  
  336.  
  337. ir_visitor_status
  338. ir_discard::accept(ir_hierarchical_visitor *v)
  339. {
  340.    ir_visitor_status s = v->visit_enter(this);
  341.    if (s != visit_continue)
  342.       return (s == visit_continue_with_parent) ? visit_continue : s;
  343.  
  344.    if (this->condition != NULL) {
  345.       s = this->condition->accept(v);
  346.       if (s != visit_continue)
  347.          return (s == visit_continue_with_parent) ? visit_continue : s;
  348.    }
  349.  
  350.    return v->visit_leave(this);
  351. }
  352.  
  353.  
  354. ir_visitor_status
  355. ir_if::accept(ir_hierarchical_visitor *v)
  356. {
  357.    ir_visitor_status s = v->visit_enter(this);
  358.    if (s != visit_continue)
  359.       return (s == visit_continue_with_parent) ? visit_continue : s;
  360.  
  361.    s = this->condition->accept(v);
  362.    if (s != visit_continue)
  363.       return (s == visit_continue_with_parent) ? visit_continue : s;
  364.  
  365.    if (s != visit_continue_with_parent) {
  366.       s = visit_list_elements(v, &this->then_instructions);
  367.       if (s == visit_stop)
  368.          return s;
  369.    }
  370.  
  371.    if (s != visit_continue_with_parent) {
  372.       s = visit_list_elements(v, &this->else_instructions);
  373.       if (s == visit_stop)
  374.          return s;
  375.    }
  376.  
  377.    return v->visit_leave(this);
  378. }
  379.