blob: 6fbf16ed791925f0e4bcd8a82de31308c6d880b6 [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
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/compiler/js-graph.h"
8#include "src/compiler/machine-operator.h"
9#include "src/compiler/node-matchers.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/compiler/operator-properties.h"
Ben Murdochc5610432016-08-08 18:44:38 +010011#include "src/compiler/simplified-operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/conversions-inl.h"
Ben Murdochda12d292016-06-02 14:46:10 +010013#include "src/type-cache.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
Ben Murdochda12d292016-06-02 14:46:10 +010020 : jsgraph_(jsgraph), type_cache_(TypeCache::Get()) {}
Emily Bernierd0a1eb72015-03-24 16:35:39 -040021
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
23
24
25Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
26 switch (node->opcode()) {
27 case IrOpcode::kBooleanNot: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028 HeapObjectMatcher m(node->InputAt(0));
29 if (m.HasValue()) {
30 return Replace(jsgraph()->BooleanConstant(!m.Value()->BooleanValue()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032 if (m.IsBooleanNot()) return Replace(m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 break;
34 }
Ben Murdochc5610432016-08-08 18:44:38 +010035 case IrOpcode::kChangeBitToTagged: {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 Int32Matcher m(node->InputAt(0));
37 if (m.Is(0)) return Replace(jsgraph()->FalseConstant());
38 if (m.Is(1)) return Replace(jsgraph()->TrueConstant());
Ben Murdochc5610432016-08-08 18:44:38 +010039 if (m.IsChangeTaggedToBit()) return Replace(m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 break;
41 }
Ben Murdochc5610432016-08-08 18:44:38 +010042 case IrOpcode::kChangeTaggedToBit: {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000043 HeapObjectMatcher m(node->InputAt(0));
44 if (m.HasValue()) return ReplaceInt32(m.Value()->BooleanValue());
Ben Murdochc5610432016-08-08 18:44:38 +010045 if (m.IsChangeBitToTagged()) return Replace(m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046 break;
47 }
48 case IrOpcode::kChangeFloat64ToTagged: {
49 Float64Matcher m(node->InputAt(0));
50 if (m.HasValue()) return ReplaceNumber(m.Value());
Ben Murdochc5610432016-08-08 18:44:38 +010051 if (m.IsChangeTaggedToFloat64()) return Replace(m.node()->InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052 break;
53 }
Ben Murdochc5610432016-08-08 18:44:38 +010054 case IrOpcode::kChangeInt31ToTaggedSigned:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055 case IrOpcode::kChangeInt32ToTagged: {
56 Int32Matcher m(node->InputAt(0));
57 if (m.HasValue()) return ReplaceNumber(m.Value());
Ben Murdochc5610432016-08-08 18:44:38 +010058 if (m.IsChangeTaggedToInt32() || m.IsChangeTaggedSignedToInt32()) {
59 return Replace(m.InputAt(0));
60 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 break;
62 }
63 case IrOpcode::kChangeTaggedToFloat64: {
64 NumberMatcher m(node->InputAt(0));
65 if (m.HasValue()) return ReplaceFloat64(m.Value());
66 if (m.IsChangeFloat64ToTagged()) return Replace(m.node()->InputAt(0));
Ben Murdochc5610432016-08-08 18:44:38 +010067 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 }
70 if (m.IsChangeUint32ToTagged()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 }
73 break;
74 }
75 case IrOpcode::kChangeTaggedToInt32: {
76 NumberMatcher m(node->InputAt(0));
77 if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
78 if (m.IsChangeFloat64ToTagged()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080 }
Ben Murdochc5610432016-08-08 18:44:38 +010081 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
82 return Replace(m.InputAt(0));
83 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 break;
85 }
86 case IrOpcode::kChangeTaggedToUint32: {
87 NumberMatcher m(node->InputAt(0));
88 if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
89 if (m.IsChangeFloat64ToTagged()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 if (m.IsChangeUint32ToTagged()) return Replace(m.InputAt(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 break;
94 }
95 case IrOpcode::kChangeUint32ToTagged: {
96 Uint32Matcher m(node->InputAt(0));
97 if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
98 break;
99 }
Ben Murdochc5610432016-08-08 18:44:38 +0100100 case IrOpcode::kTruncateTaggedToWord32: {
101 NumberMatcher m(node->InputAt(0));
102 if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
103 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged() ||
104 m.IsChangeUint32ToTagged()) {
105 return Replace(m.InputAt(0));
106 }
107 if (m.IsChangeFloat64ToTagged()) {
108 return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0));
109 }
110 break;
111 }
Ben Murdochda12d292016-06-02 14:46:10 +0100112 case IrOpcode::kNumberCeil:
113 case IrOpcode::kNumberFloor:
114 case IrOpcode::kNumberRound:
115 case IrOpcode::kNumberTrunc: {
116 Node* const input = NodeProperties::GetValueInput(node, 0);
117 Type* const input_type = NodeProperties::GetType(input);
118 if (input_type->Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
119 return Replace(input);
120 }
121 break;
122 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 case IrOpcode::kReferenceEqual:
124 return ReduceReferenceEqual(node);
Ben Murdochc5610432016-08-08 18:44:38 +0100125 case IrOpcode::kTypeGuard:
126 return ReduceTypeGuard(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 default:
128 break;
129 }
130 return NoChange();
131}
132
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133Reduction SimplifiedOperatorReducer::ReduceReferenceEqual(Node* node) {
134 DCHECK_EQ(IrOpcode::kReferenceEqual, node->opcode());
135 Node* const left = NodeProperties::GetValueInput(node, 0);
136 Node* const right = NodeProperties::GetValueInput(node, 1);
137 HeapObjectMatcher match_left(left);
138 HeapObjectMatcher match_right(right);
139 if (match_left.HasValue() && match_right.HasValue()) {
140 if (match_left.Value().is_identical_to(match_right.Value())) {
141 return Replace(jsgraph()->TrueConstant());
142 } else {
143 return Replace(jsgraph()->FalseConstant());
144 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145 }
146 return NoChange();
147}
148
Ben Murdochc5610432016-08-08 18:44:38 +0100149Reduction SimplifiedOperatorReducer::ReduceTypeGuard(Node* node) {
150 DCHECK_EQ(IrOpcode::kTypeGuard, node->opcode());
151 Node* const input = NodeProperties::GetValueInput(node, 0);
152 Type* const input_type = NodeProperties::GetTypeOrAny(input);
153 Type* const guard_type = TypeOf(node->op());
154 if (input_type->Is(guard_type)) return Replace(input);
155 return NoChange();
156}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400157
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
159 Node* a) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400160 DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
161 DCHECK_LE(1, node->InputCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162 node->ReplaceInput(0, a);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 NodeProperties::ChangeOp(node, op);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164 return Changed(node);
165}
166
167
168Reduction SimplifiedOperatorReducer::ReplaceFloat64(double value) {
169 return Replace(jsgraph()->Float64Constant(value));
170}
171
172
173Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
174 return Replace(jsgraph()->Int32Constant(value));
175}
176
177
178Reduction SimplifiedOperatorReducer::ReplaceNumber(double value) {
179 return Replace(jsgraph()->Constant(value));
180}
181
182
183Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
184 return Replace(jsgraph()->Constant(value));
185}
186
187
188Graph* SimplifiedOperatorReducer::graph() const { return jsgraph()->graph(); }
189
190
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
192 return jsgraph()->machine();
193}
194
195} // namespace compiler
196} // namespace internal
197} // namespace v8