r600/sfn: Move removing of unused variables
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_instruction_alu.cpp
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 #include "sfn_instruction_alu.h"
28 #include "sfn_valuepool.h"
29
30 namespace r600 {
31
32 const AluModifiers AluInstruction::src_abs_flags[2] =
33 {alu_src0_abs, alu_src1_abs};
34 const AluModifiers AluInstruction::src_neg_flags[3] =
35 {alu_src0_neg, alu_src1_neg, alu_src2_neg};
36 const AluModifiers AluInstruction::src_rel_flags[3] =
37 {alu_src0_rel, alu_src1_rel, alu_src2_rel};
38
39 AluInstruction::AluInstruction(EAluOp opcode):
40 Instruction (Instruction::alu),
41 m_opcode(opcode),
42 m_src(alu_ops.at(opcode).nsrc),
43 m_bank_swizzle(alu_vec_unknown),
44 m_cf_type(cf_alu)
45 {
46 if (alu_ops.at(opcode).nsrc == 3)
47 m_flags.set(alu_op3);
48 }
49
50 AluInstruction::AluInstruction(EAluOp opcode, PValue dest,
51 std::vector<PValue> src,
52 const std::set<AluModifiers>& flags):
53 Instruction (Instruction::alu),
54 m_opcode(opcode),
55 m_dest(dest),
56 m_bank_swizzle(alu_vec_unknown),
57 m_cf_type(cf_alu)
58 {
59 m_src.swap(src);
60 for (auto f : flags)
61 m_flags.set(f);
62
63 if (alu_ops.at(opcode).nsrc == 3)
64 m_flags.set(alu_op3);
65
66 for (auto &s: m_src)
67 add_remappable_src_value(&s);
68
69 add_remappable_dst_value(&m_dest);
70 }
71
72 AluInstruction::AluInstruction(EAluOp opcode, PValue dest, PValue src0,
73 const std::set<AluModifiers>& flags):
74 AluInstruction(opcode, dest, std::vector<PValue>{src0}, flags)
75 {
76 }
77
78 AluInstruction::AluInstruction(EAluOp opcode, PValue dest,
79 PValue src0, PValue src1,
80 const std::set<AluModifiers> &m_flags):
81 AluInstruction(opcode, dest, {src0, src1}, m_flags)
82 {
83 }
84
85 AluInstruction::AluInstruction(EAluOp opcode, PValue dest, PValue src0,
86 PValue src1, PValue src2,
87 const std::set<AluModifiers> &flags):
88 AluInstruction(opcode, dest, {src0, src1, src2}, flags)
89 {
90 }
91
92 bool AluInstruction::is_equal_to(const Instruction& lhs) const
93 {
94 assert(lhs.type() == alu);
95 const auto& oth = static_cast<const AluInstruction&>(lhs);
96
97 if (m_opcode != oth.m_opcode) {
98 return false;
99 }
100
101 if (*m_dest != *oth.m_dest)
102 return false;
103
104 if (m_src.size() != oth.m_src.size())
105 return false;
106
107 for (unsigned i = 0; i < m_src.size(); ++i)
108 if (*m_src[i] != *oth.m_src[i]) {
109 return false;
110 }
111 return (m_flags == oth.m_flags && m_cf_type == oth.m_cf_type);
112 }
113
114 void AluInstruction::replace_values(const ValueSet& candiates, PValue new_value)
115 {
116 for (auto c: candiates) {
117 if (*c == *m_dest)
118 m_dest = new_value;
119
120 for (auto& s: m_src) {
121 if (*c == *s)
122 s = new_value;
123 }
124 }
125 }
126
127 PValue AluInstruction::remap_one_registers(PValue reg, std::vector<rename_reg_pair>& map,
128 ValueMap &values)
129 {
130 auto new_index = map[reg->sel()];
131 if (new_index.valid)
132 reg = values.get_or_inject(new_index.new_reg, reg->chan());
133 map[reg->sel()].used = true;
134 return reg;
135 }
136
137
138 void AluInstruction::set_flag(AluModifiers flag)
139 {
140 m_flags.set(flag);
141 }
142
143 void AluInstruction::set_bank_swizzle(AluBankSwizzle bswz)
144 {
145 m_bank_swizzle = bswz;
146 }
147
148 unsigned AluInstruction::n_sources() const
149 {
150 return m_src.size();
151 }
152
153 void AluInstruction::do_print(std::ostream& os) const
154 {
155 os << "ALU " << alu_ops.at(m_opcode).name;
156 if (m_flags.test(alu_dst_clamp))
157 os << "_CLAMP";
158 os << ' ' << *m_dest << " : " ;
159
160 for (unsigned i = 0; i < m_src.size(); ++i) {
161 int pflags = 0;
162 if (i)
163 os << ' ';
164 if (m_flags.test(src_neg_flags[i])) pflags |= Value::PrintFlags::has_neg;
165 if (m_flags.test(src_rel_flags[i])) pflags |= Value::PrintFlags::is_rel;
166 if (i < 2)
167 if (m_flags.test(src_abs_flags[i])) pflags |= Value::PrintFlags::has_abs;
168 m_src[i]->print(os, Value::PrintFlags(0, pflags));
169 }
170 os << " {";
171 os << (m_flags.test(alu_write) ? 'W' : ' ');
172 os << (m_flags.test(alu_last_instr) ? 'L' : ' ');
173 os << (m_flags.test(alu_update_exec) ? 'E' : ' ');
174 os << (m_flags.test(alu_update_pred) ? 'P' : ' ');
175 os << "}";
176
177 os << " BS:" << m_bank_swizzle;
178 os << " CF:" << m_cf_type;
179 }
180
181 }