Flutter Engine
The Flutter Engine
parallel_move_resolver.h
Go to the documentation of this file.
1// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_COMPILER_BACKEND_PARALLEL_MOVE_RESOLVER_H_
6#define RUNTIME_VM_COMPILER_BACKEND_PARALLEL_MOVE_RESOLVER_H_
7
8#if defined(DART_PRECOMPILED_RUNTIME)
9#error "AOT runtime should not use compiler sources (including header files)"
10#endif // defined(DART_PRECOMPILED_RUNTIME)
11
12#include "vm/allocation.h"
15#include "vm/constants.h"
16
17namespace dart {
18
19class MoveOperands;
20
22 public:
24
25 // Schedule moves specified by the given parallel move and store the
26 // schedule on the parallel move itself.
27 void Resolve(ParallelMoveInstr* parallel_move);
28
29 private:
30 // Build the initial list of moves.
31 void BuildInitialMoveList(ParallelMoveInstr* parallel_move);
32
33 // Perform the move at the moves_ index in question (possibly requiring
34 // other moves to satisfy dependencies).
35 void PerformMove(const InstructionSource& source, int index);
36
37 // Schedule a move and remove it from the move graph.
38 void AddMoveToSchedule(int index);
39
40 // Schedule a swap of two operands. The move from
41 // source to destination is removed from the move graph.
42 void AddSwapToSchedule(int index);
43
44 FlowGraphCompiler* compiler_;
45
46 // List of moves not yet resolved.
48
49 enum class OpKind : uint8_t {
50 kNop,
51 kMove,
52 kSwap,
53 };
54
55 struct Op {
56 OpKind kind;
57 MoveOperands operands;
58 };
59
60 GrowableArray<Op> scheduled_ops_;
61
62 friend class MoveSchedule;
63 friend class ParallelMoveEmitter;
65};
66
68 public:
70 ParallelMoveInstr* parallel_move)
71 : compiler_(compiler), parallel_move_(parallel_move) {}
72
73 void EmitNativeCode();
74
75 private:
76 class ScratchFpuRegisterScope : public ValueObject {
77 public:
78 ScratchFpuRegisterScope(ParallelMoveEmitter* emitter, FpuRegister blocked);
79 ~ScratchFpuRegisterScope();
80
81 FpuRegister reg() const { return reg_; }
82
83 private:
84 ParallelMoveEmitter* const emitter_;
85 FpuRegister reg_;
86 bool spilled_;
87 };
88
89 class TemporaryAllocator : public TemporaryRegisterAllocator {
90 public:
91 TemporaryAllocator(ParallelMoveEmitter* emitter, Register blocked);
92
93 Register AllocateTemporary() override;
94 void ReleaseTemporary() override;
95 DEBUG_ONLY(bool DidAllocateTemporary() { return allocated_; })
96
97 virtual ~TemporaryAllocator() { ASSERT(reg_ == kNoRegister); }
98
99 private:
100 ParallelMoveEmitter* const emitter_;
101 const Register blocked_;
102 Register reg_;
103 bool spilled_;
104 DEBUG_ONLY(bool allocated_ = false);
105 };
106
107 class ScratchRegisterScope : public ValueObject {
108 public:
109 ScratchRegisterScope(ParallelMoveEmitter* emitter, Register blocked);
110 ~ScratchRegisterScope();
111
112 Register reg() const { return reg_; }
113
114 private:
115 TemporaryAllocator allocator_;
116 Register reg_;
117 };
118
119 bool IsScratchLocation(Location loc);
120 intptr_t AllocateScratchRegister(Location::Kind kind,
121 uword blocked_mask,
122 intptr_t first_free_register,
123 intptr_t last_free_register,
124 bool* spilled);
125
126 void SpillScratch(Register reg);
127 void RestoreScratch(Register reg);
128 void SpillFpuScratch(FpuRegister reg);
129 void RestoreFpuScratch(FpuRegister reg);
130
131 // Generate the code for a move from source to destination.
132 void EmitMove(const MoveOperands& move);
133
134 void EmitSwap(const MoveOperands& swap);
135
136 // Verify the move list before performing moves.
137 void Verify();
138
139 // Helpers for non-trivial source-destination combinations that cannot
140 // be handled by a single instruction.
141 void MoveMemoryToMemory(const compiler::Address& dst,
142 const compiler::Address& src);
143 void Exchange(Register reg, const compiler::Address& mem);
144 void Exchange(const compiler::Address& mem1, const compiler::Address& mem2);
145 void Exchange(Register reg, Register base_reg, intptr_t stack_offset);
146 void Exchange(Register base_reg1,
147 intptr_t stack_offset1,
148 Register base_reg2,
149 intptr_t stack_offset2);
150
151 FlowGraphCompiler* const compiler_;
152 ParallelMoveInstr* parallel_move_;
153 intptr_t current_move_;
154};
155
156} // namespace dart
157
158#endif // RUNTIME_VM_COMPILER_BACKEND_PARALLEL_MOVE_RESOLVER_H_
void swap(sk_sp< T > &a, sk_sp< T > &b)
Definition: SkRefCnt.h:341
ParallelMoveEmitter(FlowGraphCompiler *compiler, ParallelMoveInstr *parallel_move)
void Resolve(ParallelMoveInstr *parallel_move)
@ kMove
Definition: embedder.h:985
#define ASSERT(E)
SkBitmap source
Definition: examples.cpp:28
Definition: dart_vm.cc:33
uintptr_t uword
Definition: globals.h:501
@ kNoRegister
Definition: constants_arm.h:99
QRegister FpuRegister
dst
Definition: cp.py:12
#define DEBUG_ONLY(code)
Definition: globals.h:141