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

Side by Side Diff: src/lithium-allocator.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months 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 | Annotate | Revision Log
« no previous file with comments | « src/lithium-allocator.h ('k') | src/liveedit.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/lithium-allocator.h ('k') | src/liveedit.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698