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

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

Issue 795833006: Revert of [turbofan] Improve typed lowering of JSBitwiseAnd. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | test/unittests/compiler/js-typed-lowering-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/access-builder.h" 5 #include "src/compiler/access-builder.h"
6 #include "src/compiler/graph-inl.h" 6 #include "src/compiler/graph-inl.h"
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-typed-lowering.h" 8 #include "src/compiler/js-typed-lowering.h"
9 #include "src/compiler/node-aux-data-inl.h" 9 #include "src/compiler/node-aux-data-inl.h"
10 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/node-matchers.h"
(...skipping 15 matching lines...) Expand all
26 // TODO(titzer): move into a GraphEditor? 26 // TODO(titzer): move into a GraphEditor?
27 static void RelaxEffects(Node* node) { 27 static void RelaxEffects(Node* node) {
28 NodeProperties::ReplaceWithValue(node, node, NULL); 28 NodeProperties::ReplaceWithValue(node, node, NULL);
29 } 29 }
30 30
31 31
32 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone) 32 JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone)
33 : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) { 33 : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) {
34 Handle<Object> zero = factory()->NewNumber(0.0); 34 Handle<Object> zero = factory()->NewNumber(0.0);
35 Handle<Object> one = factory()->NewNumber(1.0); 35 Handle<Object> one = factory()->NewNumber(1.0);
36 zero_range_ = Type::Range(zero, zero, zone); 36 zero_range_ = Type::Range(zero, zero, graph()->zone());
37 one_range_ = Type::Range(one, one, zone); 37 one_range_ = Type::Range(one, one, graph()->zone());
38 zero_one_range_ = Type::Range(zero, one, zone);
39 Handle<Object> thirtyone = factory()->NewNumber(31.0); 38 Handle<Object> thirtyone = factory()->NewNumber(31.0);
40 zero_thirtyone_range_ = Type::Range(zero, thirtyone, zone); 39 zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone());
41 // TODO(jarin): Can we have a correctification of the stupid type system? 40 // TODO(jarin): Can we have a correctification of the stupid type system?
42 // These stupid work-arounds are just stupid! 41 // These stupid work-arounds are just stupid!
43 shifted_int32_ranges_[0] = Type::Signed32(); 42 shifted_int32_ranges_[0] = Type::Signed32();
44 if (SmiValuesAre31Bits()) { 43 if (SmiValuesAre31Bits()) {
45 shifted_int32_ranges_[1] = Type::SignedSmall(); 44 shifted_int32_ranges_[1] = Type::SignedSmall();
46 for (size_t k = 2; k < arraysize(shifted_int32_ranges_); ++k) { 45 for (size_t k = 2; k < arraysize(shifted_int32_ranges_); ++k) {
47 Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k)); 46 Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
48 Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k)); 47 Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
49 shifted_int32_ranges_[k] = Type::Range(min, max, zone); 48 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
50 } 49 }
51 } else { 50 } else {
52 for (size_t k = 1; k < arraysize(shifted_int32_ranges_); ++k) { 51 for (size_t k = 1; k < arraysize(shifted_int32_ranges_); ++k) {
53 Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k)); 52 Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
54 Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k)); 53 Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
55 shifted_int32_ranges_[k] = Type::Range(min, max, zone); 54 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
56 } 55 }
57 } 56 }
58 } 57 }
59 58
60 59
61 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { 60 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) {
62 NodeProperties::ReplaceWithValue(old, node, node); 61 NodeProperties::ReplaceWithValue(old, node, node);
63 return Changed(node); 62 return Changed(node);
64 } 63 }
65 64
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 } 104 }
106 105
107 void SwapInputs() { 106 void SwapInputs() {
108 Node* l = left(); 107 Node* l = left();
109 Node* r = right(); 108 Node* r = right();
110 node_->ReplaceInput(0, r); 109 node_->ReplaceInput(0, r);
111 node_->ReplaceInput(1, l); 110 node_->ReplaceInput(1, l);
112 std::swap(left_type_, right_type_); 111 std::swap(left_type_, right_type_);
113 } 112 }
114 113
115 void ReplaceLeftInput(Node* l) {
116 node_->ReplaceInput(0, l);
117 left_type_ = NodeProperties::GetBounds(l).upper;
118 }
119
120 // Remove all effect and control inputs and outputs to this node and change 114 // Remove all effect and control inputs and outputs to this node and change
121 // to the pure operator {op}, possibly inserting a boolean inversion. 115 // to the pure operator {op}, possibly inserting a boolean inversion.
122 Reduction ChangeToPureOperator(const Operator* op, bool invert = false, 116 Reduction ChangeToPureOperator(const Operator* op, bool invert = false,
123 Type* type = Type::Any()) { 117 Type* type = Type::Any()) {
124 DCHECK_EQ(0, op->EffectInputCount()); 118 DCHECK_EQ(0, op->EffectInputCount());
125 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 119 DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
126 DCHECK_EQ(0, op->ControlInputCount()); 120 DCHECK_EQ(0, op->ControlInputCount());
127 DCHECK_LE(1, op->ValueInputCount()); 121 DCHECK_EQ(2, op->ValueInputCount());
128 DCHECK_GE(2, op->ValueInputCount());
129 122
130 // Remove the effects from the node, if any, and update its effect usages. 123 // Remove the effects from the node, if any, and update its effect usages.
131 if (node_->op()->EffectInputCount() > 0) { 124 if (node_->op()->EffectInputCount() > 0) {
132 RelaxEffects(node_); 125 RelaxEffects(node_);
133 } 126 }
127 // Remove the inputs corresponding to context, effect, and control.
128 NodeProperties::RemoveNonValueInputs(node_);
134 // Finally, update the operator to the new one. 129 // Finally, update the operator to the new one.
135 node_->set_op(op); 130 node_->set_op(op);
136 // Remove the inputs corresponding to context, effect, and control.
137 NodeProperties::RemoveNonValueInputs(node_);
138 131
139 // TODO(jarin): Replace the explicit typing hack with a call to some method 132 // TODO(jarin): Replace the explicit typing hack with a call to some method
140 // that encapsulates changing the operator and re-typing. 133 // that encapsulates changing the operator and re-typing.
141 Bounds const bounds = NodeProperties::GetBounds(node_); 134 Bounds const bounds = NodeProperties::GetBounds(node_);
142 NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone())); 135 NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone()));
143 136
144 if (invert) { 137 if (invert) {
145 // Insert an boolean not to invert the value. 138 // Insert an boolean not to invert the value.
146 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); 139 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
147 node_->ReplaceUses(value); 140 node_->ReplaceUses(value);
148 // Note: ReplaceUses() smashes all uses, so smash it back here. 141 // Note: ReplaceUses() smashes all uses, so smash it back here.
149 value->ReplaceInput(0, node_); 142 value->ReplaceInput(0, node_);
150 return lowering_->Replace(value); 143 return lowering_->Replace(value);
151 } 144 }
152 return lowering_->Changed(node_); 145 return lowering_->Changed(node_);
153 } 146 }
154 147
155 Reduction ChangeToPureOperator(const Operator* op, Type* type) { 148 Reduction ChangeToPureOperator(const Operator* op, Type* type) {
156 return ChangeToPureOperator(op, false, type); 149 return ChangeToPureOperator(op, false, type);
157 } 150 }
158 151
159 Reduction ReplaceWithLeftInput() { 152 bool OneInputIs(Type* t) { return left_type_->Is(t) || right_type_->Is(t); }
160 // Remove the effects from the node, if any, and update its effect usages. 153
161 if (node_->op()->EffectInputCount() > 0) { 154 bool BothInputsAre(Type* t) {
162 RelaxEffects(node_); 155 return left_type_->Is(t) && right_type_->Is(t);
163 }
164 return lowering_->Replace(left());
165 } 156 }
166 157
167 bool LeftInputIs(Type* t) { return left_type_->Is(t); }
168 bool RightInputIs(Type* t) { return right_type_->Is(t); }
169 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
170 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
171
172 bool OneInputCannotBe(Type* t) { 158 bool OneInputCannotBe(Type* t) {
173 return !left_type_->Maybe(t) || !right_type_->Maybe(t); 159 return !left_type_->Maybe(t) || !right_type_->Maybe(t);
174 } 160 }
175 161
176 bool NeitherInputCanBe(Type* t) { 162 bool NeitherInputCanBe(Type* t) {
177 return !left_type_->Maybe(t) && !right_type_->Maybe(t); 163 return !left_type_->Maybe(t) && !right_type_->Maybe(t);
178 } 164 }
179 165
180 Node* effect() { return NodeProperties::GetEffectInput(node_); } 166 Node* effect() { return NodeProperties::GetEffectInput(node_); }
181 Node* control() { return NodeProperties::GetControlInput(node_); } 167 Node* control() { return NodeProperties::GetControlInput(node_); }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 // JSAdd(x:string, y:string) => StringAdd(x, y) 257 // JSAdd(x:string, y:string) => StringAdd(x, y)
272 // JSAdd(x:string, y) => StringAdd(x, ToString(y)) 258 // JSAdd(x:string, y) => StringAdd(x, ToString(y))
273 // JSAdd(x, y:string) => StringAdd(ToString(x), y) 259 // JSAdd(x, y:string) => StringAdd(ToString(x), y)
274 r.ConvertInputsToString(); 260 r.ConvertInputsToString();
275 return r.ChangeToPureOperator(simplified()->StringAdd()); 261 return r.ChangeToPureOperator(simplified()->StringAdd());
276 } 262 }
277 #endif 263 #endif
278 return NoChange(); 264 return NoChange();
279 } 265 }
280 266
281
282 Reduction JSTypedLowering::ReduceJSBitwiseAnd(Node* node) {
283 JSBinopReduction r(this, node);
284 if (r.LeftInputIs(one_range_)) {
285 if (r.RightInputIs(zero_one_range_)) {
286 // JSBitwiseAnd(1, x:[0,1]) => x
287 r.SwapInputs();
288 return r.ReplaceWithLeftInput();
289 } else if (r.RightInputIs(Type::Boolean())) {
290 // JSBitwiseAnd(1, x:boolean) => BooleanToNumber(x)
291 r.SwapInputs();
292 return r.ChangeToPureOperator(simplified()->BooleanToNumber());
293 }
294 }
295 if (r.RightInputIs(one_range_)) {
296 if (r.LeftInputIs(zero_one_range_)) {
297 // JSBitwiseAnd(x:[0,1], 1) => x
298 return r.ReplaceWithLeftInput();
299 } else if (r.LeftInputIs(Type::Boolean())) {
300 // JSBitwiseAnd(x:boolean, 1) => BooleanToNumber(x)
301 return r.ChangeToPureOperator(simplified()->BooleanToNumber());
302 }
303 }
304 if (r.BothInputsAre(Type::Primitive())) {
305 // TODO(titzer): some Smi bitwise operations don't really require going
306 // all the way to int32, which can save tagging/untagging for some
307 // operations
308 // on some platforms.
309 // TODO(turbofan): make this heuristic configurable for code size.
310 r.ConvertInputsToUI32(kSigned, kSigned);
311 return r.ChangeToPureOperator(machine()->Word32And(), Type::Integral32());
312 }
313 return NoChange();
314 }
315
316 267
317 Reduction JSTypedLowering::ReduceJSBitwiseOr(Node* node) { 268 Reduction JSTypedLowering::ReduceJSBitwiseOr(Node* node) {
318 JSBinopReduction r(this, node); 269 JSBinopReduction r(this, node);
319 if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(zero_range_)) { 270 if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(zero_range_)) {
320 // TODO(jarin): Propagate frame state input from non-primitive input node to 271 // TODO(jarin): Propagate frame state input from non-primitive input node to
321 // JSToNumber node. 272 // JSToNumber node.
322 // TODO(titzer): some Smi bitwise operations don't really require going 273 // TODO(titzer): some Smi bitwise operations don't really require going
323 // all the way to int32, which can save tagging/untagging for some 274 // all the way to int32, which can save tagging/untagging for some
324 // operations 275 // operations
325 // on some platforms. 276 // on some platforms.
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 case IrOpcode::kJSLessThan: // fall through 880 case IrOpcode::kJSLessThan: // fall through
930 case IrOpcode::kJSGreaterThan: // fall through 881 case IrOpcode::kJSGreaterThan: // fall through
931 case IrOpcode::kJSLessThanOrEqual: // fall through 882 case IrOpcode::kJSLessThanOrEqual: // fall through
932 case IrOpcode::kJSGreaterThanOrEqual: 883 case IrOpcode::kJSGreaterThanOrEqual:
933 return ReduceJSComparison(node); 884 return ReduceJSComparison(node);
934 case IrOpcode::kJSBitwiseOr: 885 case IrOpcode::kJSBitwiseOr:
935 return ReduceJSBitwiseOr(node); 886 return ReduceJSBitwiseOr(node);
936 case IrOpcode::kJSBitwiseXor: 887 case IrOpcode::kJSBitwiseXor:
937 return ReduceInt32Binop(node, machine()->Word32Xor()); 888 return ReduceInt32Binop(node, machine()->Word32Xor());
938 case IrOpcode::kJSBitwiseAnd: 889 case IrOpcode::kJSBitwiseAnd:
939 return ReduceJSBitwiseAnd(node); 890 return ReduceInt32Binop(node, machine()->Word32And());
940 case IrOpcode::kJSShiftLeft: 891 case IrOpcode::kJSShiftLeft:
941 return ReduceUI32Shift(node, kSigned, machine()->Word32Shl()); 892 return ReduceUI32Shift(node, kSigned, machine()->Word32Shl());
942 case IrOpcode::kJSShiftRight: 893 case IrOpcode::kJSShiftRight:
943 return ReduceUI32Shift(node, kSigned, machine()->Word32Sar()); 894 return ReduceUI32Shift(node, kSigned, machine()->Word32Sar());
944 case IrOpcode::kJSShiftRightLogical: 895 case IrOpcode::kJSShiftRightLogical:
945 return ReduceUI32Shift(node, kUnsigned, machine()->Word32Shr()); 896 return ReduceUI32Shift(node, kUnsigned, machine()->Word32Shr());
946 case IrOpcode::kJSAdd: 897 case IrOpcode::kJSAdd:
947 return ReduceJSAdd(node); 898 return ReduceJSAdd(node);
948 case IrOpcode::kJSSubtract: 899 case IrOpcode::kJSSubtract:
949 return ReduceNumberBinop(node, simplified()->NumberSubtract()); 900 return ReduceNumberBinop(node, simplified()->NumberSubtract());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 } 986 }
1036 987
1037 988
1038 MachineOperatorBuilder* JSTypedLowering::machine() const { 989 MachineOperatorBuilder* JSTypedLowering::machine() const {
1039 return jsgraph()->machine(); 990 return jsgraph()->machine();
1040 } 991 }
1041 992
1042 } // namespace compiler 993 } // namespace compiler
1043 } // namespace internal 994 } // namespace internal
1044 } // namespace v8 995 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | test/unittests/compiler/js-typed-lowering-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698