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

Side by Side Diff: src/lithium-allocator.cc

Issue 12867002: Fixed two register allocator bugs (off-by-one error/failure propagation). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed MIPS Created 7 years, 9 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 | « src/lithium-allocator.h ('k') | src/mips/lithium-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 LUnallocated* input_copy = cur_input->CopyUnconstrained(zone()); 832 LUnallocated* input_copy = cur_input->CopyUnconstrained(zone());
833 bool is_tagged = HasTaggedValue(cur_input->virtual_register()); 833 bool is_tagged = HasTaggedValue(cur_input->virtual_register());
834 AllocateFixed(cur_input, gap_index + 1, is_tagged); 834 AllocateFixed(cur_input, gap_index + 1, is_tagged);
835 AddConstraintsGapMove(gap_index, input_copy, cur_input); 835 AddConstraintsGapMove(gap_index, input_copy, cur_input);
836 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) { 836 } else if (cur_input->policy() == LUnallocated::WRITABLE_REGISTER) {
837 // The live range of writable input registers always goes until the end 837 // The live range of writable input registers always goes until the end
838 // of the instruction. 838 // of the instruction.
839 ASSERT(!cur_input->IsUsedAtStart()); 839 ASSERT(!cur_input->IsUsedAtStart());
840 840
841 LUnallocated* input_copy = cur_input->CopyUnconstrained(zone()); 841 LUnallocated* input_copy = cur_input->CopyUnconstrained(zone());
842 cur_input->set_virtual_register(GetVirtualRegister()); 842 int vreg = GetVirtualRegister();
843 if (!AllocationOk()) return; 843 if (!AllocationOk()) return;
844 cur_input->set_virtual_register(vreg);
844 845
845 if (RequiredRegisterKind(input_copy->virtual_register()) == 846 if (RequiredRegisterKind(input_copy->virtual_register()) ==
846 DOUBLE_REGISTERS) { 847 DOUBLE_REGISTERS) {
847 double_artificial_registers_.Add( 848 double_artificial_registers_.Add(
848 cur_input->virtual_register() - first_artificial_register_, 849 cur_input->virtual_register() - first_artificial_register_,
849 zone_); 850 zone_);
850 } 851 }
851 852
852 AddConstraintsGapMove(gap_index, input_copy, cur_input); 853 AddConstraintsGapMove(gap_index, input_copy, cur_input);
853 } 854 }
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after
1917 SpillBetween(current, current->Start(), register_use->pos()); 1918 SpillBetween(current, current->Start(), register_use->pos());
1918 return; 1919 return;
1919 } 1920 }
1920 1921
1921 if (block_pos[reg].Value() < current->End().Value()) { 1922 if (block_pos[reg].Value() < current->End().Value()) {
1922 // Register becomes blocked before the current range end. Split before that 1923 // Register becomes blocked before the current range end. Split before that
1923 // position. 1924 // position.
1924 LiveRange* tail = SplitBetween(current, 1925 LiveRange* tail = SplitBetween(current,
1925 current->Start(), 1926 current->Start(),
1926 block_pos[reg].InstructionStart()); 1927 block_pos[reg].InstructionStart());
1928 if (!AllocationOk()) return;
1927 AddToUnhandledSorted(tail); 1929 AddToUnhandledSorted(tail);
1928 } 1930 }
1929 1931
1930 // Register reg is not blocked for the whole range. 1932 // Register reg is not blocked for the whole range.
1931 ASSERT(block_pos[reg].Value() >= current->End().Value()); 1933 ASSERT(block_pos[reg].Value() >= current->End().Value());
1932 TraceAlloc("Assigning blocked reg %s to live range %d\n", 1934 TraceAlloc("Assigning blocked reg %s to live range %d\n",
1933 RegisterName(reg), 1935 RegisterName(reg),
1934 current->id()); 1936 current->id());
1935 SetLiveRangeAssignedRegister(current, reg, mode_, zone_); 1937 SetLiveRangeAssignedRegister(current, reg, mode_, zone_);
1936 1938
(...skipping 10 matching lines...) Expand all
1947 LifetimePosition split_pos = current->Start(); 1949 LifetimePosition split_pos = current->Start();
1948 for (int i = 0; i < active_live_ranges_.length(); ++i) { 1950 for (int i = 0; i < active_live_ranges_.length(); ++i) {
1949 LiveRange* range = active_live_ranges_[i]; 1951 LiveRange* range = active_live_ranges_[i];
1950 if (range->assigned_register() == reg) { 1952 if (range->assigned_register() == reg) {
1951 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 1953 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
1952 if (next_pos == NULL) { 1954 if (next_pos == NULL) {
1953 SpillAfter(range, split_pos); 1955 SpillAfter(range, split_pos);
1954 } else { 1956 } else {
1955 SpillBetween(range, split_pos, next_pos->pos()); 1957 SpillBetween(range, split_pos, next_pos->pos());
1956 } 1958 }
1959 if (!AllocationOk()) return;
1957 ActiveToHandled(range); 1960 ActiveToHandled(range);
1958 --i; 1961 --i;
1959 } 1962 }
1960 } 1963 }
1961 1964
1962 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { 1965 for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
1963 LiveRange* range = inactive_live_ranges_[i]; 1966 LiveRange* range = inactive_live_ranges_[i];
1964 ASSERT(range->End().Value() > current->Start().Value()); 1967 ASSERT(range->End().Value() > current->Start().Value());
1965 if (range->assigned_register() == reg && !range->IsFixed()) { 1968 if (range->assigned_register() == reg && !range->IsFixed()) {
1966 LifetimePosition next_intersection = range->FirstIntersection(current); 1969 LifetimePosition next_intersection = range->FirstIntersection(current);
1967 if (next_intersection.IsValid()) { 1970 if (next_intersection.IsValid()) {
1968 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 1971 UsePosition* next_pos = range->NextRegisterPosition(current->Start());
1969 if (next_pos == NULL) { 1972 if (next_pos == NULL) {
1970 SpillAfter(range, split_pos); 1973 SpillAfter(range, split_pos);
1971 } else { 1974 } else {
1972 next_intersection = Min(next_intersection, next_pos->pos()); 1975 next_intersection = Min(next_intersection, next_pos->pos());
1973 SpillBetween(range, split_pos, next_intersection); 1976 SpillBetween(range, split_pos, next_intersection);
1974 } 1977 }
1978 if (!AllocationOk()) return;
1975 InactiveToHandled(range); 1979 InactiveToHandled(range);
1976 --i; 1980 --i;
1977 } 1981 }
1978 } 1982 }
1979 } 1983 }
1980 } 1984 }
1981 1985
1982 1986
1983 bool LAllocator::IsBlockBoundary(LifetimePosition pos) { 1987 bool LAllocator::IsBlockBoundary(LifetimePosition pos) {
1984 return pos.IsInstructionStart() && 1988 return pos.IsInstructionStart() &&
1985 InstructionAt(pos.InstructionIndex())->IsLabel(); 1989 InstructionAt(pos.InstructionIndex())->IsLabel();
1986 } 1990 }
1987 1991
1988 1992
1989 LiveRange* LAllocator::SplitRangeAt(LiveRange* range, LifetimePosition pos) { 1993 LiveRange* LAllocator::SplitRangeAt(LiveRange* range, LifetimePosition pos) {
1990 ASSERT(!range->IsFixed()); 1994 ASSERT(!range->IsFixed());
1991 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 1995 TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
1992 1996
1993 if (pos.Value() <= range->Start().Value()) return range; 1997 if (pos.Value() <= range->Start().Value()) return range;
1994 1998
1995 // We can't properly connect liveranges if split occured at the end 1999 // We can't properly connect liveranges if split occured at the end
1996 // of control instruction. 2000 // of control instruction.
1997 ASSERT(pos.IsInstructionStart() || 2001 ASSERT(pos.IsInstructionStart() ||
1998 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl()); 2002 !chunk_->instructions()->at(pos.InstructionIndex())->IsControl());
1999 2003
2000 LiveRange* result = LiveRangeFor(GetVirtualRegister()); 2004 int vreg = GetVirtualRegister();
2001 if (!AllocationOk()) return NULL; 2005 if (!AllocationOk()) return NULL;
2006 LiveRange* result = LiveRangeFor(vreg);
2002 range->SplitAt(pos, result, zone_); 2007 range->SplitAt(pos, result, zone_);
2003 return result; 2008 return result;
2004 } 2009 }
2005 2010
2006 2011
2007 LiveRange* LAllocator::SplitBetween(LiveRange* range, 2012 LiveRange* LAllocator::SplitBetween(LiveRange* range,
2008 LifetimePosition start, 2013 LifetimePosition start,
2009 LifetimePosition end) { 2014 LifetimePosition end) {
2010 ASSERT(!range->IsFixed()); 2015 ASSERT(!range->IsFixed());
2011 TraceAlloc("Splitting live range %d in position between [%d, %d]\n", 2016 TraceAlloc("Splitting live range %d in position between [%d, %d]\n",
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2068 if (!AllocationOk()) return; 2073 if (!AllocationOk()) return;
2069 2074
2070 if (second_part->Start().Value() < end.Value()) { 2075 if (second_part->Start().Value() < end.Value()) {
2071 // The split result intersects with [start, end[. 2076 // The split result intersects with [start, end[.
2072 // Split it at position between ]start+1, end[, spill the middle part 2077 // Split it at position between ]start+1, end[, spill the middle part
2073 // and put the rest to unhandled. 2078 // and put the rest to unhandled.
2074 LiveRange* third_part = SplitBetween( 2079 LiveRange* third_part = SplitBetween(
2075 second_part, 2080 second_part,
2076 second_part->Start().InstructionEnd(), 2081 second_part->Start().InstructionEnd(),
2077 end.PrevInstruction().InstructionEnd()); 2082 end.PrevInstruction().InstructionEnd());
2083 if (!AllocationOk()) return;
2078 2084
2079 ASSERT(third_part != second_part); 2085 ASSERT(third_part != second_part);
2080 2086
2081 Spill(second_part); 2087 Spill(second_part);
2082 AddToUnhandledSorted(third_part); 2088 AddToUnhandledSorted(third_part);
2083 } else { 2089 } else {
2084 // The split result does not intersect with [start, end[. 2090 // The split result does not intersect with [start, end[.
2085 // Nothing to spill. Just put it to unhandled as whole. 2091 // Nothing to spill. Just put it to unhandled as whole.
2086 AddToUnhandledSorted(second_part); 2092 AddToUnhandledSorted(second_part);
2087 } 2093 }
(...skipping 27 matching lines...) Expand all
2115 LiveRange* current = live_ranges()->at(i); 2121 LiveRange* current = live_ranges()->at(i);
2116 if (current != NULL) current->Verify(); 2122 if (current != NULL) current->Verify();
2117 } 2123 }
2118 } 2124 }
2119 2125
2120 2126
2121 #endif 2127 #endif
2122 2128
2123 2129
2124 } } // namespace v8::internal 2130 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lithium-allocator.h ('k') | src/mips/lithium-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698