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

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

Issue 601103004: Keep list of uses sorted when building it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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 | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.h" 10 #include "vm/flow_graph.h"
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 // Process initial definitions, ie, constants and incoming parameters. 257 // Process initial definitions, ie, constants and incoming parameters.
258 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); i++) { 258 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); i++) {
259 Definition* def = (*graph_entry_->initial_definitions())[i]; 259 Definition* def = (*graph_entry_->initial_definitions())[i];
260 const intptr_t vreg = def->ssa_temp_index(); 260 const intptr_t vreg = def->ssa_temp_index();
261 kill_[graph_entry_->postorder_number()]->Add(vreg); 261 kill_[graph_entry_->postorder_number()]->Add(vreg);
262 live_in_[graph_entry_->postorder_number()]->Remove(vreg); 262 live_in_[graph_entry_->postorder_number()]->Remove(vreg);
263 } 263 }
264 } 264 }
265 265
266 266
267 void LiveRange::AddUse(intptr_t pos, Location* location_slot) { 267 UsePosition* LiveRange::AddUse(intptr_t pos, Location* location_slot) {
srdjan 2014/09/25 16:32:43 Who is using result of LiveRange::AddUse?
268 ASSERT(location_slot != NULL); 268 ASSERT(location_slot != NULL);
269 ASSERT((first_use_interval_->start_ <= pos) && 269 ASSERT((first_use_interval_->start_ <= pos) &&
270 (pos <= first_use_interval_->end_)); 270 (pos <= first_use_interval_->end_));
271 if ((uses_ != NULL) && 271 if (uses_ != NULL) {
272 (uses_->pos() == pos) && 272 if ((uses_->pos() == pos) &&
273 (uses_->location_slot() == location_slot)) { 273 (uses_->location_slot() == location_slot)) {
274 return; 274 return uses_;
275 } else if (uses_->pos() < pos) {
276 // If an instruction at position P is using the same value both as
277 // a fixed register input and a non-fixed input (in this order) we will
278 // add uses both at position P-1 and *then* P which will make
279 // uses_ unsorted unless we account for it here.
280 UsePosition* insert_after = uses_;
281 while ((insert_after->next() != NULL) &&
282 (insert_after->next()->pos() < pos)) {
283 insert_after = insert_after->next();
284 }
285
286 UsePosition* insert_before = insert_after->next();
287 while (insert_before != NULL && (insert_before->pos() == pos)) {
288 if (insert_before->location_slot() == location_slot) {
289 return insert_before;
290 }
291 insert_before = insert_before->next();
292 }
293
294 insert_after->set_next(
295 new UsePosition(pos, insert_after->next(), location_slot));
296 return insert_after->next();
297 }
275 } 298 }
276 uses_ = new UsePosition(pos, uses_, location_slot); 299 uses_ = new UsePosition(pos, uses_, location_slot);
300 return uses_;
277 } 301 }
278 302
279 303
280 void LiveRange::AddSafepoint(intptr_t pos, LocationSummary* locs) { 304 void LiveRange::AddSafepoint(intptr_t pos, LocationSummary* locs) {
281 ASSERT(IsInstructionStartPosition(pos)); 305 ASSERT(IsInstructionStartPosition(pos));
282 SafepointPosition* safepoint = 306 SafepointPosition* safepoint =
283 new SafepointPosition(ToInstructionEnd(pos), locs); 307 new SafepointPosition(ToInstructionEnd(pos), locs);
284 308
285 if (first_safepoint_ == NULL) { 309 if (first_safepoint_ == NULL) {
286 ASSERT(last_safepoint_ == NULL); 310 ASSERT(last_safepoint_ == NULL);
287 first_safepoint_ = last_safepoint_ = safepoint; 311 first_safepoint_ = last_safepoint_ = safepoint;
288 } else { 312 } else {
289 ASSERT(last_safepoint_ != NULL); 313 ASSERT(last_safepoint_ != NULL);
290 // We assume that safepoints list is sorted by position and that 314 // We assume that safepoints list is sorted by position and that
291 // safepoints are added in this order. 315 // safepoints are added in this order.
292 ASSERT(last_safepoint_->pos() < pos); 316 ASSERT(last_safepoint_->pos() < pos);
293 last_safepoint_->set_next(safepoint); 317 last_safepoint_->set_next(safepoint);
294 last_safepoint_ = safepoint; 318 last_safepoint_ = safepoint;
295 } 319 }
296 } 320 }
297 321
298 322
299 void LiveRange::AddHintedUse(intptr_t pos, 323 void LiveRange::AddHintedUse(intptr_t pos,
300 Location* location_slot, 324 Location* location_slot,
301 Location* hint) { 325 Location* hint) {
302 ASSERT(hint != NULL); 326 ASSERT(hint != NULL);
303 AddUse(pos, location_slot); 327 AddUse(pos, location_slot)->set_hint(hint);
304 uses_->set_hint(hint);
305 } 328 }
306 329
307 330
308 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) { 331 void LiveRange::AddUseInterval(intptr_t start, intptr_t end) {
309 ASSERT(start < end); 332 ASSERT(start < end);
310 333
311 // Live ranges are being build by visiting instructions in post-order. 334 // Live ranges are being build by visiting instructions in post-order.
312 // This implies that use intervals will be prepended in a monotonically 335 // This implies that use intervals will be prepended in a monotonically
313 // decreasing order. 336 // decreasing order.
314 if (first_use_interval() != NULL) { 337 if (first_use_interval() != NULL) {
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 ASSERT(input != NULL); 1115 ASSERT(input != NULL);
1093 // Output register will contain a value of the first input at instruction's 1116 // Output register will contain a value of the first input at instruction's
1094 // start. Expected shape of live ranges: 1117 // start. Expected shape of live ranges:
1095 // 1118 //
1096 // i i' 1119 // i i'
1097 // input #0 --* 1120 // input #0 --*
1098 // output [---- 1121 // output [----
1099 // 1122 //
1100 ASSERT(in_ref->Equals(Location::RequiresRegister()) || 1123 ASSERT(in_ref->Equals(Location::RequiresRegister()) ||
1101 in_ref->Equals(Location::RequiresFpuRegister())); 1124 in_ref->Equals(Location::RequiresFpuRegister()));
1102
1103 // TODO(johnmccutchan): Without this I get allocated a register instead
1104 // of an FPU register. Figure out why.
1105
1106 *out = *in_ref; 1125 *out = *in_ref;
1107 // Create move that will copy value between input and output. 1126 // Create move that will copy value between input and output.
1108 MoveOperands* move = AddMoveAt(pos, 1127 MoveOperands* move = AddMoveAt(pos,
1109 Location::RequiresRegister(), 1128 Location::RequiresRegister(),
1110 Location::Any()); 1129 Location::Any());
1111 1130
1112 // Add uses to the live range of the input. 1131 // Add uses to the live range of the input.
1113 LiveRange* input_range = GetLiveRange(input_vreg); 1132 LiveRange* input_range = GetLiveRange(input_vreg);
1114 input_range->AddUseInterval(block->start_pos(), pos); 1133 input_range->AddUseInterval(block->start_pos(), pos);
1115 input_range->AddUse(pos, move->src_slot()); 1134 input_range->AddUse(pos, move->src_slot());
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 first_register_use_ = range->first_use(); 1583 first_register_use_ = range->first_use();
1565 first_register_beneficial_use_ = range->first_use(); 1584 first_register_beneficial_use_ = range->first_use();
1566 first_hinted_use_ = range->first_use(); 1585 first_hinted_use_ = range->first_use();
1567 } 1586 }
1568 1587
1569 1588
1570 bool AllocationFinger::Advance(const intptr_t start) { 1589 bool AllocationFinger::Advance(const intptr_t start) {
1571 UseInterval* a = first_pending_use_interval_; 1590 UseInterval* a = first_pending_use_interval_;
1572 while (a != NULL && a->end() <= start) a = a->next(); 1591 while (a != NULL && a->end() <= start) a = a->next();
1573 first_pending_use_interval_ = a; 1592 first_pending_use_interval_ = a;
1574 if (first_pending_use_interval_ == NULL) { 1593 return (first_pending_use_interval_ == NULL);
1575 return true;
1576 }
1577 return false;
1578 } 1594 }
1579 1595
1580 1596
1581 Location AllocationFinger::FirstHint() { 1597 Location AllocationFinger::FirstHint() {
1582 UsePosition* use = first_hinted_use_; 1598 UsePosition* use = first_hinted_use_;
1583 1599
1584 while (use != NULL) { 1600 while (use != NULL) {
1585 if (use->HasHint()) return use->hint(); 1601 if (use->HasHint()) return use->hint();
1586 use = use->next(); 1602 use = use->next();
1587 } 1603 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1670 a = a->next(); 1686 a = a->next();
1671 } else { 1687 } else {
1672 u = u->next(); 1688 u = u->next();
1673 } 1689 }
1674 } 1690 }
1675 1691
1676 return kMaxPosition; 1692 return kMaxPosition;
1677 } 1693 }
1678 1694
1679 1695
1680 LiveRange* LiveRange::MakeTemp(intptr_t pos, Location* location_slot) {
1681 UNREACHABLE();
1682 return NULL;
1683 }
1684
1685
1686 template<typename PositionType> 1696 template<typename PositionType>
1687 PositionType* SplitListOfPositions(PositionType** head, 1697 PositionType* SplitListOfPositions(PositionType** head,
1688 intptr_t split_pos, 1698 intptr_t split_pos,
1689 bool split_at_start) { 1699 bool split_at_start) {
1690 PositionType* last_before_split = NULL; 1700 PositionType* last_before_split = NULL;
1691 PositionType* pos = *head; 1701 PositionType* pos = *head;
1692 if (split_at_start) { 1702 if (split_at_start) {
1693 while ((pos != NULL) && (pos->pos() < split_pos)) { 1703 while ((pos != NULL) && (pos->pos() < split_pos)) {
1694 last_before_split = pos; 1704 last_before_split = pos;
1695 pos = pos->next(); 1705 pos = pos->next();
(...skipping 1249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2955 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2946 function.ToFullyQualifiedCString()); 2956 function.ToFullyQualifiedCString());
2947 FlowGraphPrinter printer(flow_graph_, true); 2957 FlowGraphPrinter printer(flow_graph_, true);
2948 printer.PrintBlocks(); 2958 printer.PrintBlocks();
2949 OS::Print("----------------------------------------------\n"); 2959 OS::Print("----------------------------------------------\n");
2950 } 2960 }
2951 } 2961 }
2952 2962
2953 2963
2954 } // namespace dart 2964 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698