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 1930 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 if (instr->CheckFlag(HValue::kUseGVN)) { | 1941 if (instr->CheckFlag(HValue::kUseGVN)) { |
1942 TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n", | 1942 TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n", |
1943 instr->id(), | 1943 instr->id(), |
1944 instr->Mnemonic(), | 1944 instr->Mnemonic(), |
1945 *GetGVNFlagsString(instr->gvn_flags()), | 1945 *GetGVNFlagsString(instr->gvn_flags()), |
1946 *GetGVNFlagsString(loop_kills)); | 1946 *GetGVNFlagsString(loop_kills)); |
1947 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); | 1947 bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags); |
1948 if (can_hoist && !graph()->use_optimistic_licm()) { | 1948 if (can_hoist && !graph()->use_optimistic_licm()) { |
1949 can_hoist = block->IsLoopSuccessorDominator(); | 1949 can_hoist = block->IsLoopSuccessorDominator(); |
1950 } | 1950 } |
1951 if (instr->IsTransitionElementsKind()) { | |
1952 // It's possible to hoist transitions out of a loop as long as the | |
1953 // hoisting wouldn't move the transition past an instruction that has a | |
1954 // DependsOn flag for anything it changes. | |
1955 GVNFlagSet hoist_depends_blockers = | |
1956 HValue::ConvertChangesToDependsFlags(instr->ChangesFlags()); | |
1957 | |
1958 // In addition, the transition must not be hoisted above elements kind | |
1959 // changes, or if the transition is destructive to the elements buffer, | |
1960 // changes to array pointer or array contents. | |
1961 GVNFlagSet hoist_change_blockers; | |
1962 hoist_change_blockers.Add(kChangesElementsKind); | |
1963 HTransitionElementsKind* trans = HTransitionElementsKind::cast(instr); | |
1964 if (trans->original_map()->has_fast_double_elements()) { | |
1965 hoist_change_blockers.Add(kChangesElementsPointer); | |
1966 hoist_change_blockers.Add(kChangesDoubleArrayElements); | |
1967 } | |
1968 if (trans->transitioned_map()->has_fast_double_elements()) { | |
1969 hoist_change_blockers.Add(kChangesElementsPointer); | |
1970 hoist_change_blockers.Add(kChangesArrayElements); | |
1971 } | |
1972 if (FLAG_trace_gvn) { | |
1973 GVNFlagSet hoist_blockers = hoist_depends_blockers; | |
1974 hoist_blockers.Add(hoist_change_blockers); | |
1975 GVNFlagSet first_time = *first_time_changes; | |
1976 first_time.Add(*first_time_depends); | |
1977 TRACE_GVN_4("Checking dependencies on HTransitionElementsKind " | |
1978 "%d (%s) hoist blockers: %s; " | |
1979 "first-time accumulated: %s\n", | |
1980 instr->id(), | |
1981 instr->Mnemonic(), | |
1982 *GetGVNFlagsString(hoist_blockers), | |
1983 *GetGVNFlagsString(first_time)); | |
1984 } | |
1985 // It's possible to hoist transition from the current loop loop only if | |
1986 // they dominate all of the successor blocks in the same loop and there | |
1987 // are not any instructions that have Changes/DependsOn that intervene | |
1988 // between it and the beginning of the loop header. | |
1989 bool in_nested_loop = block != loop_header && | |
1990 ((block->parent_loop_header() != loop_header) || | |
1991 block->IsLoopHeader()); | |
1992 can_hoist = !in_nested_loop && | |
1993 block->IsLoopSuccessorDominator() && | |
1994 !first_time_depends->ContainsAnyOf(hoist_depends_blockers) && | |
1995 !first_time_changes->ContainsAnyOf(hoist_change_blockers); | |
1996 } | |
1997 | 1951 |
1998 if (can_hoist) { | 1952 if (can_hoist) { |
1999 bool inputs_loop_invariant = true; | 1953 bool inputs_loop_invariant = true; |
2000 for (int i = 0; i < instr->OperandCount(); ++i) { | 1954 for (int i = 0; i < instr->OperandCount(); ++i) { |
2001 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { | 1955 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { |
2002 inputs_loop_invariant = false; | 1956 inputs_loop_invariant = false; |
2003 } | 1957 } |
2004 } | 1958 } |
2005 | 1959 |
2006 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { | 1960 if (inputs_loop_invariant && ShouldMove(instr, loop_header)) { |
(...skipping 7976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9983 } | 9937 } |
9984 } | 9938 } |
9985 | 9939 |
9986 #ifdef DEBUG | 9940 #ifdef DEBUG |
9987 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9941 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9988 if (allocator_ != NULL) allocator_->Verify(); | 9942 if (allocator_ != NULL) allocator_->Verify(); |
9989 #endif | 9943 #endif |
9990 } | 9944 } |
9991 | 9945 |
9992 } } // namespace v8::internal | 9946 } } // namespace v8::internal |
OLD | NEW |