blob: 9d45e5b19261c39f5492687aa828588b3a63054c [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005#include "src/compiler/simplified-operator-reducer.h"
6
7#include "src/compiler/access-builder.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/js-graph.h"
9#include "src/compiler/machine-operator.h"
10#include "src/compiler/node-matchers.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040011#include "src/compiler/node-properties-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012
13namespace v8 {
14namespace internal {
15namespace compiler {
16
Emily Bernierd0a1eb72015-03-24 16:35:39 -040017SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
18 : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
19
20
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
22
23
24Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
25 switch (node->opcode()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040026 case IrOpcode::kAnyToBoolean:
27 return ReduceAnyToBoolean(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028 case IrOpcode::kBooleanNot: {
29 HeapObjectMatcher<HeapObject> m(node->InputAt(0));
30 if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
31 return Replace(jsgraph()->TrueConstant());
32 }
33 if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->true_value()))) {
34 return Replace(jsgraph()->FalseConstant());
35 }
36 if (m.IsBooleanNot()) return Replace(m.node()->InputAt(0));
37 break;
38 }
39 case IrOpcode::kChangeBitToBool: {
40 Int32Matcher m(node->InputAt(0));
41 if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
42 if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
43 if (m.IsChangeBoolToBit()) return Replace(m.node()->InputAt(0));
44 break;
45 }
46 case IrOpcode::kChangeBoolToBit: {
47 HeapObjectMatcher<HeapObject> m(node->InputAt(0));
48 if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
49 return ReplaceInt32(0);
50 }
51 if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->true_value()))) {
52 return ReplaceInt32(1);
53 }
54 if (m.IsChangeBitToBool()) return Replace(m.node()->InputAt(0));
55 break;
56 }
57 case IrOpcode::kChangeFloat64ToTagged: {
58 Float64Matcher m(node->InputAt(0));
59 if (m.HasValue()) return ReplaceNumber(m.Value());
60 break;
61 }
62 case IrOpcode::kChangeInt32ToTagged: {
63 Int32Matcher m(node->InputAt(0));
64 if (m.HasValue()) return ReplaceNumber(m.Value());
65 break;
66 }
67 case IrOpcode::kChangeTaggedToFloat64: {
68 NumberMatcher m(node->InputAt(0));
69 if (m.HasValue()) return ReplaceFloat64(m.Value());
70 if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
71 if (m.IsChangeInt32ToTagged()) {
72 return Change(node, machine()->ChangeInt32ToFloat64(),
73 m.node()->InputAt(0));
74 }
75 if (m.IsChangeUint32ToTagged()) {
76 return Change(node, machine()->ChangeUint32ToFloat64(),
77 m.node()->InputAt(0));
78 }
79 break;
80 }
81 case IrOpcode::kChangeTaggedToInt32: {
82 NumberMatcher m(node->InputAt(0));
83 if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
84 if (m.IsChangeFloat64ToTagged()) {
85 return Change(node, machine()->ChangeFloat64ToInt32(),
86 m.node()->InputAt(0));
87 }
88 if (m.IsChangeInt32ToTagged()) return Replace(m.node()->InputAt(0));
89 break;
90 }
91 case IrOpcode::kChangeTaggedToUint32: {
92 NumberMatcher m(node->InputAt(0));
93 if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
94 if (m.IsChangeFloat64ToTagged()) {
95 return Change(node, machine()->ChangeFloat64ToUint32(),
96 m.node()->InputAt(0));
97 }
98 if (m.IsChangeUint32ToTagged()) return Replace(m.node()->InputAt(0));
99 break;
100 }
101 case IrOpcode::kChangeUint32ToTagged: {
102 Uint32Matcher m(node->InputAt(0));
103 if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
104 break;
105 }
106 default:
107 break;
108 }
109 return NoChange();
110}
111
112
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) {
114 Node* const input = NodeProperties::GetValueInput(node, 0);
115 Type* const input_type = NodeProperties::GetBounds(input).upper;
116 if (input_type->Is(Type::Boolean())) {
117 // AnyToBoolean(x:boolean) => x
118 return Replace(input);
119 }
120 if (input_type->Is(Type::OrderedNumber())) {
121 // AnyToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
122 Node* compare = graph()->NewNode(simplified()->NumberEqual(), input,
123 jsgraph()->ZeroConstant());
124 return Change(node, simplified()->BooleanNot(), compare);
125 }
126 if (input_type->Is(Type::String())) {
127 // AnyToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
128 FieldAccess const access = AccessBuilder::ForStringLength();
129 Node* length = graph()->NewNode(simplified()->LoadField(access), input,
130 graph()->start(), graph()->start());
131 Node* compare = graph()->NewNode(simplified()->NumberEqual(), length,
132 jsgraph()->ZeroConstant());
133 return Change(node, simplified()->BooleanNot(), compare);
134 }
135 return NoChange();
136}
137
138
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
140 Node* a) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400141 DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
142 DCHECK_LE(1, node->InputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000143 node->set_op(op);
144 node->ReplaceInput(0, a);
145 return Changed(node);
146}
147
148
149Reduction SimplifiedOperatorReducer::ReplaceFloat64(double value) {
150 return Replace(jsgraph()->Float64Constant(value));
151}
152
153
154Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
155 return Replace(jsgraph()->Int32Constant(value));
156}
157
158
159Reduction SimplifiedOperatorReducer::ReplaceNumber(double value) {
160 return Replace(jsgraph()->Constant(value));
161}
162
163
164Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
165 return Replace(jsgraph()->Constant(value));
166}
167
168
169Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
170
171
172Factory* SimplifiedOperatorReducer::factory() const {
173 return jsgraph()->isolate()->factory();
174}
175
176
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400177CommonOperatorBuilder* SimplifiedOperatorReducer::common() const {
178 return jsgraph()->common();
179}
180
181
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
183 return jsgraph()->machine();
184}
185
186} // namespace compiler
187} // namespace internal
188} // namespace v8