OLD | NEW |
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-builtin-reducer.h" | 5 #include "src/compiler/js-builtin-reducer.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 JSCallReduction r(node); | 123 JSCallReduction r(node); |
124 if (r.InputsMatchTwo(Type::Integral32(), Type::Integral32())) { | 124 if (r.InputsMatchTwo(Type::Integral32(), Type::Integral32())) { |
125 // Math.imul(a:int32, b:int32) -> Int32Mul(a, b) | 125 // Math.imul(a:int32, b:int32) -> Int32Mul(a, b) |
126 Node* value = graph()->NewNode(machine()->Int32Mul(), r.left(), r.right()); | 126 Node* value = graph()->NewNode(machine()->Int32Mul(), r.left(), r.right()); |
127 return Replace(value); | 127 return Replace(value); |
128 } | 128 } |
129 return NoChange(); | 129 return NoChange(); |
130 } | 130 } |
131 | 131 |
132 // ES6 draft 08-24-14, section 20.2.2.16. | 132 // ES6 draft 08-24-14, section 20.2.2.16. |
| 133 Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) { |
| 134 JSCallReduction r(node); |
| 135 if (r.InputsMatchOne(Type::Number())) { |
| 136 // Math.ceil(a:number) -> NumberCeil(a) |
| 137 Node* value = graph()->NewNode(simplified()->NumberCeil(), r.left()); |
| 138 return Replace(value); |
| 139 } |
| 140 return NoChange(); |
| 141 } |
| 142 |
| 143 // ES6 draft 08-24-14, section 20.2.2.16. |
133 Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) { | 144 Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) { |
134 JSCallReduction r(node); | 145 JSCallReduction r(node); |
135 if (r.InputsMatchOne(Type::Number())) { | 146 if (r.InputsMatchOne(Type::Number())) { |
136 // Math.floor(a:number) -> NumberFloor(a) | 147 // Math.floor(a:number) -> NumberFloor(a) |
137 Node* value = graph()->NewNode(simplified()->NumberFloor(), r.left()); | 148 Node* value = graph()->NewNode(simplified()->NumberFloor(), r.left()); |
138 return Replace(value); | 149 return Replace(value); |
139 } | 150 } |
140 return NoChange(); | 151 return NoChange(); |
141 } | 152 } |
142 | 153 |
143 // ES6 draft 08-24-14, section 20.2.2.17. | 154 // ES6 draft 08-24-14, section 20.2.2.17. |
144 Reduction JSBuiltinReducer::ReduceMathFround(Node* node) { | 155 Reduction JSBuiltinReducer::ReduceMathFround(Node* node) { |
145 JSCallReduction r(node); | 156 JSCallReduction r(node); |
146 if (r.InputsMatchOne(Type::Number())) { | 157 if (r.InputsMatchOne(Type::Number())) { |
147 // Math.fround(a:number) -> TruncateFloat64ToFloat32(a) | 158 // Math.fround(a:number) -> TruncateFloat64ToFloat32(a) |
148 Node* value = | 159 Node* value = |
149 graph()->NewNode(machine()->TruncateFloat64ToFloat32(), r.left()); | 160 graph()->NewNode(machine()->TruncateFloat64ToFloat32(), r.left()); |
150 return Replace(value); | 161 return Replace(value); |
151 } | 162 } |
152 return NoChange(); | 163 return NoChange(); |
153 } | 164 } |
154 | 165 |
155 // ES6 section 20.2.2.28 Math.round ( x ) | 166 // ES6 section 20.2.2.28 Math.round ( x ) |
156 Reduction JSBuiltinReducer::ReduceMathRound(Node* node) { | 167 Reduction JSBuiltinReducer::ReduceMathRound(Node* node) { |
157 JSCallReduction r(node); | 168 JSCallReduction r(node); |
158 if (r.InputsMatchOne(type_cache_.kIntegerOrMinusZeroOrNaN)) { | 169 if (r.InputsMatchOne(Type::Number())) { |
159 // Math.round(a:integer \/ -0 \/ NaN) -> a | 170 // Math.round(a:number) -> NumberRound(a) |
160 return Replace(r.left()); | 171 Node* value = graph()->NewNode(simplified()->NumberRound(), r.left()); |
161 } | 172 return Replace(value); |
162 if (r.InputsMatchOne(Type::Number()) && | |
163 machine()->Float64RoundUp().IsSupported()) { | |
164 // Math.round(a:number) -> Select(Float64LessThan(#0.5, Float64Sub(i, a)), | |
165 // Float64Sub(i, #1.0), i) | |
166 // where i = Float64RoundUp(a) | |
167 Node* value = r.left(); | |
168 Node* integer = graph()->NewNode(machine()->Float64RoundUp().op(), value); | |
169 Node* real = graph()->NewNode(machine()->Float64Sub(), integer, value); | |
170 return Replace(graph()->NewNode( | |
171 common()->Select(MachineRepresentation::kFloat64), | |
172 graph()->NewNode(machine()->Float64LessThan(), | |
173 jsgraph()->Float64Constant(0.5), real), | |
174 graph()->NewNode(machine()->Float64Sub(), integer, | |
175 jsgraph()->Float64Constant(1.0)), | |
176 integer)); | |
177 } | 173 } |
178 return NoChange(); | 174 return NoChange(); |
179 } | 175 } |
180 | 176 |
181 // ES6 section 20.2.2.32 Math.sqrt ( x ) | 177 // ES6 section 20.2.2.32 Math.sqrt ( x ) |
182 Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) { | 178 Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) { |
183 JSCallReduction r(node); | 179 JSCallReduction r(node); |
184 if (r.InputsMatchOne(Type::Number())) { | 180 if (r.InputsMatchOne(Type::Number())) { |
185 // Math.sqrt(a:number) -> Float64Sqrt(a) | 181 // Math.sqrt(a:number) -> Float64Sqrt(a) |
186 Node* value = graph()->NewNode(machine()->Float64Sqrt(), r.left()); | 182 Node* value = graph()->NewNode(machine()->Float64Sqrt(), r.left()); |
187 return Replace(value); | 183 return Replace(value); |
188 } | 184 } |
189 return NoChange(); | 185 return NoChange(); |
190 } | 186 } |
191 | 187 |
| 188 // ES6 section 20.2.2.35 Math.trunc ( x ) |
| 189 Reduction JSBuiltinReducer::ReduceMathTrunc(Node* node) { |
| 190 JSCallReduction r(node); |
| 191 if (r.InputsMatchOne(Type::Number())) { |
| 192 // Math.trunc(a:number) -> NumberTrunc(a) |
| 193 Node* value = graph()->NewNode(simplified()->NumberTrunc(), r.left()); |
| 194 return Replace(value); |
| 195 } |
| 196 return NoChange(); |
| 197 } |
| 198 |
192 Reduction JSBuiltinReducer::Reduce(Node* node) { | 199 Reduction JSBuiltinReducer::Reduce(Node* node) { |
193 Reduction reduction = NoChange(); | 200 Reduction reduction = NoChange(); |
194 JSCallReduction r(node); | 201 JSCallReduction r(node); |
195 | 202 |
196 // Dispatch according to the BuiltinFunctionId if present. | 203 // Dispatch according to the BuiltinFunctionId if present. |
197 if (!r.HasBuiltinFunctionId()) return NoChange(); | 204 if (!r.HasBuiltinFunctionId()) return NoChange(); |
198 switch (r.GetBuiltinFunctionId()) { | 205 switch (r.GetBuiltinFunctionId()) { |
199 case kMathMax: | 206 case kMathMax: |
200 reduction = ReduceMathMax(node); | 207 reduction = ReduceMathMax(node); |
201 break; | 208 break; |
202 case kMathImul: | 209 case kMathImul: |
203 reduction = ReduceMathImul(node); | 210 reduction = ReduceMathImul(node); |
204 break; | 211 break; |
| 212 case kMathCeil: |
| 213 reduction = ReduceMathCeil(node); |
| 214 break; |
205 case kMathFloor: | 215 case kMathFloor: |
206 reduction = ReduceMathFloor(node); | 216 reduction = ReduceMathFloor(node); |
207 break; | 217 break; |
208 case kMathFround: | 218 case kMathFround: |
209 reduction = ReduceMathFround(node); | 219 reduction = ReduceMathFround(node); |
210 break; | 220 break; |
211 case kMathRound: | 221 case kMathRound: |
212 reduction = ReduceMathRound(node); | 222 reduction = ReduceMathRound(node); |
213 break; | 223 break; |
214 case kMathSqrt: | 224 case kMathSqrt: |
215 reduction = ReduceMathSqrt(node); | 225 reduction = ReduceMathSqrt(node); |
216 break; | 226 break; |
| 227 case kMathTrunc: |
| 228 reduction = ReduceMathTrunc(node); |
| 229 break; |
217 default: | 230 default: |
218 break; | 231 break; |
219 } | 232 } |
220 | 233 |
221 // Replace builtin call assuming replacement nodes are pure values that don't | 234 // Replace builtin call assuming replacement nodes are pure values that don't |
222 // produce an effect. Replaces {node} with {reduction} and relaxes effects. | 235 // produce an effect. Replaces {node} with {reduction} and relaxes effects. |
223 if (reduction.Changed()) ReplaceWithValue(node, reduction.replacement()); | 236 if (reduction.Changed()) ReplaceWithValue(node, reduction.replacement()); |
224 | 237 |
225 return reduction; | 238 return reduction; |
226 } | 239 } |
(...skipping 15 matching lines...) Expand all Loading... |
242 } | 255 } |
243 | 256 |
244 | 257 |
245 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { | 258 SimplifiedOperatorBuilder* JSBuiltinReducer::simplified() const { |
246 return jsgraph()->simplified(); | 259 return jsgraph()->simplified(); |
247 } | 260 } |
248 | 261 |
249 } // namespace compiler | 262 } // namespace compiler |
250 } // namespace internal | 263 } // namespace internal |
251 } // namespace v8 | 264 } // namespace v8 |
OLD | NEW |