summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/register_allocator.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2015-03-27 10:22:41 +0000
committerNicolas Geoffray <ngeoffray@google.com>2015-03-31 20:40:19 +0100
commitd8126bef62df7f40f2e6abc74004f52e664daf45 (patch)
tree8e3d3eee847f8376541ddabc5274bd84bd13311d /compiler/optimizing/register_allocator.cc
parentef3456f872539df65c4c88ca346713f74366d803 (diff)
downloadart-d8126bef62df7f40f2e6abc74004f52e664daf45.tar.gz
art-d8126bef62df7f40f2e6abc74004f52e664daf45.tar.bz2
art-d8126bef62df7f40f2e6abc74004f52e664daf45.zip
Fix locations at environment uses.
We were too agressive in not recording environment uses when the instruction was not of type object. We have to record the use to the use list of an interval, but it should not affect the live ranges of that interval. Change-Id: Id16fb7cc06f14083766d408a345837793583b6ea
Diffstat (limited to 'compiler/optimizing/register_allocator.cc')
-rw-r--r--compiler/optimizing/register_allocator.cc54
1 files changed, 36 insertions, 18 deletions
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index cf38bd3f8c..aa1584a4cc 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -1408,26 +1408,36 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) {
// Walk over all uses covered by this interval, and update the location
// information.
- while (use != nullptr && use->GetPosition() <= current->GetEnd()) {
- LocationSummary* locations = use->GetUser()->GetLocations();
- if (use->GetIsEnvironment()) {
- locations->SetEnvironmentAt(use->GetInputIndex(), source);
- } else {
- Location expected_location = locations->InAt(use->GetInputIndex());
- // The expected (actual) location may be invalid in case the input is unused. Currently
- // this only happens for intrinsics.
- if (expected_location.IsValid()) {
- if (expected_location.IsUnallocated()) {
- locations->SetInAt(use->GetInputIndex(), source);
- } else if (!expected_location.IsConstant()) {
- AddInputMoveFor(interval->GetDefinedBy(), use->GetUser(), source, expected_location);
- }
+
+ LiveRange* range = current->GetFirstRange();
+ while (range != nullptr) {
+ while (use != nullptr && use->GetPosition() < range->GetStart()) {
+ DCHECK(use->GetIsEnvironment());
+ use = use->GetNext();
+ }
+ while (use != nullptr && use->GetPosition() <= range->GetEnd()) {
+ DCHECK(current->Covers(use->GetPosition()) || (use->GetPosition() == range->GetEnd()));
+ LocationSummary* locations = use->GetUser()->GetLocations();
+ if (use->GetIsEnvironment()) {
+ locations->SetEnvironmentAt(use->GetInputIndex(), source);
} else {
- DCHECK(use->GetUser()->IsInvoke());
- DCHECK(use->GetUser()->AsInvoke()->GetIntrinsic() != Intrinsics::kNone);
+ Location expected_location = locations->InAt(use->GetInputIndex());
+ // The expected (actual) location may be invalid in case the input is unused. Currently
+ // this only happens for intrinsics.
+ if (expected_location.IsValid()) {
+ if (expected_location.IsUnallocated()) {
+ locations->SetInAt(use->GetInputIndex(), source);
+ } else if (!expected_location.IsConstant()) {
+ AddInputMoveFor(interval->GetDefinedBy(), use->GetUser(), source, expected_location);
+ }
+ } else {
+ DCHECK(use->GetUser()->IsInvoke());
+ DCHECK(use->GetUser()->AsInvoke()->GetIntrinsic() != Intrinsics::kNone);
+ }
}
+ use = use->GetNext();
}
- use = use->GetNext();
+ range = range->GetNext();
}
// If the next interval starts just after this one, and has a register,
@@ -1503,7 +1513,15 @@ void RegisterAllocator::ConnectSiblings(LiveInterval* interval) {
}
current = next_sibling;
} while (current != nullptr);
- DCHECK(use == nullptr);
+
+ if (kIsDebugBuild) {
+ // Following uses can only be environment uses. The location for
+ // these environments will be none.
+ while (use != nullptr) {
+ DCHECK(use->GetIsEnvironment());
+ use = use->GetNext();
+ }
+ }
}
void RegisterAllocator::ConnectSplitSiblings(LiveInterval* interval,