3 * Copyright (c) 2018 Collabora LTD
5 * Author: Gert Wollny <gert.wollny@collabora.com>
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:
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
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.
31 #include "sfn_instruction_base.h"
32 #include "sfn_liverange.h"
33 #include "sfn_valuepool.h"
37 ValueRemapper::ValueRemapper(std::vector
<rename_reg_pair
>& m
,
44 void ValueRemapper::remap(PValue
& v
)
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
));
56 if (addr
->type() == Value::gpr
)
57 val
.reset_addr(remap_one_registers(addr
));
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;
66 void ValueRemapper::remap(GPRVector
& v
)
68 for (int i
= 0; i
< 4; ++i
) {
70 auto& ns_idx
= m_map
[v
.reg_i(i
)->sel()];
72 v
.set_reg_i(i
,m_values
.get_or_inject(ns_idx
.new_reg
, v
.reg_i(i
)->chan()));
73 m_map
[v
.reg_i(i
)->sel()].used
= true;
78 PValue
ValueRemapper::remap_one_registers(PValue
& reg
)
80 auto new_index
= m_map
[reg
->sel()];
82 reg
= m_values
.get_or_inject(new_index
.new_reg
, reg
->chan());
83 m_map
[reg
->sel()].used
= true;
88 Instruction::Instruction(instr_type t
):
93 Instruction::~Instruction()
97 void Instruction::print(std::ostream
& os
) const
104 void Instruction::remap_registers(ValueRemapper
& map
)
106 sfn_log
<< SfnLog::merge
<< "REMAP " << *this << "\n";
107 for (auto& v
: m_mappable_src_registers
)
110 for (auto& v
: m_mappable_src_vectors
)
113 for (auto& v
: m_mappable_dst_registers
)
116 for (auto& v
: m_mappable_dst_vectors
)
118 sfn_log
<< SfnLog::merge
<< "TO " << *this << "\n\n";
121 void Instruction::add_remappable_src_value(PValue
*v
)
123 m_mappable_src_registers
.push_back(v
);
126 void Instruction::add_remappable_src_value(GPRVector
*v
)
128 m_mappable_src_vectors
.push_back(v
);
131 void Instruction::add_remappable_dst_value(PValue
*v
)
133 m_mappable_dst_registers
.push_back(v
);
136 void Instruction::add_remappable_dst_value(GPRVector
*v
)
138 m_mappable_dst_vectors
.push_back(v
);
141 void Instruction::replace_values(UNUSED
const ValueSet
& candiates
, UNUSED PValue new_value
)
146 void Instruction::evalue_liveness(LiverangeEvaluator
& eval
) const
148 sfn_log
<< SfnLog::merge
<< "Scan " << *this << "\n";
149 for (const auto& s
: m_mappable_src_registers
)
151 eval
.record_read(**s
);
153 for (const auto& s
: m_mappable_src_vectors
)
154 eval
.record_read(*s
);
156 for (const auto& s
: m_mappable_dst_registers
)
158 eval
.record_write(**s
);
160 for (const auto& s
: m_mappable_dst_vectors
)
161 eval
.record_write(*s
);
163 do_evalue_liveness(eval
);
166 void Instruction::do_evalue_liveness(UNUSED LiverangeEvaluator
& eval
) const
171 bool operator == (const Instruction
& lhs
, const Instruction
& rhs
)
173 if (rhs
.m_type
!= lhs
.m_type
)
176 return lhs
.is_equal_to(rhs
);