| 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/graph-inl.h" | 5 #include "src/compiler/graph-inl.h" |
| 6 #include "src/compiler/js-builtin-reducer.h" | 6 #include "src/compiler/js-builtin-reducer.h" |
| 7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
| 8 #include "src/compiler/node-properties-inl.h" | 8 #include "src/compiler/node-properties-inl.h" |
| 9 #include "src/types.h" | 9 #include "src/types.h" |
| 10 | 10 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 JSCallReduction r(node); | 210 JSCallReduction r(node); |
| 211 if (r.InputsMatchOne(Type::Number())) { | 211 if (r.InputsMatchOne(Type::Number())) { |
| 212 // Math.ceil(a:number) -> Float64Ceil(a) | 212 // Math.ceil(a:number) -> Float64Ceil(a) |
| 213 Node* value = graph()->NewNode(machine()->Float64Ceil(), r.left()); | 213 Node* value = graph()->NewNode(machine()->Float64Ceil(), r.left()); |
| 214 return Replace(value); | 214 return Replace(value); |
| 215 } | 215 } |
| 216 return NoChange(); | 216 return NoChange(); |
| 217 } | 217 } |
| 218 | 218 |
| 219 | 219 |
| 220 // ES6 draft 10-14-14, section 20.2.2.28. |
| 221 Reduction JSBuiltinReducer::ReduceMathRound(Node* node) { |
| 222 if (machine()->HasFloat64Floor() && machine()->HasFloat64RoundTiesAway()) { |
| 223 JSCallReduction r(node); |
| 224 if (r.InputsMatchOne(Type::Number())) { |
| 225 // This is based on the implementation from Crankshaft, |
| 226 // see lithium-codegen-arm64.cc:LCodeGen::DoMathRoundD. |
| 227 // Implementation will be selected for 32bit ARMv8, too. |
| 228 // Math.round(a:number) -> |
| 229 // double res = Float64RoundTiesAway(a); |
| 230 // if (a >= 0.0 || a == res) { |
| 231 // return res; |
| 232 // } else { |
| 233 // return -abs(Float64Floor(a + 0.5)) |
| 234 // } |
| 235 Node* p = r.GetJSCallInput(0); |
| 236 Node* control = graph()->start(); |
| 237 Node* rounded_away = |
| 238 graph()->NewNode(machine()->Float64RoundTiesAway(), p); |
| 239 |
| 240 Node* ge_zero = graph()->NewNode(simplified()->NumberLessThanOrEqual(), |
| 241 jsgraph()->ZeroConstant(), p); |
| 242 Node* eq_rounded = |
| 243 graph()->NewNode(machine()->Float64Equal(), p, rounded_away); |
| 244 |
| 245 Node* condition = |
| 246 graph()->NewNode(machine()->WordOr(), eq_rounded, ge_zero); |
| 247 |
| 248 Node* branch = graph()->NewNode(common()->Branch(), condition, control); |
| 249 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
| 250 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| 251 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); |
| 252 |
| 253 Node* sum = graph()->NewNode(machine()->Float64Add(), p, |
| 254 jsgraph()->Constant(0.5)); |
| 255 Node* floored = graph()->NewNode(machine()->Float64Floor(), sum); |
| 256 |
| 257 // Now ensure negative sign. |
| 258 // TODO(turbofan): use FNEG(FABS(x)) instructions here; they are |
| 259 // available on ARM (which this implementation is targeted at). |
| 260 Node* zero = jsgraph()->Constant(-0.0); |
| 261 Node* tag = graph()->NewNode(machine()->Float64LessThan(), floored, zero); |
| 262 |
| 263 Node* branch2 = graph()->NewNode(common()->Branch(), tag, control); |
| 264 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); |
| 265 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); |
| 266 Node* merge2 = graph()->NewNode(common()->Merge(2), if_true2, if_false2); |
| 267 |
| 268 Node* neg = |
| 269 graph()->NewNode(simplified()->NumberSubtract(), zero, floored); |
| 270 Node* value = graph()->NewNode(common()->Phi(kMachFloat64, 2), floored, |
| 271 neg, merge2); |
| 272 |
| 273 Node* res = graph()->NewNode(common()->Phi(kMachFloat64, 2), rounded_away, |
| 274 value, merge); |
| 275 |
| 276 return Replace(res); |
| 277 } |
| 278 } |
| 279 return NoChange(); |
| 280 } |
| 281 |
| 282 |
| 220 Reduction JSBuiltinReducer::Reduce(Node* node) { | 283 Reduction JSBuiltinReducer::Reduce(Node* node) { |
| 221 JSCallReduction r(node); | 284 JSCallReduction r(node); |
| 222 | 285 |
| 223 // Dispatch according to the BuiltinFunctionId if present. | 286 // Dispatch according to the BuiltinFunctionId if present. |
| 224 if (!r.HasBuiltinFunctionId()) return NoChange(); | 287 if (!r.HasBuiltinFunctionId()) return NoChange(); |
| 225 switch (r.GetBuiltinFunctionId()) { | 288 switch (r.GetBuiltinFunctionId()) { |
| 226 case kMathAbs: | 289 case kMathAbs: |
| 227 return ReplaceWithPureReduction(node, ReduceMathAbs(node)); | 290 return ReplaceWithPureReduction(node, ReduceMathAbs(node)); |
| 228 case kMathSqrt: | 291 case kMathSqrt: |
| 229 return ReplaceWithPureReduction(node, ReduceMathSqrt(node)); | 292 return ReplaceWithPureReduction(node, ReduceMathSqrt(node)); |
| 230 case kMathMax: | 293 case kMathMax: |
| 231 return ReplaceWithPureReduction(node, ReduceMathMax(node)); | 294 return ReplaceWithPureReduction(node, ReduceMathMax(node)); |
| 232 case kMathImul: | 295 case kMathImul: |
| 233 return ReplaceWithPureReduction(node, ReduceMathImul(node)); | 296 return ReplaceWithPureReduction(node, ReduceMathImul(node)); |
| 234 case kMathFround: | 297 case kMathFround: |
| 235 return ReplaceWithPureReduction(node, ReduceMathFround(node)); | 298 return ReplaceWithPureReduction(node, ReduceMathFround(node)); |
| 236 case kMathFloor: | 299 case kMathFloor: |
| 237 return ReplaceWithPureReduction(node, ReduceMathFloor(node)); | 300 return ReplaceWithPureReduction(node, ReduceMathFloor(node)); |
| 238 case kMathCeil: | 301 case kMathCeil: |
| 239 return ReplaceWithPureReduction(node, ReduceMathCeil(node)); | 302 return ReplaceWithPureReduction(node, ReduceMathCeil(node)); |
| 303 case kMathRound: |
| 304 return ReplaceWithPureReduction(node, ReduceMathRound(node)); |
| 240 default: | 305 default: |
| 241 break; | 306 break; |
| 242 } | 307 } |
| 243 return NoChange(); | 308 return NoChange(); |
| 244 } | 309 } |
| 245 | 310 |
| 246 } // namespace compiler | 311 } // namespace compiler |
| 247 } // namespace internal | 312 } // namespace internal |
| 248 } // namespace v8 | 313 } // namespace v8 |
| OLD | NEW |