5 #include "src/compiler/simplified-operator-reducer.h" 7 #include "src/compiler/js-graph.h" 8 #include "src/compiler/machine-operator.h" 9 #include "src/compiler/node-matchers.h" 10 #include "src/compiler/operator-properties.h" 11 #include "src/compiler/simplified-operator.h" 12 #include "src/compiler/type-cache.h" 13 #include "src/conversions-inl.h" 21 Decision DecideObjectIsSmi(Node*
const input) {
22 NumberMatcher m(input);
24 return IsSmiDouble(m.Value()) ? Decision::kTrue : Decision::kFalse;
26 if (m.IsAllocate())
return Decision::kFalse;
27 if (m.IsChangeBitToTagged())
return Decision::kFalse;
28 if (m.IsChangeInt31ToTaggedSigned())
return Decision::kTrue;
29 if (m.IsHeapConstant())
return Decision::kFalse;
30 return Decision::kUnknown;
35 SimplifiedOperatorReducer::SimplifiedOperatorReducer(Editor* editor,
38 : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
40 SimplifiedOperatorReducer::~SimplifiedOperatorReducer() =
default;
43 Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
44 DisallowHeapAccess no_heap_access;
45 switch (node->opcode()) {
46 case IrOpcode::kBooleanNot: {
48 HeapObjectMatcher m(node->InputAt(0));
49 if (m.Is(factory()->true_value()))
return ReplaceBoolean(
false);
50 if (m.Is(factory()->false_value()))
return ReplaceBoolean(
true);
51 if (m.IsBooleanNot())
return Replace(m.InputAt(0));
54 case IrOpcode::kChangeBitToTagged: {
55 Int32Matcher m(node->InputAt(0));
56 if (m.Is(0))
return Replace(jsgraph()->FalseConstant());
57 if (m.Is(1))
return Replace(jsgraph()->TrueConstant());
58 if (m.IsChangeTaggedToBit())
return Replace(m.InputAt(0));
61 case IrOpcode::kChangeTaggedToBit: {
62 HeapObjectMatcher m(node->InputAt(0));
64 return ReplaceInt32(m.Ref(broker()).BooleanValue());
66 if (m.IsChangeBitToTagged())
return Replace(m.InputAt(0));
69 case IrOpcode::kChangeFloat64ToTagged: {
70 Float64Matcher m(node->InputAt(0));
71 if (m.HasValue())
return ReplaceNumber(m.Value());
72 if (m.IsChangeTaggedToFloat64())
return Replace(m.node()->InputAt(0));
75 case IrOpcode::kChangeInt31ToTaggedSigned:
76 case IrOpcode::kChangeInt32ToTagged: {
77 Int32Matcher m(node->InputAt(0));
78 if (m.HasValue())
return ReplaceNumber(m.Value());
79 if (m.IsChangeTaggedToInt32() || m.IsChangeTaggedSignedToInt32()) {
80 return Replace(m.InputAt(0));
84 case IrOpcode::kChangeTaggedToFloat64:
85 case IrOpcode::kTruncateTaggedToFloat64: {
86 NumberMatcher m(node->InputAt(0));
87 if (m.HasValue())
return ReplaceFloat64(m.Value());
88 if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
89 return Replace(m.node()->InputAt(0));
91 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
92 return Change(node, machine()->ChangeInt32ToFloat64(), m.InputAt(0));
94 if (m.IsChangeUint32ToTagged()) {
95 return Change(node, machine()->ChangeUint32ToFloat64(), m.InputAt(0));
99 case IrOpcode::kChangeTaggedSignedToInt32:
100 case IrOpcode::kChangeTaggedToInt32: {
101 NumberMatcher m(node->InputAt(0));
102 if (m.HasValue())
return ReplaceInt32(DoubleToInt32(m.Value()));
103 if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
104 return Change(node, machine()->ChangeFloat64ToInt32(), m.InputAt(0));
106 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged()) {
107 return Replace(m.InputAt(0));
111 case IrOpcode::kChangeTaggedToUint32: {
112 NumberMatcher m(node->InputAt(0));
113 if (m.HasValue())
return ReplaceUint32(DoubleToUint32(m.Value()));
114 if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
115 return Change(node, machine()->ChangeFloat64ToUint32(), m.InputAt(0));
117 if (m.IsChangeUint32ToTagged())
return Replace(m.InputAt(0));
120 case IrOpcode::kChangeUint32ToTagged: {
121 Uint32Matcher m(node->InputAt(0));
122 if (m.HasValue())
return ReplaceNumber(FastUI2D(m.Value()));
125 case IrOpcode::kTruncateTaggedToWord32: {
126 NumberMatcher m(node->InputAt(0));
127 if (m.HasValue())
return ReplaceInt32(DoubleToInt32(m.Value()));
128 if (m.IsChangeInt31ToTaggedSigned() || m.IsChangeInt32ToTagged() ||
129 m.IsChangeUint32ToTagged()) {
130 return Replace(m.InputAt(0));
132 if (m.IsChangeFloat64ToTagged() || m.IsChangeFloat64ToTaggedPointer()) {
133 return Change(node, machine()->TruncateFloat64ToWord32(), m.InputAt(0));
137 case IrOpcode::kCheckedFloat64ToInt32: {
138 Float64Matcher m(node->InputAt(0));
139 if (m.HasValue() && IsInt32Double(m.Value())) {
140 Node* value = jsgraph()->Int32Constant(static_cast<int32_t>(m.Value()));
141 ReplaceWithValue(node, value);
142 return Replace(value);
146 case IrOpcode::kCheckedTaggedToInt32:
147 case IrOpcode::kCheckedTaggedSignedToInt32: {
148 NodeMatcher m(node->InputAt(0));
149 if (m.IsConvertTaggedHoleToUndefined()) {
150 node->ReplaceInput(0, m.InputAt(0));
151 return Changed(node);
155 case IrOpcode::kCheckIf: {
156 HeapObjectMatcher m(node->InputAt(0));
157 if (m.Is(factory()->true_value())) {
158 Node*
const effect = NodeProperties::GetEffectInput(node);
159 return Replace(effect);
163 case IrOpcode::kCheckNumber: {
164 NodeMatcher m(node->InputAt(0));
165 if (m.IsConvertTaggedHoleToUndefined()) {
166 node->ReplaceInput(0, m.InputAt(0));
167 return Changed(node);
171 case IrOpcode::kCheckHeapObject: {
172 Node*
const input = node->InputAt(0);
173 if (DecideObjectIsSmi(input) == Decision::kFalse) {
174 ReplaceWithValue(node, input);
175 return Replace(input);
177 NodeMatcher m(input);
178 if (m.IsCheckHeapObject()) {
179 ReplaceWithValue(node, input);
180 return Replace(input);
184 case IrOpcode::kCheckSmi: {
185 Node*
const input = node->InputAt(0);
186 if (DecideObjectIsSmi(input) == Decision::kTrue) {
187 ReplaceWithValue(node, input);
188 return Replace(input);
190 NodeMatcher m(input);
191 if (m.IsCheckSmi()) {
192 ReplaceWithValue(node, input);
193 return Replace(input);
194 }
else if (m.IsConvertTaggedHoleToUndefined()) {
195 node->ReplaceInput(0, m.InputAt(0));
196 return Changed(node);
200 case IrOpcode::kObjectIsSmi: {
201 Node*
const input = node->InputAt(0);
202 switch (DecideObjectIsSmi(input)) {
203 case Decision::kTrue:
204 return ReplaceBoolean(
true);
205 case Decision::kFalse:
206 return ReplaceBoolean(
false);
207 case Decision::kUnknown:
212 case IrOpcode::kNumberAbs: {
213 NumberMatcher m(node->InputAt(0));
214 if (m.HasValue())
return ReplaceNumber(std::fabs(m.Value()));
217 case IrOpcode::kReferenceEqual: {
218 HeapObjectBinopMatcher m(node);
219 if (m.left().node() == m.right().node())
return ReplaceBoolean(
true);
228 Reduction SimplifiedOperatorReducer::Change(Node* node,
const Operator* op,
230 DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
231 DCHECK_LE(1, node->InputCount());
232 node->ReplaceInput(0, a);
233 NodeProperties::ChangeOp(node, op);
234 return Changed(node);
237 Reduction SimplifiedOperatorReducer::ReplaceBoolean(
bool value) {
238 return Replace(jsgraph()->BooleanConstant(value));
241 Reduction SimplifiedOperatorReducer::ReplaceFloat64(
double value) {
242 return Replace(jsgraph()->Float64Constant(value));
246 Reduction SimplifiedOperatorReducer::ReplaceInt32(int32_t value) {
247 return Replace(jsgraph()->Int32Constant(value));
251 Reduction SimplifiedOperatorReducer::ReplaceNumber(
double value) {
252 return Replace(jsgraph()->Constant(value));
256 Reduction SimplifiedOperatorReducer::ReplaceNumber(int32_t value) {
257 return Replace(jsgraph()->Constant(value));
260 Factory* SimplifiedOperatorReducer::factory()
const {
261 return jsgraph()->isolate()->factory();
264 Graph* SimplifiedOperatorReducer::graph()
const {
return jsgraph()->graph(); }
266 MachineOperatorBuilder* SimplifiedOperatorReducer::machine()
const {
267 return jsgraph()->machine();