| OLD | NEW |
| 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/linkage.h" | 5 #include "src/compiler/linkage.h" |
| 6 #include "src/compiler/register-allocator.h" | 6 #include "src/compiler/register-allocator.h" |
| 7 #include "src/string-stream.h" | 7 #include "src/string-stream.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 return false; | 93 return false; |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 #endif | 97 #endif |
| 98 | 98 |
| 99 | 99 |
| 100 LiveRange::LiveRange(int id, Zone* zone) | 100 LiveRange::LiveRange(int id, Zone* zone) |
| 101 : id_(id), | 101 : id_(id), |
| 102 spilled_(false), | 102 spilled_(false), |
| 103 is_phi_(false), | |
| 104 is_non_loop_phi_(false), | |
| 105 kind_(UNALLOCATED_REGISTERS), | 103 kind_(UNALLOCATED_REGISTERS), |
| 106 assigned_register_(kInvalidAssignment), | 104 assigned_register_(kInvalidAssignment), |
| 107 last_interval_(NULL), | 105 last_interval_(NULL), |
| 108 first_interval_(NULL), | 106 first_interval_(NULL), |
| 109 first_pos_(NULL), | 107 first_pos_(NULL), |
| 110 parent_(NULL), | 108 parent_(NULL), |
| 111 next_(NULL), | 109 next_(NULL), |
| 112 current_interval_(NULL), | 110 current_interval_(NULL), |
| 113 last_processed_use_(NULL), | 111 last_processed_use_(NULL), |
| 114 current_hint_operand_(NULL), | 112 current_hint_operand_(NULL), |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 983 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()); | 981 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()); |
| 984 const ZoneList<MoveOperands>* move_operands = move->move_operands(); | 982 const ZoneList<MoveOperands>* move_operands = move->move_operands(); |
| 985 for (int i = 0; i < move_operands->length(); ++i) { | 983 for (int i = 0; i < move_operands->length(); ++i) { |
| 986 MoveOperands* cur = &move_operands->at(i); | 984 MoveOperands* cur = &move_operands->at(i); |
| 987 if (cur->IsIgnored()) continue; | 985 if (cur->IsIgnored()) continue; |
| 988 InstructionOperand* from = cur->source(); | 986 InstructionOperand* from = cur->source(); |
| 989 InstructionOperand* to = cur->destination(); | 987 InstructionOperand* to = cur->destination(); |
| 990 InstructionOperand* hint = to; | 988 InstructionOperand* hint = to; |
| 991 if (to->IsUnallocated()) { | 989 if (to->IsUnallocated()) { |
| 992 int to_vreg = UnallocatedOperand::cast(to)->virtual_register(); | 990 int to_vreg = UnallocatedOperand::cast(to)->virtual_register(); |
| 993 LiveRange* to_range = LiveRangeFor(to_vreg); | 991 if (live->Contains(to_vreg)) { |
| 994 if (to_range->is_phi()) { | 992 Define(curr_position, to, from); |
| 995 if (to_range->is_non_loop_phi()) { | 993 live->Remove(to_vreg); |
| 996 hint = to_range->current_hint_operand(); | |
| 997 } | |
| 998 } else { | 994 } else { |
| 999 if (live->Contains(to_vreg)) { | 995 cur->Eliminate(); |
| 1000 Define(curr_position, to, from); | 996 continue; |
| 1001 live->Remove(to_vreg); | |
| 1002 } else { | |
| 1003 cur->Eliminate(); | |
| 1004 continue; | |
| 1005 } | |
| 1006 } | 997 } |
| 1007 } else { | 998 } else { |
| 1008 Define(curr_position, to, from); | 999 Define(curr_position, to, from); |
| 1009 } | 1000 } |
| 1010 Use(block_start_position, curr_position, from, hint); | 1001 Use(block_start_position, curr_position, from, hint); |
| 1011 if (from->IsUnallocated()) { | 1002 if (from->IsUnallocated()) { |
| 1012 live->Add(UnallocatedOperand::cast(from)->virtual_register()); | 1003 live->Add(UnallocatedOperand::cast(from)->virtual_register()); |
| 1013 } | 1004 } |
| 1014 } | 1005 } |
| 1015 } else { | 1006 } else { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 } | 1066 } |
| 1076 } | 1067 } |
| 1077 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); | 1068 Use(block_start_position, curr_position.InstructionEnd(), temp, NULL); |
| 1078 Define(curr_position, temp, NULL); | 1069 Define(curr_position, temp, NULL); |
| 1079 } | 1070 } |
| 1080 } | 1071 } |
| 1081 } | 1072 } |
| 1082 } | 1073 } |
| 1083 | 1074 |
| 1084 | 1075 |
| 1085 void RegisterAllocator::ResolvePhis(const InstructionBlock* block) { | 1076 void RegisterAllocator::ProcessPhis(const InstructionBlock* block) { |
| 1086 for (auto phi : block->phis()) { | 1077 for (auto phi : block->phis()) { |
| 1087 UnallocatedOperand* phi_operand = | 1078 auto output = phi->output(); |
| 1088 new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE); | |
| 1089 int phi_vreg = phi->virtual_register(); | 1079 int phi_vreg = phi->virtual_register(); |
| 1090 phi_operand->set_virtual_register(phi_vreg); | |
| 1091 | |
| 1092 for (size_t i = 0; i < phi->operands().size(); ++i) { | |
| 1093 UnallocatedOperand* operand = | |
| 1094 new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); | |
| 1095 operand->set_virtual_register(phi->operands()[i]); | |
| 1096 InstructionBlock* cur_block = | |
| 1097 code()->InstructionBlockAt(block->predecessors()[i]); | |
| 1098 // The gap move must be added without any special processing as in | |
| 1099 // the AddConstraintsGapMove. | |
| 1100 code()->AddGapMove(cur_block->last_instruction_index() - 1, operand, | |
| 1101 phi_operand); | |
| 1102 | |
| 1103 Instruction* branch = InstructionAt(cur_block->last_instruction_index()); | |
| 1104 DCHECK(!branch->HasPointerMap()); | |
| 1105 USE(branch); | |
| 1106 } | |
| 1107 | |
| 1108 LiveRange* live_range = LiveRangeFor(phi_vreg); | 1080 LiveRange* live_range = LiveRangeFor(phi_vreg); |
| 1109 BlockStartInstruction* block_start = | 1081 BlockStartInstruction* block_start = |
| 1110 code()->GetBlockStart(block->rpo_number()); | 1082 code()->GetBlockStart(block->rpo_number()); |
| 1111 block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) | 1083 block_start->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone()) |
| 1112 ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); | 1084 ->AddMove(output, live_range->GetSpillOperand(), code_zone()); |
| 1113 live_range->SetSpillStartIndex(block->first_instruction_index()); | 1085 live_range->SetSpillStartIndex(block->first_instruction_index()); |
| 1114 | |
| 1115 // We use the phi-ness of some nodes in some later heuristics. | |
| 1116 live_range->set_is_phi(true); | |
| 1117 if (!block->IsLoopHeader()) { | |
| 1118 live_range->set_is_non_loop_phi(true); | |
| 1119 } | |
| 1120 } | 1086 } |
| 1121 } | 1087 } |
| 1122 | 1088 |
| 1123 | 1089 |
| 1124 void RegisterAllocator::MeetRegisterConstraints() { | 1090 void RegisterAllocator::MeetRegisterConstraints() { |
| 1125 for (auto block : code()->instruction_blocks()) { | 1091 for (auto block : code()->instruction_blocks()) { |
| 1092 ProcessPhis(block); |
| 1126 MeetRegisterConstraints(block); | 1093 MeetRegisterConstraints(block); |
| 1127 if (!AllocationOk()) return; | |
| 1128 } | 1094 } |
| 1129 } | 1095 } |
| 1130 | 1096 |
| 1131 | |
| 1132 void RegisterAllocator::ResolvePhis() { | |
| 1133 // Process the blocks in reverse order. | |
| 1134 for (auto i = code()->instruction_blocks().rbegin(); | |
| 1135 i != code()->instruction_blocks().rend(); ++i) { | |
| 1136 ResolvePhis(*i); | |
| 1137 } | |
| 1138 } | |
| 1139 | |
| 1140 | 1097 |
| 1141 ParallelMove* RegisterAllocator::GetConnectingParallelMove( | 1098 ParallelMove* RegisterAllocator::GetConnectingParallelMove( |
| 1142 LifetimePosition pos) { | 1099 LifetimePosition pos) { |
| 1143 int index = pos.InstructionIndex(); | 1100 int index = pos.InstructionIndex(); |
| 1144 if (code()->IsGapAt(index)) { | 1101 if (code()->IsGapAt(index)) { |
| 1145 GapInstruction* gap = code()->GapAt(index); | 1102 GapInstruction* gap = code()->GapAt(index); |
| 1146 return gap->GetOrCreateParallelMove( | 1103 return gap->GetOrCreateParallelMove( |
| 1147 pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END, | 1104 pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END, |
| 1148 code_zone()); | 1105 code_zone()); |
| 1149 } | 1106 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1259 if (bound->start_.Value() <= position.Value()) { | 1216 if (bound->start_.Value() <= position.Value()) { |
| 1260 if (position.Value() < bound->end_.Value()) return bound; | 1217 if (position.Value() < bound->end_.Value()) return bound; |
| 1261 DCHECK(left_index < current_index); | 1218 DCHECK(left_index < current_index); |
| 1262 left_index = current_index; | 1219 left_index = current_index; |
| 1263 } else { | 1220 } else { |
| 1264 right_index = current_index; | 1221 right_index = current_index; |
| 1265 } | 1222 } |
| 1266 } | 1223 } |
| 1267 } | 1224 } |
| 1268 | 1225 |
| 1226 LiveRangeBound* FindPred(const InstructionBlock* pred) { |
| 1227 const LifetimePosition pred_end = |
| 1228 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); |
| 1229 return Find(pred_end); |
| 1230 } |
| 1231 |
| 1232 LiveRangeBound* FindSucc(const InstructionBlock* succ) { |
| 1233 const LifetimePosition succ_start = |
| 1234 LifetimePosition::FromInstructionIndex(succ->first_instruction_index()); |
| 1235 return Find(succ_start); |
| 1236 } |
| 1237 |
| 1269 void Find(const InstructionBlock* block, const InstructionBlock* pred, | 1238 void Find(const InstructionBlock* block, const InstructionBlock* pred, |
| 1270 FindResult* result) const { | 1239 FindResult* result) const { |
| 1271 const LifetimePosition pred_end = | 1240 const LifetimePosition pred_end = |
| 1272 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); | 1241 LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); |
| 1273 LiveRangeBound* bound = Find(pred_end); | 1242 LiveRangeBound* bound = Find(pred_end); |
| 1274 result->pred_cover_ = bound->range_; | 1243 result->pred_cover_ = bound->range_; |
| 1275 const LifetimePosition cur_start = LifetimePosition::FromInstructionIndex( | 1244 const LifetimePosition cur_start = LifetimePosition::FromInstructionIndex( |
| 1276 block->first_instruction_index()); | 1245 block->first_instruction_index()); |
| 1277 // Common case. | 1246 // Common case. |
| 1278 if (bound->CanCover(cur_start)) { | 1247 if (bound->CanCover(cur_start)) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 }; | 1292 }; |
| 1324 | 1293 |
| 1325 } // namespace | 1294 } // namespace |
| 1326 | 1295 |
| 1327 | 1296 |
| 1328 void RegisterAllocator::ResolveControlFlow() { | 1297 void RegisterAllocator::ResolveControlFlow() { |
| 1329 // Lazily linearize live ranges in memory for fast lookup. | 1298 // Lazily linearize live ranges in memory for fast lookup. |
| 1330 LiveRangeFinder finder(*this); | 1299 LiveRangeFinder finder(*this); |
| 1331 for (auto block : code()->instruction_blocks()) { | 1300 for (auto block : code()->instruction_blocks()) { |
| 1332 if (CanEagerlyResolveControlFlow(block)) continue; | 1301 if (CanEagerlyResolveControlFlow(block)) continue; |
| 1302 // resolve phis |
| 1303 for (auto phi : block->phis()) { |
| 1304 auto* block_bound = |
| 1305 finder.ArrayFor(phi->virtual_register())->FindSucc(block); |
| 1306 auto phi_output = block_bound->range_->CreateAssignedOperand(code_zone()); |
| 1307 phi->output()->ConvertTo(phi_output->kind(), phi_output->index()); |
| 1308 size_t pred_index = 0; |
| 1309 for (auto pred : block->predecessors()) { |
| 1310 const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); |
| 1311 auto* pred_bound = |
| 1312 finder.ArrayFor(phi->operands()[pred_index])->FindPred(pred_block); |
| 1313 auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone()); |
| 1314 phi->inputs()[pred_index] = pred_op; |
| 1315 ResolveControlFlow(block, phi_output, pred_block, pred_op); |
| 1316 pred_index++; |
| 1317 } |
| 1318 } |
| 1333 BitVector* live = live_in_sets_[block->rpo_number().ToInt()]; | 1319 BitVector* live = live_in_sets_[block->rpo_number().ToInt()]; |
| 1334 BitVector::Iterator iterator(live); | 1320 BitVector::Iterator iterator(live); |
| 1335 while (!iterator.Done()) { | 1321 while (!iterator.Done()) { |
| 1336 LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current()); | 1322 auto* array = finder.ArrayFor(iterator.Current()); |
| 1337 for (auto pred : block->predecessors()) { | 1323 for (auto pred : block->predecessors()) { |
| 1338 FindResult result; | 1324 FindResult result; |
| 1339 const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); | 1325 const auto* pred_block = code()->InstructionBlockAt(pred); |
| 1340 array->Find(block, pred_block, &result); | 1326 array->Find(block, pred_block, &result); |
| 1341 if (result.cur_cover_ == result.pred_cover_ || | 1327 if (result.cur_cover_ == result.pred_cover_ || |
| 1342 result.cur_cover_->IsSpilled()) | 1328 result.cur_cover_->IsSpilled()) |
| 1343 continue; | 1329 continue; |
| 1344 ResolveControlFlow(block, result.cur_cover_, pred_block, | 1330 InstructionOperand* pred_op = |
| 1345 result.pred_cover_); | 1331 result.pred_cover_->CreateAssignedOperand(code_zone()); |
| 1332 InstructionOperand* cur_op = |
| 1333 result.cur_cover_->CreateAssignedOperand(code_zone()); |
| 1334 ResolveControlFlow(block, cur_op, pred_block, pred_op); |
| 1346 } | 1335 } |
| 1347 iterator.Advance(); | 1336 iterator.Advance(); |
| 1348 } | 1337 } |
| 1349 } | 1338 } |
| 1350 } | 1339 } |
| 1351 | 1340 |
| 1352 | 1341 |
| 1353 void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block, | 1342 void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block, |
| 1354 const LiveRange* cur_cover, | 1343 InstructionOperand* cur_op, |
| 1355 const InstructionBlock* pred, | 1344 const InstructionBlock* pred, |
| 1356 const LiveRange* pred_cover) { | 1345 InstructionOperand* pred_op) { |
| 1357 InstructionOperand* pred_op = pred_cover->CreateAssignedOperand(code_zone()); | 1346 if (pred_op->Equals(cur_op)) return; |
| 1358 InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone()); | 1347 GapInstruction* gap = nullptr; |
| 1359 if (!pred_op->Equals(cur_op)) { | 1348 if (block->PredecessorCount() == 1) { |
| 1360 GapInstruction* gap = NULL; | 1349 gap = code()->GapAt(block->first_instruction_index()); |
| 1361 if (block->PredecessorCount() == 1) { | 1350 } else { |
| 1362 gap = code()->GapAt(block->first_instruction_index()); | 1351 DCHECK(pred->SuccessorCount() == 1); |
| 1363 } else { | 1352 gap = GetLastGap(pred); |
| 1364 DCHECK(pred->SuccessorCount() == 1); | |
| 1365 gap = GetLastGap(pred); | |
| 1366 | 1353 |
| 1367 Instruction* branch = InstructionAt(pred->last_instruction_index()); | 1354 Instruction* branch = InstructionAt(pred->last_instruction_index()); |
| 1368 DCHECK(!branch->HasPointerMap()); | 1355 DCHECK(!branch->HasPointerMap()); |
| 1369 USE(branch); | 1356 USE(branch); |
| 1370 } | |
| 1371 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()) | |
| 1372 ->AddMove(pred_op, cur_op, code_zone()); | |
| 1373 } | 1357 } |
| 1358 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()) |
| 1359 ->AddMove(pred_op, cur_op, code_zone()); |
| 1374 } | 1360 } |
| 1375 | 1361 |
| 1376 | 1362 |
| 1377 void RegisterAllocator::BuildLiveRanges() { | 1363 void RegisterAllocator::BuildLiveRanges() { |
| 1378 InitializeLivenessAnalysis(); | 1364 InitializeLivenessAnalysis(); |
| 1379 // Process the blocks in reverse order. | 1365 // Process the blocks in reverse order. |
| 1380 for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0; | 1366 for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0; |
| 1381 --block_id) { | 1367 --block_id) { |
| 1382 const InstructionBlock* block = | 1368 const InstructionBlock* block = |
| 1383 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); | 1369 code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); |
| 1384 BitVector* live = ComputeLiveOut(block); | 1370 BitVector* live = ComputeLiveOut(block); |
| 1385 // Initially consider all live_out values live for the entire block. We | 1371 // Initially consider all live_out values live for the entire block. We |
| 1386 // will shorten these intervals if necessary. | 1372 // will shorten these intervals if necessary. |
| 1387 AddInitialIntervals(block, live); | 1373 AddInitialIntervals(block, live); |
| 1388 | 1374 |
| 1389 // Process the instructions in reverse order, generating and killing | 1375 // Process the instructions in reverse order, generating and killing |
| 1390 // live values. | 1376 // live values. |
| 1391 ProcessInstructions(block, live); | 1377 ProcessInstructions(block, live); |
| 1392 // All phi output operands are killed by this block. | 1378 // All phi output operands are killed by this block. |
| 1393 for (auto phi : block->phis()) { | 1379 for (auto phi : block->phis()) { |
| 1394 // The live range interval already ends at the first instruction of the | 1380 // The live range interval already ends at the first instruction of the |
| 1395 // block. | 1381 // block. |
| 1396 int phi_vreg = phi->virtual_register(); | 1382 int phi_vreg = phi->virtual_register(); |
| 1397 live->Remove(phi_vreg); | 1383 live->Remove(phi_vreg); |
| 1398 | |
| 1399 InstructionOperand* hint = NULL; | |
| 1400 InstructionOperand* phi_operand = NULL; | |
| 1401 GapInstruction* gap = | |
| 1402 GetLastGap(code()->InstructionBlockAt(block->predecessors()[0])); | |
| 1403 | |
| 1404 // TODO(titzer): no need to create the parallel move if it doesn't exit. | |
| 1405 ParallelMove* move = | |
| 1406 gap->GetOrCreateParallelMove(GapInstruction::START, code_zone()); | |
| 1407 for (int j = 0; j < move->move_operands()->length(); ++j) { | |
| 1408 InstructionOperand* to = move->move_operands()->at(j).destination(); | |
| 1409 if (to->IsUnallocated() && | |
| 1410 UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) { | |
| 1411 hint = move->move_operands()->at(j).source(); | |
| 1412 phi_operand = to; | |
| 1413 break; | |
| 1414 } | |
| 1415 } | |
| 1416 DCHECK(hint != NULL); | |
| 1417 | |
| 1418 LifetimePosition block_start = LifetimePosition::FromInstructionIndex( | |
| 1419 block->first_instruction_index()); | |
| 1420 Define(block_start, phi_operand, hint); | |
| 1421 } | 1384 } |
| 1422 | 1385 |
| 1423 // Now live is live_in for this block except not including values live | 1386 // Now live is live_in for this block except not including values live |
| 1424 // out on backward successor edges. | 1387 // out on backward successor edges. |
| 1425 live_in_sets_[block_id] = live; | 1388 live_in_sets_[block_id] = live; |
| 1426 | 1389 |
| 1427 if (block->IsLoopHeader()) { | 1390 if (block->IsLoopHeader()) { |
| 1428 // Add a live range stretching from the first loop instruction to the last | 1391 // Add a live range stretching from the first loop instruction to the last |
| 1429 // for each value live on entry to the header. | 1392 // for each value live on entry to the header. |
| 1430 BitVector::Iterator iterator(live); | 1393 BitVector::Iterator iterator(live); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1455 // TODO(bmeurer): This is a horrible hack to make sure that for constant | 1418 // TODO(bmeurer): This is a horrible hack to make sure that for constant |
| 1456 // live ranges, every use requires the constant to be in a register. | 1419 // live ranges, every use requires the constant to be in a register. |
| 1457 // Without this hack, all uses with "any" policy would get the constant | 1420 // Without this hack, all uses with "any" policy would get the constant |
| 1458 // operand assigned. | 1421 // operand assigned. |
| 1459 LiveRange* range = live_ranges_[i]; | 1422 LiveRange* range = live_ranges_[i]; |
| 1460 if (range->HasAllocatedSpillOperand() && | 1423 if (range->HasAllocatedSpillOperand() && |
| 1461 range->GetSpillOperand()->IsConstant()) { | 1424 range->GetSpillOperand()->IsConstant()) { |
| 1462 for (UsePosition* pos = range->first_pos(); pos != NULL; | 1425 for (UsePosition* pos = range->first_pos(); pos != NULL; |
| 1463 pos = pos->next_) { | 1426 pos = pos->next_) { |
| 1464 pos->register_beneficial_ = true; | 1427 pos->register_beneficial_ = true; |
| 1465 // TODO(dcarney): should the else case assert requires_reg_ == false? | 1428 pos->requires_reg_ = true; |
| 1466 // Can't mark phis as needing a register. | |
| 1467 if (!code() | |
| 1468 ->InstructionAt(pos->pos().InstructionIndex()) | |
| 1469 ->IsGapMoves()) { | |
| 1470 pos->requires_reg_ = true; | |
| 1471 } | |
| 1472 } | 1429 } |
| 1473 } | 1430 } |
| 1474 } | 1431 } |
| 1475 } | 1432 } |
| 1476 } | 1433 } |
| 1477 | 1434 |
| 1478 | 1435 |
| 1479 bool RegisterAllocator::ExistsUseWithoutDefinition() { | 1436 bool RegisterAllocator::ExistsUseWithoutDefinition() { |
| 1480 bool found = false; | 1437 bool found = false; |
| 1481 BitVector::Iterator iterator(live_in_sets_[0]); | 1438 BitVector::Iterator iterator(live_in_sets_[0]); |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2276 } else { | 2233 } else { |
| 2277 DCHECK(range->Kind() == GENERAL_REGISTERS); | 2234 DCHECK(range->Kind() == GENERAL_REGISTERS); |
| 2278 assigned_registers_->Add(reg); | 2235 assigned_registers_->Add(reg); |
| 2279 } | 2236 } |
| 2280 range->set_assigned_register(reg, code_zone()); | 2237 range->set_assigned_register(reg, code_zone()); |
| 2281 } | 2238 } |
| 2282 | 2239 |
| 2283 } | 2240 } |
| 2284 } | 2241 } |
| 2285 } // namespace v8::internal::compiler | 2242 } // namespace v8::internal::compiler |
| OLD | NEW |