5 #include "src/compiler/backend/gap-resolver.h" 10 #include "src/register-configuration.h" 22 MoveOperands* Split(MoveOperands* move, MachineRepresentation smaller_rep,
23 ParallelMove* moves) {
24 DCHECK(!kSimpleFPAliasing);
26 DCHECK_EQ(kPointerSize, kFloatSize);
27 const LocationOperand& src_loc = LocationOperand::cast(move->source());
28 const LocationOperand& dst_loc = LocationOperand::cast(move->destination());
29 MachineRepresentation dst_rep = dst_loc.representation();
30 DCHECK_NE(smaller_rep, dst_rep);
31 auto src_kind = src_loc.location_kind();
32 auto dst_kind = dst_loc.location_kind();
35 1 << (ElementSizeLog2Of(dst_rep) - ElementSizeLog2Of(smaller_rep));
38 DCHECK_EQ(aliases, RegisterConfiguration::Default()->GetAliases(
39 dst_rep, 0, smaller_rep, &base));
42 int slot_size = (1 << ElementSizeLog2Of(smaller_rep)) / kPointerSize;
44 if (src_kind == LocationOperand::REGISTER) {
45 src_index = src_loc.register_code() * aliases;
47 src_index = src_loc.index();
51 src_step = -slot_size;
55 if (dst_kind == LocationOperand::REGISTER) {
56 dst_index = dst_loc.register_code() * aliases;
58 dst_index = dst_loc.index();
59 dst_step = -slot_size;
63 move->set_source(AllocatedOperand(src_kind, smaller_rep, src_index));
64 move->set_destination(AllocatedOperand(dst_kind, smaller_rep, dst_index));
66 for (
int i = 1;
i < aliases; ++
i) {
67 src_index += src_step;
68 dst_index += dst_step;
69 moves->AddMove(AllocatedOperand(src_kind, smaller_rep, src_index),
70 AllocatedOperand(dst_kind, smaller_rep, dst_index));
78 void GapResolver::Resolve(ParallelMove* moves) {
82 for (
size_t i = 0;
i < moves->size();) {
83 MoveOperands* move = (*moves)[
i];
84 if (move->IsRedundant()) {
85 (*moves)[
i] = moves->back();
90 if (!kSimpleFPAliasing && move->destination().IsFPRegister()) {
91 reps |= RepresentationBit(
92 LocationOperand::cast(move->destination()).representation());
96 if (!kSimpleFPAliasing) {
97 if (reps && !base::bits::IsPowerOfTwo(reps)) {
100 if ((reps & RepresentationBit(MachineRepresentation::kFloat32)) != 0) {
101 split_rep_ = MachineRepresentation::kFloat32;
102 for (
size_t i = 0;
i < moves->size(); ++
i) {
103 auto move = (*moves)[
i];
104 if (!move->IsEliminated() && move->destination().IsFloatRegister())
105 PerformMove(moves, move);
108 if ((reps & RepresentationBit(MachineRepresentation::kFloat64)) != 0) {
109 split_rep_ = MachineRepresentation::kFloat64;
110 for (
size_t i = 0;
i < moves->size(); ++
i) {
111 auto move = (*moves)[
i];
112 if (!move->IsEliminated() && move->destination().IsDoubleRegister())
113 PerformMove(moves, move);
117 split_rep_ = MachineRepresentation::kSimd128;
120 for (
size_t i = 0;
i < moves->size(); ++
i) {
121 auto move = (*moves)[
i];
122 if (!move->IsEliminated()) PerformMove(moves, move);
126 void GapResolver::PerformMove(ParallelMove* moves, MoveOperands* move) {
132 DCHECK(!move->IsPending());
133 DCHECK(!move->IsRedundant());
137 InstructionOperand source = move->source();
138 DCHECK(!source.IsInvalid());
139 InstructionOperand destination = move->destination();
143 const bool is_fp_loc_move =
144 !kSimpleFPAliasing && destination.IsFPLocationOperand();
149 for (
size_t i = 0;
i < moves->size(); ++
i) {
150 auto other = (*moves)[
i];
151 if (other->IsEliminated())
continue;
152 if (other->IsPending())
continue;
153 if (other->source().InterferesWith(destination)) {
154 if (is_fp_loc_move &&
155 LocationOperand::cast(other->source()).representation() >
160 other = Split(other, split_rep_, moves);
162 if (!other->source().InterferesWith(destination))
continue;
173 PerformMove(moves, other);
179 source = move->source();
180 if (source.EqualsCanonicalized(destination)) {
187 move->set_destination(destination);
193 std::find_if(moves->begin(), moves->end(), [&](MoveOperands* move) {
194 return !move->IsEliminated() &&
195 move->source().InterferesWith(destination);
197 if (blocker == moves->end()) {
199 assembler_->AssembleMove(&source, &destination);
205 if (source.IsStackSlot() || source.IsFPStackSlot()) {
206 std::swap(source, destination);
208 assembler_->AssembleSwap(&source, &destination);
212 if (is_fp_loc_move) {
214 for (
size_t i = 0;
i < moves->size(); ++
i) {
215 auto other = (*moves)[
i];
216 if (other->IsEliminated())
continue;
217 if (source.InterferesWith(other->source())) {
218 if (LocationOperand::cast(other->source()).representation() >
220 other = Split(other, split_rep_, moves);
221 if (!source.InterferesWith(other->source()))
continue;
223 other->set_source(destination);
224 }
else if (destination.InterferesWith(other->source())) {
225 if (LocationOperand::cast(other->source()).representation() >
227 other = Split(other, split_rep_, moves);
228 if (!destination.InterferesWith(other->source()))
continue;
230 other->set_source(source);
234 for (
auto other : *moves) {
235 if (other->IsEliminated())
continue;
236 if (source.EqualsCanonicalized(other->source())) {
237 other->set_source(destination);
238 }
else if (destination.EqualsCanonicalized(other->source())) {
239 other->set_source(source);