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 |