| 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 |