| 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 |