| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 assigned_double_registers_->Clear(); | 1088 assigned_double_registers_->Clear(); |
| 1089 MeetRegisterConstraints(); | 1089 MeetRegisterConstraints(); |
| 1090 if (!AllocationOk()) return false; | 1090 if (!AllocationOk()) return false; |
| 1091 ResolvePhis(); | 1091 ResolvePhis(); |
| 1092 BuildLiveRanges(); | 1092 BuildLiveRanges(); |
| 1093 AllocateGeneralRegisters(); | 1093 AllocateGeneralRegisters(); |
| 1094 if (!AllocationOk()) return false; | 1094 if (!AllocationOk()) return false; |
| 1095 AllocateDoubleRegisters(); | 1095 AllocateDoubleRegisters(); |
| 1096 if (!AllocationOk()) return false; | 1096 if (!AllocationOk()) return false; |
| 1097 PopulatePointerMaps(); | 1097 PopulatePointerMaps(); |
| 1098 if (has_osr_entry_) ProcessOsrEntry(); | |
| 1099 ConnectRanges(); | 1098 ConnectRanges(); |
| 1100 ResolveControlFlow(); | 1099 ResolveControlFlow(); |
| 1101 return true; | 1100 return true; |
| 1102 } | 1101 } |
| 1103 | 1102 |
| 1104 | 1103 |
| 1105 void LAllocator::MeetRegisterConstraints() { | 1104 void LAllocator::MeetRegisterConstraints() { |
| 1106 HPhase phase("L_Register constraints", chunk_); | 1105 LAllocatorPhase phase("L_Register constraints", this); |
| 1107 first_artificial_register_ = next_virtual_register_; | 1106 first_artificial_register_ = next_virtual_register_; |
| 1108 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 1107 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
| 1109 for (int i = 0; i < blocks->length(); ++i) { | 1108 for (int i = 0; i < blocks->length(); ++i) { |
| 1110 HBasicBlock* block = blocks->at(i); | 1109 HBasicBlock* block = blocks->at(i); |
| 1111 MeetRegisterConstraints(block); | 1110 MeetRegisterConstraints(block); |
| 1112 if (!AllocationOk()) return; | 1111 if (!AllocationOk()) return; |
| 1113 } | 1112 } |
| 1114 } | 1113 } |
| 1115 | 1114 |
| 1116 | 1115 |
| 1117 void LAllocator::ResolvePhis() { | 1116 void LAllocator::ResolvePhis() { |
| 1118 HPhase phase("L_Resolve phis", chunk_); | 1117 LAllocatorPhase phase("L_Resolve phis", this); |
| 1119 | 1118 |
| 1120 // Process the blocks in reverse order. | 1119 // Process the blocks in reverse order. |
| 1121 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 1120 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
| 1122 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { | 1121 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { |
| 1123 HBasicBlock* block = blocks->at(block_id); | 1122 HBasicBlock* block = blocks->at(block_id); |
| 1124 ResolvePhis(block); | 1123 ResolvePhis(block); |
| 1125 } | 1124 } |
| 1126 } | 1125 } |
| 1127 | 1126 |
| 1128 | 1127 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 } | 1198 } |
| 1200 | 1199 |
| 1201 | 1200 |
| 1202 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) { | 1201 HBasicBlock* LAllocator::GetBlock(LifetimePosition pos) { |
| 1203 LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex())); | 1202 LGap* gap = GapAt(chunk_->NearestGapPos(pos.InstructionIndex())); |
| 1204 return gap->block(); | 1203 return gap->block(); |
| 1205 } | 1204 } |
| 1206 | 1205 |
| 1207 | 1206 |
| 1208 void LAllocator::ConnectRanges() { | 1207 void LAllocator::ConnectRanges() { |
| 1209 HPhase phase("L_Connect ranges", this); | 1208 LAllocatorPhase phase("L_Connect ranges", this); |
| 1210 for (int i = 0; i < live_ranges()->length(); ++i) { | 1209 for (int i = 0; i < live_ranges()->length(); ++i) { |
| 1211 LiveRange* first_range = live_ranges()->at(i); | 1210 LiveRange* first_range = live_ranges()->at(i); |
| 1212 if (first_range == NULL || first_range->parent() != NULL) continue; | 1211 if (first_range == NULL || first_range->parent() != NULL) continue; |
| 1213 | 1212 |
| 1214 LiveRange* second_range = first_range->next(); | 1213 LiveRange* second_range = first_range->next(); |
| 1215 while (second_range != NULL) { | 1214 while (second_range != NULL) { |
| 1216 LifetimePosition pos = second_range->Start(); | 1215 LifetimePosition pos = second_range->Start(); |
| 1217 | 1216 |
| 1218 if (!second_range->IsSpilled()) { | 1217 if (!second_range->IsSpilled()) { |
| 1219 // Add gap move if the two live ranges touch and there is no block | 1218 // Add gap move if the two live ranges touch and there is no block |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1239 } | 1238 } |
| 1240 | 1239 |
| 1241 | 1240 |
| 1242 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const { | 1241 bool LAllocator::CanEagerlyResolveControlFlow(HBasicBlock* block) const { |
| 1243 if (block->predecessors()->length() != 1) return false; | 1242 if (block->predecessors()->length() != 1) return false; |
| 1244 return block->predecessors()->first()->block_id() == block->block_id() - 1; | 1243 return block->predecessors()->first()->block_id() == block->block_id() - 1; |
| 1245 } | 1244 } |
| 1246 | 1245 |
| 1247 | 1246 |
| 1248 void LAllocator::ResolveControlFlow() { | 1247 void LAllocator::ResolveControlFlow() { |
| 1249 HPhase phase("L_Resolve control flow", this); | 1248 LAllocatorPhase phase("L_Resolve control flow", this); |
| 1250 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 1249 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
| 1251 for (int block_id = 1; block_id < blocks->length(); ++block_id) { | 1250 for (int block_id = 1; block_id < blocks->length(); ++block_id) { |
| 1252 HBasicBlock* block = blocks->at(block_id); | 1251 HBasicBlock* block = blocks->at(block_id); |
| 1253 if (CanEagerlyResolveControlFlow(block)) continue; | 1252 if (CanEagerlyResolveControlFlow(block)) continue; |
| 1254 BitVector* live = live_in_sets_[block->block_id()]; | 1253 BitVector* live = live_in_sets_[block->block_id()]; |
| 1255 BitVector::Iterator iterator(live); | 1254 BitVector::Iterator iterator(live); |
| 1256 while (!iterator.Done()) { | 1255 while (!iterator.Done()) { |
| 1257 int operand_index = iterator.Current(); | 1256 int operand_index = iterator.Current(); |
| 1258 for (int i = 0; i < block->predecessors()->length(); ++i) { | 1257 for (int i = 0; i < block->predecessors()->length(); ++i) { |
| 1259 HBasicBlock* cur = block->predecessors()->at(i); | 1258 HBasicBlock* cur = block->predecessors()->at(i); |
| 1260 LiveRange* cur_range = LiveRangeFor(operand_index); | 1259 LiveRange* cur_range = LiveRangeFor(operand_index); |
| 1261 ResolveControlFlow(cur_range, block, cur); | 1260 ResolveControlFlow(cur_range, block, cur); |
| 1262 } | 1261 } |
| 1263 iterator.Advance(); | 1262 iterator.Advance(); |
| 1264 } | 1263 } |
| 1265 } | 1264 } |
| 1266 } | 1265 } |
| 1267 | 1266 |
| 1268 | 1267 |
| 1269 void LAllocator::BuildLiveRanges() { | 1268 void LAllocator::BuildLiveRanges() { |
| 1270 HPhase phase("L_Build live ranges", this); | 1269 LAllocatorPhase phase("L_Build live ranges", this); |
| 1271 InitializeLivenessAnalysis(); | 1270 InitializeLivenessAnalysis(); |
| 1272 // Process the blocks in reverse order. | 1271 // Process the blocks in reverse order. |
| 1273 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 1272 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
| 1274 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { | 1273 for (int block_id = blocks->length() - 1; block_id >= 0; --block_id) { |
| 1275 HBasicBlock* block = blocks->at(block_id); | 1274 HBasicBlock* block = blocks->at(block_id); |
| 1276 BitVector* live = ComputeLiveOut(block); | 1275 BitVector* live = ComputeLiveOut(block); |
| 1277 // Initially consider all live_out values live for the entire block. We | 1276 // Initially consider all live_out values live for the entire block. We |
| 1278 // will shorten these intervals if necessary. | 1277 // will shorten these intervals if necessary. |
| 1279 AddInitialIntervals(block, live); | 1278 AddInitialIntervals(block, live); |
| 1280 | 1279 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 for (int i = 0; i < pointer_maps->length(); ++i) { | 1371 for (int i = 0; i < pointer_maps->length(); ++i) { |
| 1373 LPointerMap* map = pointer_maps->at(i); | 1372 LPointerMap* map = pointer_maps->at(i); |
| 1374 if (safe_point > map->lithium_position()) return false; | 1373 if (safe_point > map->lithium_position()) return false; |
| 1375 safe_point = map->lithium_position(); | 1374 safe_point = map->lithium_position(); |
| 1376 } | 1375 } |
| 1377 return true; | 1376 return true; |
| 1378 } | 1377 } |
| 1379 | 1378 |
| 1380 | 1379 |
| 1381 void LAllocator::PopulatePointerMaps() { | 1380 void LAllocator::PopulatePointerMaps() { |
| 1382 HPhase phase("L_Populate pointer maps", this); | 1381 LAllocatorPhase phase("L_Populate pointer maps", this); |
| 1383 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps(); | 1382 const ZoneList<LPointerMap*>* pointer_maps = chunk_->pointer_maps(); |
| 1384 | 1383 |
| 1385 ASSERT(SafePointsAreInOrder()); | 1384 ASSERT(SafePointsAreInOrder()); |
| 1386 | 1385 |
| 1387 // Iterate over all safe point positions and record a pointer | 1386 // Iterate over all safe point positions and record a pointer |
| 1388 // for all spilled live ranges at this point. | 1387 // for all spilled live ranges at this point. |
| 1389 int first_safe_point_index = 0; | 1388 int first_safe_point_index = 0; |
| 1390 int last_range_start = 0; | 1389 int last_range_start = 0; |
| 1391 for (int range_idx = 0; range_idx < live_ranges()->length(); ++range_idx) { | 1390 for (int range_idx = 0; range_idx < live_ranges()->length(); ++range_idx) { |
| 1392 LiveRange* range = live_ranges()->at(range_idx); | 1391 LiveRange* range = live_ranges()->at(range_idx); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1459 cur->id(), cur->Start().Value(), safe_point); | 1458 cur->id(), cur->Start().Value(), safe_point); |
| 1460 LOperand* operand = cur->CreateAssignedOperand(zone_); | 1459 LOperand* operand = cur->CreateAssignedOperand(zone_); |
| 1461 ASSERT(!operand->IsStackSlot()); | 1460 ASSERT(!operand->IsStackSlot()); |
| 1462 map->RecordPointer(operand, zone()); | 1461 map->RecordPointer(operand, zone()); |
| 1463 } | 1462 } |
| 1464 } | 1463 } |
| 1465 } | 1464 } |
| 1466 } | 1465 } |
| 1467 | 1466 |
| 1468 | 1467 |
| 1469 void LAllocator::ProcessOsrEntry() { | |
| 1470 const ZoneList<LInstruction*>* instrs = chunk_->instructions(); | |
| 1471 | |
| 1472 // Linear search for the OSR entry instruction in the chunk. | |
| 1473 int index = -1; | |
| 1474 while (++index < instrs->length() && | |
| 1475 !instrs->at(index)->IsOsrEntry()) { | |
| 1476 } | |
| 1477 ASSERT(index < instrs->length()); | |
| 1478 LOsrEntry* instruction = LOsrEntry::cast(instrs->at(index)); | |
| 1479 | |
| 1480 LifetimePosition position = LifetimePosition::FromInstructionIndex(index); | |
| 1481 for (int i = 0; i < live_ranges()->length(); ++i) { | |
| 1482 LiveRange* range = live_ranges()->at(i); | |
| 1483 if (range != NULL) { | |
| 1484 if (range->Covers(position) && | |
| 1485 range->HasRegisterAssigned() && | |
| 1486 range->TopLevel()->HasAllocatedSpillOperand()) { | |
| 1487 int reg_index = range->assigned_register(); | |
| 1488 LOperand* spill_operand = range->TopLevel()->GetSpillOperand(); | |
| 1489 if (range->IsDouble()) { | |
| 1490 instruction->MarkSpilledDoubleRegister(reg_index, spill_operand); | |
| 1491 } else { | |
| 1492 instruction->MarkSpilledRegister(reg_index, spill_operand); | |
| 1493 } | |
| 1494 } | |
| 1495 } | |
| 1496 } | |
| 1497 } | |
| 1498 | |
| 1499 | |
| 1500 void LAllocator::AllocateGeneralRegisters() { | 1468 void LAllocator::AllocateGeneralRegisters() { |
| 1501 HPhase phase("L_Allocate general registers", this); | 1469 LAllocatorPhase phase("L_Allocate general registers", this); |
| 1502 num_registers_ = Register::NumAllocatableRegisters(); | 1470 num_registers_ = Register::NumAllocatableRegisters(); |
| 1503 AllocateRegisters(); | 1471 AllocateRegisters(); |
| 1504 } | 1472 } |
| 1505 | 1473 |
| 1506 | 1474 |
| 1507 void LAllocator::AllocateDoubleRegisters() { | 1475 void LAllocator::AllocateDoubleRegisters() { |
| 1508 HPhase phase("L_Allocate double registers", this); | 1476 LAllocatorPhase phase("L_Allocate double registers", this); |
| 1509 num_registers_ = DoubleRegister::NumAllocatableRegisters(); | 1477 num_registers_ = DoubleRegister::NumAllocatableRegisters(); |
| 1510 mode_ = DOUBLE_REGISTERS; | 1478 mode_ = DOUBLE_REGISTERS; |
| 1511 AllocateRegisters(); | 1479 AllocateRegisters(); |
| 1512 } | 1480 } |
| 1513 | 1481 |
| 1514 | 1482 |
| 1515 void LAllocator::AllocateRegisters() { | 1483 void LAllocator::AllocateRegisters() { |
| 1516 ASSERT(unhandled_live_ranges_.is_empty()); | 1484 ASSERT(unhandled_live_ranges_.is_empty()); |
| 1517 | 1485 |
| 1518 for (int i = 0; i < live_ranges_.length(); ++i) { | 1486 for (int i = 0; i < live_ranges_.length(); ++i) { |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2187 for (int i = 0; i < live_ranges()->length(); ++i) { | 2155 for (int i = 0; i < live_ranges()->length(); ++i) { |
| 2188 LiveRange* current = live_ranges()->at(i); | 2156 LiveRange* current = live_ranges()->at(i); |
| 2189 if (current != NULL) current->Verify(); | 2157 if (current != NULL) current->Verify(); |
| 2190 } | 2158 } |
| 2191 } | 2159 } |
| 2192 | 2160 |
| 2193 | 2161 |
| 2194 #endif | 2162 #endif |
| 2195 | 2163 |
| 2196 | 2164 |
| 2165 LAllocatorPhase::~LAllocatorPhase() { |
| 2166 if (ShouldProduceTraceOutput()) { |
| 2167 isolate()->GetHTracer()->TraceLithium(name(), allocator_->chunk()); |
| 2168 isolate()->GetHTracer()->TraceLiveRanges(name(), allocator_); |
| 2169 } |
| 2170 |
| 2171 #ifdef DEBUG |
| 2172 if (allocator_ != NULL) allocator_->Verify(); |
| 2173 #endif |
| 2174 } |
| 2175 |
| 2176 |
| 2197 } } // namespace v8::internal | 2177 } } // namespace v8::internal |
| OLD | NEW |