OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |