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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( | 189 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( |
190 LifetimePosition start) { | 190 LifetimePosition start) { |
191 UsePosition* pos = NextUsePosition(start); | 191 UsePosition* pos = NextUsePosition(start); |
192 while (pos != NULL && !pos->RegisterIsBeneficial()) { | 192 while (pos != NULL && !pos->RegisterIsBeneficial()) { |
193 pos = pos->next(); | 193 pos = pos->next(); |
194 } | 194 } |
195 return pos; | 195 return pos; |
196 } | 196 } |
197 | 197 |
198 | 198 |
| 199 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( |
| 200 LifetimePosition start) { |
| 201 UsePosition* pos = first_pos(); |
| 202 UsePosition* prev = NULL; |
| 203 while (pos != NULL && pos->pos().Value() < start.Value()) { |
| 204 if (pos->RegisterIsBeneficial()) prev = pos; |
| 205 pos = pos->next(); |
| 206 } |
| 207 return prev; |
| 208 } |
| 209 |
| 210 |
199 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) { | 211 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) { |
200 UsePosition* pos = NextUsePosition(start); | 212 UsePosition* pos = NextUsePosition(start); |
201 while (pos != NULL && !pos->RequiresRegister()) { | 213 while (pos != NULL && !pos->RequiresRegister()) { |
202 pos = pos->next(); | 214 pos = pos->next(); |
203 } | 215 } |
204 return pos; | 216 return pos; |
205 } | 217 } |
206 | 218 |
207 | 219 |
208 bool LiveRange::CanBeSpilled(LifetimePosition pos) { | 220 bool LiveRange::CanBeSpilled(LifetimePosition pos) { |
(...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 current->id()); | 1941 current->id()); |
1930 current->set_assigned_register(reg, mode_, zone_); | 1942 current->set_assigned_register(reg, mode_, zone_); |
1931 | 1943 |
1932 // This register was not free. Thus we need to find and spill | 1944 // This register was not free. Thus we need to find and spill |
1933 // parts of active and inactive live regions that use the same register | 1945 // parts of active and inactive live regions that use the same register |
1934 // at the same lifetime positions as current. | 1946 // at the same lifetime positions as current. |
1935 SplitAndSpillIntersecting(current); | 1947 SplitAndSpillIntersecting(current); |
1936 } | 1948 } |
1937 | 1949 |
1938 | 1950 |
| 1951 LifetimePosition LAllocator::FindOptimalSpillingPos(LiveRange* range, |
| 1952 LifetimePosition pos) { |
| 1953 HBasicBlock* block = GetBlock(pos.InstructionStart()); |
| 1954 HBasicBlock* loop_header = |
| 1955 block->IsLoopHeader() ? block : block->parent_loop_header(); |
| 1956 |
| 1957 if (loop_header == NULL) return pos; |
| 1958 |
| 1959 UsePosition* prev_use = |
| 1960 range->PreviousUsePositionRegisterIsBeneficial(pos); |
| 1961 |
| 1962 while (loop_header != NULL) { |
| 1963 // We are going to spill live range inside the loop. |
| 1964 // If possible try to move spilling position backwards to loop header. |
| 1965 // This will reduce number of memory moves on the back edge. |
| 1966 LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( |
| 1967 loop_header->first_instruction_index()); |
| 1968 |
| 1969 if (range->Covers(loop_start)) { |
| 1970 if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { |
| 1971 // No register beneficial use inside the loop before the pos. |
| 1972 pos = loop_start; |
| 1973 } |
| 1974 } |
| 1975 |
| 1976 // Try hoisting out to an outer loop. |
| 1977 loop_header = loop_header->parent_loop_header(); |
| 1978 } |
| 1979 |
| 1980 return pos; |
| 1981 } |
| 1982 |
| 1983 |
1939 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { | 1984 void LAllocator::SplitAndSpillIntersecting(LiveRange* current) { |
1940 ASSERT(current->HasRegisterAssigned()); | 1985 ASSERT(current->HasRegisterAssigned()); |
1941 int reg = current->assigned_register(); | 1986 int reg = current->assigned_register(); |
1942 LifetimePosition split_pos = current->Start(); | 1987 LifetimePosition split_pos = current->Start(); |
1943 for (int i = 0; i < active_live_ranges_.length(); ++i) { | 1988 for (int i = 0; i < active_live_ranges_.length(); ++i) { |
1944 LiveRange* range = active_live_ranges_[i]; | 1989 LiveRange* range = active_live_ranges_[i]; |
1945 if (range->assigned_register() == reg) { | 1990 if (range->assigned_register() == reg) { |
1946 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); | 1991 UsePosition* next_pos = range->NextRegisterPosition(current->Start()); |
| 1992 LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos); |
1947 if (next_pos == NULL) { | 1993 if (next_pos == NULL) { |
1948 SpillAfter(range, split_pos); | 1994 SpillAfter(range, spill_pos); |
1949 } else { | 1995 } else { |
1950 SpillBetween(range, split_pos, next_pos->pos()); | 1996 SpillBetween(range, spill_pos, next_pos->pos()); |
1951 } | 1997 } |
1952 ActiveToHandled(range); | 1998 ActiveToHandled(range); |
1953 --i; | 1999 --i; |
1954 } | 2000 } |
1955 } | 2001 } |
1956 | 2002 |
1957 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { | 2003 for (int i = 0; i < inactive_live_ranges_.length(); ++i) { |
1958 LiveRange* range = inactive_live_ranges_[i]; | 2004 LiveRange* range = inactive_live_ranges_[i]; |
1959 ASSERT(range->End().Value() > current->Start().Value()); | 2005 ASSERT(range->End().Value() > current->Start().Value()); |
1960 if (range->assigned_register() == reg && !range->IsFixed()) { | 2006 if (range->assigned_register() == reg && !range->IsFixed()) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2110 LiveRange* current = live_ranges()->at(i); | 2156 LiveRange* current = live_ranges()->at(i); |
2111 if (current != NULL) current->Verify(); | 2157 if (current != NULL) current->Verify(); |
2112 } | 2158 } |
2113 } | 2159 } |
2114 | 2160 |
2115 | 2161 |
2116 #endif | 2162 #endif |
2117 | 2163 |
2118 | 2164 |
2119 } } // namespace v8::internal | 2165 } } // namespace v8::internal |
OLD | NEW |