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

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 2280673003: [turbofan] Separate typed optimizations from JSTypedLowering. (Closed)
Patch Set: Created 4 years, 3 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/js-typed-lowering.h" 5 #include "src/compiler/js-typed-lowering.h"
6 6
7 #include "src/builtins/builtins-utils.h" 7 #include "src/builtins/builtins-utils.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // - relax effects from generic but not-side-effecting operations 423 // - relax effects from generic but not-side-effecting operations
424 424
425 425
426 JSTypedLowering::JSTypedLowering(Editor* editor, 426 JSTypedLowering::JSTypedLowering(Editor* editor,
427 CompilationDependencies* dependencies, 427 CompilationDependencies* dependencies,
428 Flags flags, JSGraph* jsgraph, Zone* zone) 428 Flags flags, JSGraph* jsgraph, Zone* zone)
429 : AdvancedReducer(editor), 429 : AdvancedReducer(editor),
430 dependencies_(dependencies), 430 dependencies_(dependencies),
431 flags_(flags), 431 flags_(flags),
432 jsgraph_(jsgraph), 432 jsgraph_(jsgraph),
433 true_type_(Type::Constant(factory()->true_value(), graph()->zone())),
434 false_type_(Type::Constant(factory()->false_value(), graph()->zone())),
435 the_hole_type_( 433 the_hole_type_(
436 Type::Constant(factory()->the_hole_value(), graph()->zone())), 434 Type::Constant(factory()->the_hole_value(), graph()->zone())),
437 type_cache_(TypeCache::Get()) { 435 type_cache_(TypeCache::Get()) {
438 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { 436 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) {
439 double min = kMinInt / (1 << k); 437 double min = kMinInt / (1 << k);
440 double max = kMaxInt / (1 << k); 438 double max = kMaxInt / (1 << k);
441 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); 439 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
442 } 440 }
443 } 441 }
444 442
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1920 Node* element = effect = graph()->NewNode( 1918 Node* element = effect = graph()->NewNode(
1921 simplified()->LoadField(element_field), array, effect, control); 1919 simplified()->LoadField(element_field), array, effect, control);
1922 Node* stale = jsgraph()->StaleRegisterConstant(); 1920 Node* stale = jsgraph()->StaleRegisterConstant();
1923 effect = graph()->NewNode(simplified()->StoreField(element_field), array, 1921 effect = graph()->NewNode(simplified()->StoreField(element_field), array,
1924 stale, effect, control); 1922 stale, effect, control);
1925 1923
1926 ReplaceWithValue(node, element, effect, control); 1924 ReplaceWithValue(node, element, effect, control);
1927 return Changed(element); 1925 return Changed(element);
1928 } 1926 }
1929 1927
1930 Reduction JSTypedLowering::ReducePhi(Node* node) {
1931 // Try to narrow the type of the Phi {node}, which might be more precise now
1932 // after lowering based on types, i.e. a SpeculativeNumberAdd has a more
1933 // precise type than the JSAdd that was in the graph when the Typer was run.
1934 DCHECK_EQ(IrOpcode::kPhi, node->opcode());
1935 int arity = node->op()->ValueInputCount();
1936 Type* type = NodeProperties::GetType(node->InputAt(0));
1937 for (int i = 1; i < arity; ++i) {
1938 type = Type::Union(type, NodeProperties::GetType(node->InputAt(i)),
1939 graph()->zone());
1940 }
1941 Type* const node_type = NodeProperties::GetType(node);
1942 if (!node_type->Is(type)) {
1943 type = Type::Intersect(node_type, type, graph()->zone());
1944 NodeProperties::SetType(node, type);
1945 return Changed(node);
1946 }
1947 return NoChange();
1948 }
1949
1950 Reduction JSTypedLowering::ReduceSelect(Node* node) {
1951 DCHECK_EQ(IrOpcode::kSelect, node->opcode());
1952 Node* const condition = NodeProperties::GetValueInput(node, 0);
1953 Type* const condition_type = NodeProperties::GetType(condition);
1954 Node* const vtrue = NodeProperties::GetValueInput(node, 1);
1955 Type* const vtrue_type = NodeProperties::GetType(vtrue);
1956 Node* const vfalse = NodeProperties::GetValueInput(node, 2);
1957 Type* const vfalse_type = NodeProperties::GetType(vfalse);
1958 if (condition_type->Is(true_type_)) {
1959 // Select(condition:true, vtrue, vfalse) => vtrue
1960 return Replace(vtrue);
1961 }
1962 if (condition_type->Is(false_type_)) {
1963 // Select(condition:false, vtrue, vfalse) => vfalse
1964 return Replace(vfalse);
1965 }
1966 if (vtrue_type->Is(true_type_) && vfalse_type->Is(false_type_)) {
1967 // Select(condition, vtrue:true, vfalse:false) => condition
1968 return Replace(condition);
1969 }
1970 if (vtrue_type->Is(false_type_) && vfalse_type->Is(true_type_)) {
1971 // Select(condition, vtrue:false, vfalse:true) => BooleanNot(condition)
1972 node->TrimInputCount(1);
1973 NodeProperties::ChangeOp(node, simplified()->BooleanNot());
1974 return Changed(node);
1975 }
1976 return NoChange();
1977 }
1978
1979 namespace {
1980
1981 MaybeHandle<Map> GetStableMapFromObjectType(Type* object_type) {
1982 if (object_type->IsConstant() &&
1983 object_type->AsConstant()->Value()->IsHeapObject()) {
1984 Handle<Map> object_map(
1985 Handle<HeapObject>::cast(object_type->AsConstant()->Value())->map());
1986 if (object_map->is_stable()) return object_map;
1987 } else if (object_type->IsClass()) {
1988 Handle<Map> object_map = object_type->AsClass()->Map();
1989 if (object_map->is_stable()) return object_map;
1990 }
1991 return MaybeHandle<Map>();
1992 }
1993
1994 } // namespace
1995
1996 Reduction JSTypedLowering::ReduceCheckMaps(Node* node) {
1997 // TODO(bmeurer): Find a better home for this thing!
1998 // The CheckMaps(o, ...map...) can be eliminated if map is stable and
1999 // either
2000 // (a) o has type Constant(object) and map == object->map, or
2001 // (b) o has type Class(map),
2002 // and either
2003 // (1) map cannot transition further, or
2004 // (2) we can add a code dependency on the stability of map
2005 // (to guard the Constant type information).
2006 Node* const object = NodeProperties::GetValueInput(node, 0);
2007 Type* const object_type = NodeProperties::GetType(object);
2008 Node* const effect = NodeProperties::GetEffectInput(node);
2009 Handle<Map> object_map;
2010 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) {
2011 for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
2012 Node* const map = NodeProperties::GetValueInput(node, i);
2013 Type* const map_type = NodeProperties::GetType(map);
2014 if (map_type->IsConstant() &&
2015 map_type->AsConstant()->Value().is_identical_to(object_map)) {
2016 if (object_map->CanTransition()) {
2017 DCHECK(flags() & kDeoptimizationEnabled);
2018 dependencies()->AssumeMapStable(object_map);
2019 }
2020 return Replace(effect);
2021 }
2022 }
2023 }
2024 return NoChange();
2025 }
2026
2027 Reduction JSTypedLowering::ReduceCheckString(Node* node) {
2028 // TODO(bmeurer): Find a better home for this thing!
2029 Node* const input = NodeProperties::GetValueInput(node, 0);
2030 Type* const input_type = NodeProperties::GetType(input);
2031 if (input_type->Is(Type::String())) {
2032 ReplaceWithValue(node, input);
2033 return Replace(input);
2034 }
2035 return NoChange();
2036 }
2037
2038 Reduction JSTypedLowering::ReduceLoadField(Node* node) {
2039 // TODO(bmeurer): Find a better home for this thing!
2040 Node* const object = NodeProperties::GetValueInput(node, 0);
2041 Type* const object_type = NodeProperties::GetType(object);
2042 FieldAccess const& access = FieldAccessOf(node->op());
2043 if (access.base_is_tagged == kTaggedBase &&
2044 access.offset == HeapObject::kMapOffset) {
2045 // We can replace LoadField[Map](o) with map if is stable and either
2046 // (a) o has type Constant(object) and map == object->map, or
2047 // (b) o has type Class(map),
2048 // and either
2049 // (1) map cannot transition further, or
2050 // (2) deoptimization is enabled and we can add a code dependency on the
2051 // stability of map (to guard the Constant type information).
2052 Handle<Map> object_map;
2053 if (GetStableMapFromObjectType(object_type).ToHandle(&object_map)) {
2054 if (object_map->CanTransition()) {
2055 if (flags() & kDeoptimizationEnabled) {
2056 dependencies()->AssumeMapStable(object_map);
2057 } else {
2058 return NoChange();
2059 }
2060 }
2061 Node* const value = jsgraph()->HeapConstant(object_map);
2062 ReplaceWithValue(node, value);
2063 return Replace(value);
2064 }
2065 }
2066 return NoChange();
2067 }
2068
2069 Reduction JSTypedLowering::ReduceNumberRoundop(Node* node) {
2070 // TODO(bmeurer): Find a better home for this thing!
2071 Node* const input = NodeProperties::GetValueInput(node, 0);
2072 Type* const input_type = NodeProperties::GetType(input);
2073 if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
2074 return Replace(input);
2075 }
2076 return NoChange();
2077 }
2078
2079 Reduction JSTypedLowering::Reduce(Node* node) { 1928 Reduction JSTypedLowering::Reduce(Node* node) {
2080 // Check if the output type is a singleton. In that case we already know the
2081 // result value and can simply replace the node if it's eliminable.
2082 if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
2083 node->op()->HasProperty(Operator::kEliminatable)) {
2084 // We can only constant-fold nodes here, that are known to not cause any
2085 // side-effect, may it be a JavaScript observable side-effect or a possible
2086 // eager deoptimization exit (i.e. {node} has an operator that doesn't have
2087 // the Operator::kNoDeopt property).
2088 Type* upper = NodeProperties::GetType(node);
2089 if (upper->IsInhabited()) {
2090 if (upper->IsConstant()) {
2091 Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
2092 ReplaceWithValue(node, replacement);
2093 return Changed(replacement);
2094 } else if (upper->Is(Type::MinusZero())) {
2095 Node* replacement = jsgraph()->Constant(factory()->minus_zero_value());
2096 ReplaceWithValue(node, replacement);
2097 return Changed(replacement);
2098 } else if (upper->Is(Type::NaN())) {
2099 Node* replacement = jsgraph()->NaNConstant();
2100 ReplaceWithValue(node, replacement);
2101 return Changed(replacement);
2102 } else if (upper->Is(Type::Null())) {
2103 Node* replacement = jsgraph()->NullConstant();
2104 ReplaceWithValue(node, replacement);
2105 return Changed(replacement);
2106 } else if (upper->Is(Type::PlainNumber()) &&
2107 upper->Min() == upper->Max()) {
2108 Node* replacement = jsgraph()->Constant(upper->Min());
2109 ReplaceWithValue(node, replacement);
2110 return Changed(replacement);
2111 } else if (upper->Is(Type::Undefined())) {
2112 Node* replacement = jsgraph()->UndefinedConstant();
2113 ReplaceWithValue(node, replacement);
2114 return Changed(replacement);
2115 }
2116 }
2117 }
2118 switch (node->opcode()) { 1929 switch (node->opcode()) {
2119 case IrOpcode::kJSEqual: 1930 case IrOpcode::kJSEqual:
2120 return ReduceJSEqual(node, false); 1931 return ReduceJSEqual(node, false);
2121 case IrOpcode::kJSNotEqual: 1932 case IrOpcode::kJSNotEqual:
2122 return ReduceJSEqual(node, true); 1933 return ReduceJSEqual(node, true);
2123 case IrOpcode::kJSStrictEqual: 1934 case IrOpcode::kJSStrictEqual:
2124 return ReduceJSStrictEqual(node, false); 1935 return ReduceJSStrictEqual(node, false);
2125 case IrOpcode::kJSStrictNotEqual: 1936 case IrOpcode::kJSStrictNotEqual:
2126 return ReduceJSStrictEqual(node, true); 1937 return ReduceJSStrictEqual(node, true);
2127 case IrOpcode::kJSLessThan: // fall through 1938 case IrOpcode::kJSLessThan: // fall through
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 case IrOpcode::kJSForInNext: 1991 case IrOpcode::kJSForInNext:
2181 return ReduceJSForInNext(node); 1992 return ReduceJSForInNext(node);
2182 case IrOpcode::kJSForInStep: 1993 case IrOpcode::kJSForInStep:
2183 return ReduceJSForInStep(node); 1994 return ReduceJSForInStep(node);
2184 case IrOpcode::kJSGeneratorStore: 1995 case IrOpcode::kJSGeneratorStore:
2185 return ReduceJSGeneratorStore(node); 1996 return ReduceJSGeneratorStore(node);
2186 case IrOpcode::kJSGeneratorRestoreContinuation: 1997 case IrOpcode::kJSGeneratorRestoreContinuation:
2187 return ReduceJSGeneratorRestoreContinuation(node); 1998 return ReduceJSGeneratorRestoreContinuation(node);
2188 case IrOpcode::kJSGeneratorRestoreRegister: 1999 case IrOpcode::kJSGeneratorRestoreRegister:
2189 return ReduceJSGeneratorRestoreRegister(node); 2000 return ReduceJSGeneratorRestoreRegister(node);
2190 case IrOpcode::kPhi:
2191 return ReducePhi(node);
2192 case IrOpcode::kSelect:
2193 return ReduceSelect(node);
2194 case IrOpcode::kCheckMaps:
2195 return ReduceCheckMaps(node);
2196 case IrOpcode::kCheckString:
2197 return ReduceCheckString(node);
2198 case IrOpcode::kNumberCeil:
2199 case IrOpcode::kNumberFloor:
2200 case IrOpcode::kNumberRound:
2201 case IrOpcode::kNumberTrunc:
2202 return ReduceNumberRoundop(node);
2203 case IrOpcode::kLoadField:
2204 return ReduceLoadField(node);
2205 default: 2001 default:
2206 break; 2002 break;
2207 } 2003 }
2208 return NoChange(); 2004 return NoChange();
2209 } 2005 }
2210 2006
2211 2007
2212 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } 2008 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
2213 2009
2214 2010
(...skipping 21 matching lines...) Expand all
2236 } 2032 }
2237 2033
2238 2034
2239 CompilationDependencies* JSTypedLowering::dependencies() const { 2035 CompilationDependencies* JSTypedLowering::dependencies() const {
2240 return dependencies_; 2036 return dependencies_;
2241 } 2037 }
2242 2038
2243 } // namespace compiler 2039 } // namespace compiler
2244 } // namespace internal 2040 } // namespace internal
2245 } // namespace v8 2041 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698