Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/compiler/move-optimizer.cc

Issue 1422333003: [turbofan] optimize redundant moves around splinter sites (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/move-optimizer.h" 5 #include "src/compiler/move-optimizer.h"
6 6
7 namespace v8 { 7 namespace v8 {
8 namespace internal { 8 namespace internal {
9 namespace compiler { 9 namespace compiler {
10 10
11 namespace { 11 namespace {
12 12
13 typedef std::pair<InstructionOperand, InstructionOperand> MoveKey; 13 typedef std::pair<InstructionOperand, InstructionOperand> MoveKey;
14 14
15 struct MoveKeyCompare { 15 struct MoveKeyCompare {
16 bool operator()(const MoveKey& a, const MoveKey& b) const { 16 bool operator()(const MoveKey& a, const MoveKey& b) const {
17 if (a.first.EqualsCanonicalized(b.first)) { 17 if (a.first.EqualsCanonicalized(b.first)) {
18 return a.second.CompareCanonicalized(b.second); 18 return a.second.CompareCanonicalized(b.second);
19 } 19 }
20 return a.first.CompareCanonicalized(b.first); 20 return a.first.CompareCanonicalized(b.first);
21 } 21 }
22 }; 22 };
23 23
24 struct OperandCompare {
25 bool operator()(const InstructionOperand& a,
26 const InstructionOperand& b) const {
27 return a.CompareCanonicalized(b);
28 }
29 };
30
24 typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap; 31 typedef ZoneMap<MoveKey, unsigned, MoveKeyCompare> MoveMap;
25 typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet; 32 typedef ZoneSet<InstructionOperand, CompareOperandModuloType> OperandSet;
26 33
27 34
28 bool GapsCanMoveOver(Instruction* instr) { return instr->IsNop(); } 35 bool GapsCanMoveOver(Instruction* instr, Zone* zone) {
36 if (instr->IsNop()) return true;
37 if (instr->ClobbersTemps() || instr->ClobbersRegisters() ||
38 instr->ClobbersDoubleRegisters()) {
39 return false;
40 }
41 if (instr->arch_opcode() != ArchOpcode::kArchNop) return false;
42
43 ZoneSet<InstructionOperand, OperandCompare> operands(zone);
44 for (size_t i = 0; i < instr->InputCount(); ++i) {
45 operands.insert(*instr->InputAt(i));
46 }
47 for (size_t i = 0; i < instr->OutputCount(); ++i) {
48 operands.insert(*instr->OutputAt(i));
49 }
50 for (size_t i = 0; i < instr->TempCount(); ++i) {
51 operands.insert(*instr->TempAt(i));
52 }
53 for (int i = Instruction::GapPosition::FIRST_GAP_POSITION;
54 i <= Instruction::GapPosition::LAST_GAP_POSITION; ++i) {
55 ParallelMove* moves = instr->parallel_moves()[i];
56 if (moves == nullptr) continue;
57 for (MoveOperands* move : *moves) {
58 if (operands.count(move->source()) > 0 ||
59 operands.count(move->destination()) > 0) {
60 return false;
61 }
62 }
63 }
64 return true;
65 }
29 66
30 67
31 int FindFirstNonEmptySlot(Instruction* instr) { 68 int FindFirstNonEmptySlot(Instruction* instr) {
32 int i = Instruction::FIRST_GAP_POSITION; 69 int i = Instruction::FIRST_GAP_POSITION;
33 for (; i <= Instruction::LAST_GAP_POSITION; i++) { 70 for (; i <= Instruction::LAST_GAP_POSITION; i++) {
34 auto moves = instr->parallel_moves()[i]; 71 auto moves = instr->parallel_moves()[i];
35 if (moves == nullptr) continue; 72 if (moves == nullptr) continue;
36 for (auto move : *moves) { 73 for (auto move : *moves) {
37 if (!move->IsRedundant()) return i; 74 if (!move->IsRedundant()) return i;
38 move->Eliminate(); 75 move->Eliminate();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 // Smash left into prev_instr, killing left. 165 // Smash left into prev_instr, killing left.
129 auto pred_moves = prev_instr->parallel_moves()[0]; 166 auto pred_moves = prev_instr->parallel_moves()[0];
130 CompressMoves(&temp_vector, pred_moves, left); 167 CompressMoves(&temp_vector, pred_moves, left);
131 } 168 }
132 } 169 }
133 if (prev_instr != nullptr) { 170 if (prev_instr != nullptr) {
134 // Slide prev_instr down so we always know where to look for it. 171 // Slide prev_instr down so we always know where to look for it.
135 std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]); 172 std::swap(prev_instr->parallel_moves()[0], instr->parallel_moves()[0]);
136 } 173 }
137 prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr; 174 prev_instr = instr->parallel_moves()[0] == nullptr ? nullptr : instr;
138 if (GapsCanMoveOver(instr)) continue; 175 if (GapsCanMoveOver(instr, local_zone())) continue;
139 if (prev_instr != nullptr) { 176 if (prev_instr != nullptr) {
140 to_finalize_.push_back(prev_instr); 177 to_finalize_.push_back(prev_instr);
141 prev_instr = nullptr; 178 prev_instr = nullptr;
142 } 179 }
143 } 180 }
144 if (prev_instr != nullptr) { 181 if (prev_instr != nullptr) {
145 to_finalize_.push_back(prev_instr); 182 to_finalize_.push_back(prev_instr);
146 } 183 }
147 } 184 }
148 185
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 228 }
192 } 229 }
193 } 230 }
194 } 231 }
195 if (move_map.empty() || correct_counts != move_map.size()) return; 232 if (move_map.empty() || correct_counts != move_map.size()) return;
196 // Find insertion point. 233 // Find insertion point.
197 Instruction* instr = nullptr; 234 Instruction* instr = nullptr;
198 for (int i = block->first_instruction_index(); 235 for (int i = block->first_instruction_index();
199 i <= block->last_instruction_index(); ++i) { 236 i <= block->last_instruction_index(); ++i) {
200 instr = code()->instructions()[i]; 237 instr = code()->instructions()[i];
201 if (!GapsCanMoveOver(instr) || !instr->AreMovesRedundant()) break; 238 if (!GapsCanMoveOver(instr, local_zone()) || !instr->AreMovesRedundant())
239 break;
202 } 240 }
203 DCHECK(instr != nullptr); 241 DCHECK(instr != nullptr);
204 bool gap_initialized = true; 242 bool gap_initialized = true;
205 if (instr->parallel_moves()[0] == nullptr || 243 if (instr->parallel_moves()[0] == nullptr ||
206 instr->parallel_moves()[0]->empty()) { 244 instr->parallel_moves()[0]->empty()) {
207 to_finalize_.push_back(instr); 245 to_finalize_.push_back(instr);
208 } else { 246 } else {
209 // Will compress after insertion. 247 // Will compress after insertion.
210 gap_initialized = false; 248 gap_initialized = false;
211 std::swap(instr->parallel_moves()[0], instr->parallel_moves()[1]); 249 std::swap(instr->parallel_moves()[0], instr->parallel_moves()[1]);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 static_cast<Instruction::GapPosition>(1), code_zone()); 325 static_cast<Instruction::GapPosition>(1), code_zone());
288 slot_1->AddMove(group_begin->destination(), load->destination()); 326 slot_1->AddMove(group_begin->destination(), load->destination());
289 load->Eliminate(); 327 load->Eliminate();
290 } 328 }
291 loads.clear(); 329 loads.clear();
292 } 330 }
293 331
294 } // namespace compiler 332 } // namespace compiler
295 } // namespace internal 333 } // namespace internal
296 } // namespace v8 334 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/move-optimizer-unittest.cc » ('j') | test/unittests/compiler/move-optimizer-unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698