• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 #include "ir.h"
24 #include "ir_builder.h"
25 #include "ir_rvalue_visitor.h"
26 #include "ir_optimization.h"
27 
28 using namespace ir_builder;
29 
30 namespace {
31 
32 class vector_deref_visitor : public ir_rvalue_enter_visitor {
33 public:
vector_deref_visitor()34    vector_deref_visitor()
35       : progress(false)
36    {
37    }
38 
~vector_deref_visitor()39    virtual ~vector_deref_visitor()
40    {
41    }
42 
43    virtual void handle_rvalue(ir_rvalue **rv);
44    virtual ir_visitor_status visit_enter(ir_assignment *ir);
45 
46    bool progress;
47 };
48 
49 } /* anonymous namespace */
50 
51 ir_visitor_status
visit_enter(ir_assignment * ir)52 vector_deref_visitor::visit_enter(ir_assignment *ir)
53 {
54    if (!ir->lhs || ir->lhs->ir_type != ir_type_dereference_array)
55       return ir_rvalue_enter_visitor::visit_enter(ir);
56 
57    ir_dereference_array *const deref = (ir_dereference_array *) ir->lhs;
58    if (!deref->array->type->is_vector())
59       return ir_rvalue_enter_visitor::visit_enter(ir);
60 
61    ir_dereference *const new_lhs = (ir_dereference *) deref->array;
62    ir->set_lhs(new_lhs);
63 
64    void *mem_ctx = ralloc_parent(ir);
65    ir_constant *old_index_constant =
66       deref->array_index->constant_expression_value(mem_ctx);
67    if (!old_index_constant) {
68       ir->rhs = new(mem_ctx) ir_expression(ir_triop_vector_insert,
69                                            new_lhs->type,
70                                            new_lhs->clone(mem_ctx, NULL),
71                                            ir->rhs,
72                                            deref->array_index);
73       ir->write_mask = (1 << new_lhs->type->vector_elements) - 1;
74    } else {
75       ir->write_mask = 1 << old_index_constant->get_int_component(0);
76    }
77 
78    return ir_rvalue_enter_visitor::visit_enter(ir);
79 }
80 
81 void
handle_rvalue(ir_rvalue ** rv)82 vector_deref_visitor::handle_rvalue(ir_rvalue **rv)
83 {
84    if (*rv == NULL || (*rv)->ir_type != ir_type_dereference_array)
85       return;
86 
87    ir_dereference_array *const deref = (ir_dereference_array *) *rv;
88    if (!deref->array->type->is_vector())
89       return;
90 
91    void *mem_ctx = ralloc_parent(deref);
92    *rv = new(mem_ctx) ir_expression(ir_binop_vector_extract,
93                                     deref->array,
94                                     deref->array_index);
95 }
96 
97 bool
lower_vector_derefs(gl_linked_shader * shader)98 lower_vector_derefs(gl_linked_shader *shader)
99 {
100    vector_deref_visitor v;
101 
102    visit_list_elements(&v, shader->ir);
103 
104    return v.progress;
105 }
106