Lines Matching refs:move
19 // Splits a FP move between two location operands into the equivalent series of
20 // moves between smaller sub-operands, e.g. a double move to two single moves.
23 MoveOperands* Split(MoveOperands* move, MachineRepresentation smaller_rep,
28 const LocationOperand& src_loc = LocationOperand::cast(move->source());
29 const LocationOperand& dst_loc = LocationOperand::cast(move->destination());
63 // Reuse 'move' for the first fragment. It is not pending.
64 move->set_source(AllocatedOperand(src_kind, smaller_rep, src_index));
65 move->set_destination(AllocatedOperand(dst_kind, smaller_rep, dst_index));
74 return move;
79 MoveOperandKind GetKind(const InstructionOperand& move) {
80 if (move.IsConstant()) return kConstant;
81 LocationOperand loc_op = LocationOperand::cast(move);
93 // detect simple non-overlapping moves, and collect FP move representations if
98 MoveOperands* move = (*moves)[i];
99 if (move->IsRedundant()) {
105 source_kinds.Add(GetKind(move->source()));
106 destination_kinds.Add(GetKind(move->destination()));
108 move->destination().IsFPRegister()) {
110 LocationOperand::cast(move->destination()).representation());
117 for (MoveOperands* move : *moves) {
118 assembler_->AssembleMove(&move->source(), &move->destination());
130 auto move = (*moves)[i];
131 if (!move->IsEliminated() && move->destination().IsFloatRegister())
132 PerformMove(moves, move);
138 auto move = (*moves)[i];
139 if (!move->IsEliminated() && move->destination().IsDoubleRegister())
140 PerformMove(moves, move);
148 auto move = (*moves)[i];
149 if (!move->IsEliminated()) PerformMove(moves, move);
153 void GapResolver::PerformMove(ParallelMove* moves, MoveOperands* move) {
154 // Each call to this function performs a move and deletes it from the move
155 // graph. We first recursively perform any move blocking this one. We mark a
156 // move as "pending" on entry to PerformMove in order to detect cycles in the
157 // move graph. We use operand swaps to resolve cycles, which means that a
158 // call to PerformMove could change any source operand in the move graph.
159 DCHECK(!move->IsPending());
160 DCHECK(!move->IsRedundant());
162 // Clear this move's destination to indicate a pending move. The actual
164 InstructionOperand source = move->source();
166 InstructionOperand destination = move->destination();
167 move->SetPending();
173 // Perform a depth-first traversal of the move graph to resolve dependencies.
174 // Any unperformed, unpending move with a source the same as this one's
184 // 'other' must also be an FP location move. Break it into fragments
185 // of the same size as 'move'. 'other' is set to one of the fragments,
191 // Though PerformMove can change any source operand in the move graph,
192 // this call cannot create a blocking move via a swap (this loop does not
193 // miss any). Assume there is a non-blocking move with source A and this
194 // move is blocked on source B and there is a swap of A and B. Then A and
196 // Since this move's destination is B and there is only a single incoming
197 // edge to an operand, this move must also be involved in the same cycle.
198 // In that case, the blocking move will be created but will be "pending"
204 // This move's source may have changed due to swaps to resolve cycles and so
205 // it may now be the last move in the cycle. If so remove it.
206 source = move->source();
208 move->Eliminate();
212 // We are about to resolve this move and don't need it marked as pending, so
214 move->set_destination(destination);
216 // The move may be blocked on a (at most one) pending move, in which case we
217 // have a cycle. Search for such a blocking move and perform a swap to
220 std::find_if(moves->begin(), moves->end(), [&](MoveOperands* move) {
221 return !move->IsEliminated() &&
222 move->source().InterferesWith(destination);
225 // The easy case: This move is not blocked.
227 move->Eliminate();
236 move->Eliminate();