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

Side by Side Diff: runtime/vm/flow_graph_allocator.cc

Issue 10806099: Some cleanups. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 Instruction* FlowGraphAllocator::InstructionAt(intptr_t pos) const { 853 Instruction* FlowGraphAllocator::InstructionAt(intptr_t pos) const {
854 return instructions_[pos / 2]; 854 return instructions_[pos / 2];
855 } 855 }
856 856
857 857
858 bool FlowGraphAllocator::IsBlockEntry(intptr_t pos) const { 858 bool FlowGraphAllocator::IsBlockEntry(intptr_t pos) const {
859 return InstructionAt(pos)->IsBlockEntry(); 859 return InstructionAt(pos)->IsBlockEntry();
860 } 860 }
861 861
862 862
863 static UsePosition* FirstUseAfter(UsePosition* use, intptr_t after) { 863 void AllocationFinger::Initialize(LiveRange* range) {
864 while ((use != NULL) && (use->pos() < after)) { 864 first_pending_use_interval_ = range->first_use_interval();
865 use = use->next(); 865 first_register_use_ = range->first_use();
866 } 866 first_register_beneficial_use_ = range->first_use();
867 return use; 867 first_hinted_use_ = range->first_use();
868 } 868 }
869 869
870 870
871 bool AllocationFinger::Advance(const intptr_t start) {
872 UseInterval* a = first_pending_use_interval_;
873 while (a != NULL && a->end() <= start) a = a->next();
874 first_pending_use_interval_ = a;
875 if (first_pending_use_interval_ == NULL) {
876 return true;
877 }
878 return false;
879 }
880
881
871 Location AllocationFinger::FirstHint() { 882 Location AllocationFinger::FirstHint() {
872 UsePosition* use = first_hinted_use_; 883 UsePosition* use = first_hinted_use_;
873 884
874 while (use != NULL) { 885 while (use != NULL) {
875 if (use->HasHint()) return use->hint(); 886 if (use->HasHint()) return use->hint();
876 use = use->next(); 887 use = use->next();
877 } 888 }
878 889
879 return Location::NoLocation(); 890 return Location::NoLocation();
880 } 891 }
881 892
882 893
894 static UsePosition* FirstUseAfter(UsePosition* use, intptr_t after) {
895 while ((use != NULL) && (use->pos() < after)) {
896 use = use->next();
897 }
898 return use;
899 }
900
901
883 UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) { 902 UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) {
884 for (UsePosition* use = FirstUseAfter(first_register_use_, after); 903 for (UsePosition* use = FirstUseAfter(first_register_use_, after);
885 use != NULL; 904 use != NULL;
886 use = use->next()) { 905 use = use->next()) {
887 Location* loc = use->location_slot(); 906 Location* loc = use->location_slot();
888 if ((loc != NULL) && 907 if ((loc != NULL) &&
889 loc->IsUnallocated() && 908 loc->IsUnallocated() &&
890 (loc->policy() == Location::kRequiresRegister)) { 909 (loc->policy() == Location::kRequiresRegister)) {
891 first_register_use_ = use; 910 first_register_use_ = use;
892 return use; 911 return use;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1180
1162 cpu_regs_[candidate].Add(unallocated); 1181 cpu_regs_[candidate].Add(unallocated);
1163 unallocated->set_assigned_location(Location::RegisterLocation(candidate)); 1182 unallocated->set_assigned_location(Location::RegisterLocation(candidate));
1164 1183
1165 return true; 1184 return true;
1166 } 1185 }
1167 1186
1168 1187
1169 void FlowGraphAllocator::AllocateAnyRegister(LiveRange* unallocated) { 1188 void FlowGraphAllocator::AllocateAnyRegister(LiveRange* unallocated) {
1170 UsePosition* register_use = 1189 UsePosition* register_use =
1171 unallocated->finger()->FirstRegisterUse(unallocated->Start()); 1190 unallocated->finger()->FirstRegisterUse(unallocated->Start());
1172 if (register_use == NULL) { 1191 if (register_use == NULL) {
1173 Spill(unallocated); 1192 Spill(unallocated);
1174 return; 1193 return;
1175 } 1194 }
1176 1195
1177 Register candidate = kNoRegister; 1196 Register candidate = kNoRegister;
1178 intptr_t free_until = 0; 1197 intptr_t free_until = 0;
1179 intptr_t blocked_at = kMaxPosition; 1198 intptr_t blocked_at = kMaxPosition;
1180 1199
1181 for (int reg = 0; reg < kNumberOfCpuRegisters; ++reg) { 1200 for (int reg = 0; reg < kNumberOfCpuRegisters; ++reg) {
(...skipping 29 matching lines...) Expand all
1211 intptr_t* cur_free_until, 1230 intptr_t* cur_free_until,
1212 intptr_t* cur_blocked_at) { 1231 intptr_t* cur_blocked_at) {
1213 intptr_t free_until = kMaxPosition; 1232 intptr_t free_until = kMaxPosition;
1214 intptr_t blocked_at = kMaxPosition; 1233 intptr_t blocked_at = kMaxPosition;
1215 const intptr_t start = unallocated->Start(); 1234 const intptr_t start = unallocated->Start();
1216 1235
1217 for (intptr_t i = 0; i < cpu_regs_[reg].length(); i++) { 1236 for (intptr_t i = 0; i < cpu_regs_[reg].length(); i++) {
1218 LiveRange* allocated = cpu_regs_[reg][i]; 1237 LiveRange* allocated = cpu_regs_[reg][i];
1219 1238
1220 UseInterval* first_pending_use_interval = 1239 UseInterval* first_pending_use_interval =
1221 allocated->finger()->first_pending_use_interval(); 1240 allocated->finger()->first_pending_use_interval();
1222 if (first_pending_use_interval->Contains(start)) { 1241 if (first_pending_use_interval->Contains(start)) {
1223 // This is an active interval. 1242 // This is an active interval.
1224 if (allocated->vreg() <= 0) { 1243 if (allocated->vreg() <= 0) {
1225 // This register blocked by an interval that 1244 // This register blocked by an interval that
1226 // can't be spilled. 1245 // can't be spilled.
1227 return false; 1246 return false;
1228 } 1247 }
1229 1248
1230 const UsePosition* use = 1249 const UsePosition* use =
1231 allocated->finger()->FirstRegisterBeneficialUse(unallocated->Start()); 1250 allocated->finger()->FirstRegisterBeneficialUse(unallocated->Start());
1232 1251
1233 if ((use != NULL) && ((use->pos() - start) <= 1)) { 1252 if ((use != NULL) && ((use->pos() - start) <= 1)) {
1234 // This register is blocked by interval that is used 1253 // This register is blocked by interval that is used
1235 // as register in the current instruction and can't 1254 // as register in the current instruction and can't
1236 // be spilled. 1255 // be spilled.
1237 return false; 1256 return false;
1238 } 1257 }
1239 1258
1240 const intptr_t use_pos = (use != NULL) ? use->pos() 1259 const intptr_t use_pos = (use != NULL) ? use->pos()
1241 : allocated->End(); 1260 : allocated->End();
1242 1261
1243 if (use_pos < free_until) free_until = use_pos; 1262 if (use_pos < free_until) free_until = use_pos;
1244 } else { 1263 } else {
1245 // This is inactive interval. 1264 // This is inactive interval.
1246 const intptr_t intersection = FirstIntersection( 1265 const intptr_t intersection = FirstIntersection(
1247 first_pending_use_interval, unallocated->first_use_interval()); 1266 first_pending_use_interval, unallocated->first_use_interval());
1248 if (intersection != kMaxPosition) { 1267 if (intersection != kMaxPosition) {
1249 if (intersection < free_until) free_until = intersection; 1268 if (intersection < free_until) free_until = intersection;
1250 if (allocated->vreg() == kNoVirtualRegister) blocked_at = intersection; 1269 if (allocated->vreg() == kNoVirtualRegister) blocked_at = intersection;
1251 } 1270 }
1252 } 1271 }
1253 1272
1254 if (free_until <= *cur_free_until) { 1273 if (free_until <= *cur_free_until) {
1255 return false; 1274 return false;
1256 } 1275 }
1257 } 1276 }
(...skipping 19 matching lines...) Expand all
1277 void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated, 1296 void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated,
1278 Register reg) { 1297 Register reg) {
1279 TRACE_ALLOC(("assigning blocked register %s to live range %d\n", 1298 TRACE_ALLOC(("assigning blocked register %s to live range %d\n",
1280 Location::RegisterLocation(reg).Name(), 1299 Location::RegisterLocation(reg).Name(),
1281 unallocated->vreg())); 1300 unallocated->vreg()));
1282 1301
1283 intptr_t first_evicted = -1; 1302 intptr_t first_evicted = -1;
1284 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) { 1303 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) {
1285 LiveRange* allocated = cpu_regs_[reg][i]; 1304 LiveRange* allocated = cpu_regs_[reg][i];
1286 if (allocated->vreg() < 0) continue; // Can't be evicted. 1305 if (allocated->vreg() < 0) continue; // Can't be evicted.
1287 if (EvictIntersection(allocated, 1306 if (EvictIntersection(allocated, unallocated)) {
1288 unallocated)) {
1289 cpu_regs_[reg][i] = NULL; 1307 cpu_regs_[reg][i] = NULL;
1290 first_evicted = i; 1308 first_evicted = i;
1291 } 1309 }
1292 } 1310 }
1293 1311
1294 // Remove evicted ranges from the array. 1312 // Remove evicted ranges from the array.
1295 if (first_evicted != -1) RemoveEvicted(reg, first_evicted); 1313 if (first_evicted != -1) RemoveEvicted(reg, first_evicted);
1296 1314
1297 cpu_regs_[reg].Add(unallocated); 1315 cpu_regs_[reg].Add(unallocated);
1298 unallocated->set_assigned_location(Location::RegisterLocation(reg)); 1316 unallocated->set_assigned_location(Location::RegisterLocation(reg));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 range->vreg(), 1373 range->vreg(),
1356 range->assigned_location().Name())); 1374 range->assigned_location().Name()));
1357 ASSERT(!range->assigned_location().IsInvalid()); 1375 ASSERT(!range->assigned_location().IsInvalid());
1358 const Location loc = range->assigned_location(); 1376 const Location loc = range->assigned_location();
1359 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { 1377 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) {
1360 ConvertUseTo(use, loc); 1378 ConvertUseTo(use, loc);
1361 } 1379 }
1362 } 1380 }
1363 1381
1364 1382
1365 bool AllocationFinger::Advance(const intptr_t start) {
1366 UseInterval* a = first_pending_use_interval_;
1367 while (a != NULL && a->end() <= start) a = a->next();
1368 first_pending_use_interval_ = a;
1369 if (first_pending_use_interval_ == NULL) {
1370 return true;
1371 }
1372 return false;
1373 }
1374
1375
1376 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { 1383 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) {
1377 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { 1384 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
1378 if (cpu_regs_[reg].is_empty()) continue; 1385 if (cpu_regs_[reg].is_empty()) continue;
1379 1386
1380 intptr_t first_evicted = -1; 1387 intptr_t first_evicted = -1;
1381 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) { 1388 for (intptr_t i = cpu_regs_[reg].length() - 1; i >= 0; i--) {
1382 LiveRange* range = cpu_regs_[reg][i]; 1389 LiveRange* range = cpu_regs_[reg][i];
1383 if (range->finger()->Advance(start)) { 1390 if (range->finger()->Advance(start)) {
1384 ConvertAllUses(range); 1391 ConvertAllUses(range);
1385 cpu_regs_[reg][i] = NULL; 1392 cpu_regs_[reg][i] = NULL;
1386 first_evicted = i; 1393 first_evicted = i;
1387 } 1394 }
1388 } 1395 }
1389 1396
1390 if (first_evicted != -1) { 1397 if (first_evicted != -1) {
1391 RemoveEvicted(static_cast<Register>(reg), first_evicted); 1398 RemoveEvicted(static_cast<Register>(reg), first_evicted);
1392 } 1399 }
1393 } 1400 }
1394 } 1401 }
1395 1402
1396 1403
1397 void AllocationFinger::Initialize(LiveRange* range) {
1398 first_pending_use_interval_ = range->first_use_interval();
1399 first_register_use_ = range->first_use();
1400 first_register_beneficial_use_ = range->first_use();
1401 first_hinted_use_ = range->first_use();
1402 }
1403
1404
1405 static inline bool ShouldBeAllocatedBefore(LiveRange* a, LiveRange* b) { 1404 static inline bool ShouldBeAllocatedBefore(LiveRange* a, LiveRange* b) {
1406 return a->Start() <= b->Start(); 1405 return a->Start() <= b->Start();
1407 } 1406 }
1408 1407
1409 1408
1410 void FlowGraphAllocator::AddToUnallocated(LiveRange* range) { 1409 void FlowGraphAllocator::AddToUnallocated(LiveRange* range) {
1411 range->finger()->Initialize(range); 1410 range->finger()->Initialize(range);
1412 1411
1413 if (unallocated_.is_empty()) { 1412 if (unallocated_.is_empty()) {
1414 unallocated_.Add(range); 1413 unallocated_.Add(range);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 1594
1596 if (FLAG_trace_ssa_allocator) { 1595 if (FLAG_trace_ssa_allocator) {
1597 OS::Print("-- ir after allocation -------------------------\n"); 1596 OS::Print("-- ir after allocation -------------------------\n");
1598 FlowGraphPrinter printer(Function::Handle(), block_order_, true); 1597 FlowGraphPrinter printer(Function::Handle(), block_order_, true);
1599 printer.PrintBlocks(); 1598 printer.PrintBlocks();
1600 } 1599 }
1601 } 1600 }
1602 1601
1603 1602
1604 } // namespace dart 1603 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698