Chromium Code Reviews| 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/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
| 7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
| 8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1215 | 1215 |
| 1216 while (interval != nullptr) { | 1216 while (interval != nullptr) { |
| 1217 os << '[' << interval->start() << ", " << interval->end() << ')' | 1217 os << '[' << interval->start() << ", " << interval->end() << ')' |
| 1218 << std::endl; | 1218 << std::endl; |
| 1219 interval = interval->next(); | 1219 interval = interval->next(); |
| 1220 } | 1220 } |
| 1221 os << "}"; | 1221 os << "}"; |
| 1222 return os; | 1222 return os; |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 | |
| 1226 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) | 1225 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) |
| 1227 : live_ranges_(zone), | 1226 : live_ranges_(zone), |
| 1228 assigned_slot_(kUnassignedSlot), | 1227 assigned_slot_(kUnassignedSlot), |
| 1229 byte_width_(GetByteWidth(parent->representation())), | 1228 representation_(parent->representation()), |
| 1230 kind_(parent->kind()) { | 1229 byte_width_(GetByteWidth(parent->representation())) { |
| 1231 // Spill ranges are created for top level, non-splintered ranges. This is so | 1230 // Spill ranges are created for top level, non-splintered ranges. This is so |
| 1232 // that, when merging decisions are made, we consider the full extent of the | 1231 // that, when merging decisions are made, we consider the full extent of the |
| 1233 // virtual register, and avoid clobbering it. | 1232 // virtual register, and avoid clobbering it. |
| 1234 DCHECK(!parent->IsSplinter()); | 1233 DCHECK(!parent->IsSplinter()); |
| 1235 UseInterval* result = nullptr; | 1234 UseInterval* result = nullptr; |
| 1236 UseInterval* node = nullptr; | 1235 UseInterval* node = nullptr; |
| 1237 // Copy the intervals for all ranges. | 1236 // Copy the intervals for all ranges. |
| 1238 for (LiveRange* range = parent; range != nullptr; range = range->next()) { | 1237 for (LiveRange* range = parent; range != nullptr; range = range->next()) { |
| 1239 UseInterval* src = range->first_interval(); | 1238 UseInterval* src = range->first_interval(); |
| 1240 while (src != nullptr) { | 1239 while (src != nullptr) { |
| 1241 UseInterval* new_node = new (zone) UseInterval(src->start(), src->end()); | 1240 UseInterval* new_node = new (zone) UseInterval(src->start(), src->end()); |
| 1242 if (result == nullptr) { | 1241 if (result == nullptr) { |
| 1243 result = new_node; | 1242 result = new_node; |
| 1244 } else { | 1243 } else { |
| 1245 node->set_next(new_node); | 1244 node->set_next(new_node); |
| 1246 } | 1245 } |
| 1247 node = new_node; | 1246 node = new_node; |
| 1248 src = src->next(); | 1247 src = src->next(); |
| 1249 } | 1248 } |
| 1250 } | 1249 } |
| 1251 use_interval_ = result; | 1250 use_interval_ = result; |
| 1252 live_ranges().push_back(parent); | 1251 live_ranges().push_back(parent); |
| 1253 end_position_ = node->end(); | 1252 end_position_ = node->end(); |
| 1254 parent->SetSpillRange(this); | 1253 parent->SetSpillRange(this); |
| 1255 } | 1254 } |
| 1256 | 1255 |
| 1257 | |
| 1258 int SpillRange::ByteWidth() const { | |
| 1259 return GetByteWidth(live_ranges_[0]->representation()); | |
| 1260 } | |
| 1261 | |
| 1262 | |
| 1263 bool SpillRange::IsIntersectingWith(SpillRange* other) const { | 1256 bool SpillRange::IsIntersectingWith(SpillRange* other) const { |
| 1264 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || | 1257 if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || |
| 1265 this->End() <= other->use_interval_->start() || | 1258 this->End() <= other->use_interval_->start() || |
| 1266 other->End() <= this->use_interval_->start()) { | 1259 other->End() <= this->use_interval_->start()) { |
| 1267 return false; | 1260 return false; |
| 1268 } | 1261 } |
| 1269 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); | 1262 return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); |
| 1270 } | 1263 } |
| 1271 | 1264 |
| 1272 | 1265 |
| 1273 bool SpillRange::TryMerge(SpillRange* other) { | 1266 bool SpillRange::TryMerge(SpillRange* other) { |
| 1274 if (HasSlot() || other->HasSlot()) return false; | 1267 if (HasSlot() || other->HasSlot()) return false; |
| 1275 // TODO(dcarney): byte widths should be compared here not kinds. | 1268 if (live_ranges_[0]->representation() != |
| 1276 if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() || | 1269 other->live_ranges_[0]->representation() || |
|
bbudge
2016/06/18 23:33:22
It occurs to me that this will now prevent non-FP
| |
| 1277 IsIntersectingWith(other)) { | 1270 IsIntersectingWith(other)) { |
| 1278 return false; | 1271 return false; |
| 1279 } | 1272 } |
| 1280 | 1273 |
| 1281 LifetimePosition max = LifetimePosition::MaxPosition(); | 1274 LifetimePosition max = LifetimePosition::MaxPosition(); |
| 1282 if (End() < other->End() && other->End() != max) { | 1275 if (End() < other->End() && other->End() != max) { |
| 1283 end_position_ = other->End(); | 1276 end_position_ = other->End(); |
| 1284 } | 1277 } |
| 1285 other->end_position_ = max; | 1278 other->end_position_ = max; |
| 1286 | 1279 |
| (...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3160 if (other != nullptr && !other->IsEmpty()) { | 3153 if (other != nullptr && !other->IsEmpty()) { |
| 3161 range->TryMerge(other); | 3154 range->TryMerge(other); |
| 3162 } | 3155 } |
| 3163 } | 3156 } |
| 3164 } | 3157 } |
| 3165 // Allocate slots for the merged spill ranges. | 3158 // Allocate slots for the merged spill ranges. |
| 3166 for (SpillRange* range : spill_ranges) { | 3159 for (SpillRange* range : spill_ranges) { |
| 3167 if (range == nullptr || range->IsEmpty()) continue; | 3160 if (range == nullptr || range->IsEmpty()) continue; |
| 3168 // Allocate a new operand referring to the spill slot. | 3161 // Allocate a new operand referring to the spill slot. |
| 3169 if (!range->HasSlot()) { | 3162 if (!range->HasSlot()) { |
| 3170 int byte_width = range->ByteWidth(); | 3163 int byte_width = range->byte_width(); |
| 3171 int index = data()->frame()->AllocateSpillSlot(byte_width); | 3164 int index = data()->frame()->AllocateSpillSlot(byte_width); |
| 3172 range->set_assigned_slot(index); | 3165 range->set_assigned_slot(index); |
| 3173 } | 3166 } |
| 3174 } | 3167 } |
| 3175 } | 3168 } |
| 3176 | 3169 |
| 3177 | 3170 |
| 3178 void OperandAssigner::CommitAssignment() { | 3171 void OperandAssigner::CommitAssignment() { |
| 3179 for (TopLevelLiveRange* top_range : data()->live_ranges()) { | 3172 for (TopLevelLiveRange* top_range : data()->live_ranges()) { |
| 3180 if (top_range == nullptr || top_range->IsEmpty()) continue; | 3173 if (top_range == nullptr || top_range->IsEmpty()) continue; |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3632 } | 3625 } |
| 3633 } | 3626 } |
| 3634 } | 3627 } |
| 3635 } | 3628 } |
| 3636 } | 3629 } |
| 3637 | 3630 |
| 3638 | 3631 |
| 3639 } // namespace compiler | 3632 } // namespace compiler |
| 3640 } // namespace internal | 3633 } // namespace internal |
| 3641 } // namespace v8 | 3634 } // namespace v8 |
| OLD | NEW |