• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mesa-c++  -*-
2  *
3  * Copyright (c) 2018 Collabora LTD
4  *
5  * Author: Gert Wollny <gert.wollny@collabora.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * on the rights to use, copy, modify, merge, publish, distribute, sub
11  * license, and/or sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 
28 #include <algorithm>
29 #include <cassert>
30 
31 #include "sfn_instruction_base.h"
32 #include "sfn_liverange.h"
33 #include "sfn_valuepool.h"
34 
35 namespace r600  {
36 
ValueRemapper(std::vector<rename_reg_pair> & m,ValueMap & values)37 ValueRemapper::ValueRemapper(std::vector<rename_reg_pair>& m,
38                              ValueMap& values):
39    m_map(m),
40    m_values(values)
41 {
42 }
43 
remap(PValue & v)44 void ValueRemapper::remap(PValue& v)
45 {
46    if (!v)
47       return;
48    if (v->type() == Value::gpr) {
49       v = remap_one_registers(v);
50    } else if (v->type() == Value::gpr_array_value) {
51       GPRArrayValue& val = static_cast<GPRArrayValue&>(*v);
52       auto value = val.value();
53       auto addr = val.indirect();
54       val.reset_value(remap_one_registers(value));
55       if (addr) {
56          if (addr->type() == Value::gpr)
57             val.reset_addr(remap_one_registers(addr));
58       }
59       size_t range_start = val.sel();
60       size_t range_end = range_start + val.array_size();
61       while (range_start < range_end)
62          m_map[range_start++].used = true;
63    } else if (v->type() == Value::kconst) {
64       auto& val = static_cast<UniformValue&>(*v);
65       auto addr = val.addr();
66       if (addr && addr->type() == Value::gpr)
67             val.reset_addr(remap_one_registers(addr));
68    }
69 
70 }
71 
remap(GPRVector & v)72 void ValueRemapper::remap(GPRVector& v)
73 {
74    for (int i = 0; i < 4; ++i) {
75       if (v.reg_i(i)) {
76          auto& ns_idx = m_map[v.reg_i(i)->sel()];
77          if (ns_idx.valid)
78             v.set_reg_i(i,m_values.get_or_inject(ns_idx.new_reg, v.reg_i(i)->chan()));
79          m_map[v.reg_i(i)->sel()].used = true;
80       }
81    }
82 }
83 
remap_one_registers(PValue & reg)84 PValue ValueRemapper::remap_one_registers(PValue& reg)
85 {
86    auto new_index = m_map[reg->sel()];
87    if (new_index.valid)
88       reg = m_values.get_or_inject(new_index.new_reg, reg->chan());
89    m_map[reg->sel()].used = true;
90    return reg;
91 }
92 
93 
Instruction(instr_type t)94 Instruction::Instruction(instr_type t):
95    m_type(t)
96 {
97 }
98 
~Instruction()99 Instruction::~Instruction()
100 {
101 }
102 
print(std::ostream & os) const103 void Instruction::print(std::ostream& os) const
104 {
105    os << "OP:";
106    do_print(os);
107 }
108 
109 
remap_registers(ValueRemapper & map)110 void Instruction::remap_registers(ValueRemapper& map)
111 {
112    sfn_log << SfnLog::merge << "REMAP " << *this << "\n";
113    for (auto& v: m_mappable_src_registers)
114       map.remap(*v);
115 
116    for (auto& v: m_mappable_src_vectors)
117       map.remap(*v);
118 
119    for (auto& v: m_mappable_dst_registers)
120       map.remap(*v);
121 
122    for (auto& v: m_mappable_dst_vectors)
123       map.remap(*v);
124    sfn_log << SfnLog::merge << "TO    " << *this << "\n\n";
125 }
126 
add_remappable_src_value(PValue * v)127 void Instruction::add_remappable_src_value(PValue *v)
128 {
129    if (*v)
130       m_mappable_src_registers.push_back(v);
131 }
132 
add_remappable_src_value(GPRVector * v)133 void Instruction::add_remappable_src_value(GPRVector *v)
134 {
135    m_mappable_src_vectors.push_back(v);
136 }
137 
add_remappable_dst_value(PValue * v)138 void Instruction::add_remappable_dst_value(PValue *v)
139 {
140    if (v)
141       m_mappable_dst_registers.push_back(v);
142 }
143 
add_remappable_dst_value(GPRVector * v)144 void Instruction::add_remappable_dst_value(GPRVector *v)
145 {
146    m_mappable_dst_vectors.push_back(v);
147 }
148 
replace_values(UNUSED const ValueSet & candidates,UNUSED PValue new_value)149 void Instruction::replace_values(UNUSED const ValueSet& candidates, UNUSED PValue new_value)
150 {
151 
152 }
153 
evalue_liveness(LiverangeEvaluator & eval) const154 void Instruction::evalue_liveness(LiverangeEvaluator& eval) const
155 {
156    sfn_log << SfnLog::merge << "Scan " << *this << "\n";
157    for (const auto& s: m_mappable_src_registers)
158       if (*s)
159          eval.record_read(**s);
160 
161    for (const auto& s: m_mappable_src_vectors)
162       eval.record_read(*s);
163 
164    for (const auto& s: m_mappable_dst_registers)
165       if (*s)
166          eval.record_write(**s);
167 
168    for (const auto& s: m_mappable_dst_vectors)
169       eval.record_write(*s);
170 
171    do_evalue_liveness(eval);
172 }
173 
do_evalue_liveness(UNUSED LiverangeEvaluator & eval) const174 void Instruction::do_evalue_liveness(UNUSED LiverangeEvaluator& eval) const
175 {
176 
177 }
178 
operator ==(const Instruction & lhs,const Instruction & rhs)179 bool operator == (const Instruction& lhs, const Instruction& rhs)
180 {
181    if (rhs.m_type != lhs.m_type)
182       return false;
183 
184    return lhs.is_equal_to(rhs);
185 }
186 
187 }
188