| 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) { | 157 void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) { |
| 158 for (Edge edge : node->use_edges()) { | 158 for (Edge edge : node->use_edges()) { |
| 159 if (NodeProperties::IsControlEdge(edge)) { | 159 if (NodeProperties::IsControlEdge(edge)) { |
| 160 edge.UpdateTo(control); | 160 edge.UpdateTo(control); |
| 161 } else if (NodeProperties::IsEffectEdge(edge)) { | 161 } else if (NodeProperties::IsEffectEdge(edge)) { |
| 162 edge.UpdateTo(effect); | 162 edge.UpdateTo(effect); |
| 163 } else { | 163 } else { |
| 164 DCHECK(NodeProperties::IsValueEdge(edge) || | 164 DCHECK(NodeProperties::IsValueEdge(edge)); |
| 165 NodeProperties::IsContextEdge(edge)); | |
| 166 } | 165 } |
| 167 } | 166 } |
| 168 } | 167 } |
| 169 | 168 |
| 170 void ChangeToPureOp(Node* node, const Operator* new_op) { | 169 void ChangeToPureOp(Node* node, const Operator* new_op) { |
| 171 if (node->op()->EffectInputCount() > 0) { | 170 if (node->op()->EffectInputCount() > 0) { |
| 172 DCHECK_LT(0, node->op()->ControlInputCount()); | 171 DCHECK_LT(0, node->op()->ControlInputCount()); |
| 173 // Disconnect the node from effect and control chains. | 172 // Disconnect the node from effect and control chains. |
| 174 Node* control = NodeProperties::GetControlInput(node); | 173 Node* control = NodeProperties::GetControlInput(node); |
| 175 Node* effect = NodeProperties::GetEffectInput(node); | 174 Node* effect = NodeProperties::GetEffectInput(node); |
| (...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); | 1259 if (lower()) DeferReplacement(node, lowering->Int32Mod(node)); |
| 1261 return; | 1260 return; |
| 1262 } | 1261 } |
| 1263 // default case => Float64Mod | 1262 // default case => Float64Mod |
| 1264 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 1263 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), |
| 1265 MachineRepresentation::kFloat64, Type::Number()); | 1264 MachineRepresentation::kFloat64, Type::Number()); |
| 1266 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1265 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
| 1267 return; | 1266 return; |
| 1268 } | 1267 } |
| 1269 | 1268 |
| 1270 void VisitOsrGuard(Node* node) { | |
| 1271 VisitInputs(node); | |
| 1272 | |
| 1273 // Insert a dynamic check for the OSR value type if necessary. | |
| 1274 switch (OsrGuardTypeOf(node->op())) { | |
| 1275 case OsrGuardType::kUninitialized: | |
| 1276 // At this point, we should always have a type for the OsrValue. | |
| 1277 UNREACHABLE(); | |
| 1278 break; | |
| 1279 case OsrGuardType::kSignedSmall: | |
| 1280 if (lower()) { | |
| 1281 NodeProperties::ChangeOp(node, | |
| 1282 simplified()->CheckedTaggedToTaggedSigned()); | |
| 1283 } | |
| 1284 return SetOutput(node, MachineRepresentation::kTaggedSigned); | |
| 1285 case OsrGuardType::kAny: // Nothing to check. | |
| 1286 if (lower()) { | |
| 1287 DeferReplacement(node, node->InputAt(0)); | |
| 1288 } | |
| 1289 return SetOutput(node, MachineRepresentation::kTagged); | |
| 1290 } | |
| 1291 UNREACHABLE(); | |
| 1292 } | |
| 1293 | |
| 1294 // Dispatching routine for visiting the node {node} with the usage {use}. | 1269 // Dispatching routine for visiting the node {node} with the usage {use}. |
| 1295 // Depending on the operator, propagate new usage info to the inputs. | 1270 // Depending on the operator, propagate new usage info to the inputs. |
| 1296 void VisitNode(Node* node, Truncation truncation, | 1271 void VisitNode(Node* node, Truncation truncation, |
| 1297 SimplifiedLowering* lowering) { | 1272 SimplifiedLowering* lowering) { |
| 1298 // Unconditionally eliminate unused pure nodes (only relevant if there's | 1273 // Unconditionally eliminate unused pure nodes (only relevant if there's |
| 1299 // a pure operation in between two effectful ones, where the last one | 1274 // a pure operation in between two effectful ones, where the last one |
| 1300 // is unused). | 1275 // is unused). |
| 1301 // Note: We must not do this for constants, as they are cached and we | 1276 // Note: We must not do this for constants, as they are cached and we |
| 1302 // would thus kill the cached {node} during lowering (i.e. replace all | 1277 // would thus kill the cached {node} during lowering (i.e. replace all |
| 1303 // uses with Dead), but at that point some node lowering might have | 1278 // uses with Dead), but at that point some node lowering might have |
| (...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2427 // We just get rid of the sigma here. In principle, it should be | 2402 // We just get rid of the sigma here. In principle, it should be |
| 2428 // possible to refine the truncation and representation based on | 2403 // possible to refine the truncation and representation based on |
| 2429 // the sigma's type. | 2404 // the sigma's type. |
| 2430 MachineRepresentation output = | 2405 MachineRepresentation output = |
| 2431 GetOutputInfoForPhi(node, TypeOf(node->InputAt(0)), truncation); | 2406 GetOutputInfoForPhi(node, TypeOf(node->InputAt(0)), truncation); |
| 2432 VisitUnop(node, UseInfo(output, truncation), output); | 2407 VisitUnop(node, UseInfo(output, truncation), output); |
| 2433 if (lower()) DeferReplacement(node, node->InputAt(0)); | 2408 if (lower()) DeferReplacement(node, node->InputAt(0)); |
| 2434 return; | 2409 return; |
| 2435 } | 2410 } |
| 2436 | 2411 |
| 2437 case IrOpcode::kOsrGuard: | |
| 2438 return VisitOsrGuard(node); | |
| 2439 | |
| 2440 // Operators with all inputs tagged and no or tagged output have uniform | 2412 // Operators with all inputs tagged and no or tagged output have uniform |
| 2441 // handling. | 2413 // handling. |
| 2442 case IrOpcode::kEnd: | 2414 case IrOpcode::kEnd: |
| 2443 case IrOpcode::kReturn: | 2415 case IrOpcode::kReturn: |
| 2444 case IrOpcode::kIfSuccess: | 2416 case IrOpcode::kIfSuccess: |
| 2445 case IrOpcode::kIfException: | 2417 case IrOpcode::kIfException: |
| 2446 case IrOpcode::kIfTrue: | 2418 case IrOpcode::kIfTrue: |
| 2447 case IrOpcode::kIfFalse: | 2419 case IrOpcode::kIfFalse: |
| 2448 case IrOpcode::kDeoptimize: | 2420 case IrOpcode::kDeoptimize: |
| 2449 case IrOpcode::kEffectPhi: | 2421 case IrOpcode::kEffectPhi: |
| 2450 case IrOpcode::kTerminate: | 2422 case IrOpcode::kTerminate: |
| 2451 case IrOpcode::kFrameState: | 2423 case IrOpcode::kFrameState: |
| 2452 case IrOpcode::kCheckpoint: | 2424 case IrOpcode::kCheckpoint: |
| 2453 case IrOpcode::kLoop: | 2425 case IrOpcode::kLoop: |
| 2454 case IrOpcode::kMerge: | 2426 case IrOpcode::kMerge: |
| 2455 case IrOpcode::kThrow: | 2427 case IrOpcode::kThrow: |
| 2456 case IrOpcode::kBeginRegion: | 2428 case IrOpcode::kBeginRegion: |
| 2457 case IrOpcode::kFinishRegion: | 2429 case IrOpcode::kFinishRegion: |
| 2430 case IrOpcode::kOsrValue: |
| 2458 case IrOpcode::kProjection: | 2431 case IrOpcode::kProjection: |
| 2459 case IrOpcode::kObjectState: | 2432 case IrOpcode::kObjectState: |
| 2460 case IrOpcode::kOsrValue: | |
| 2461 // All JavaScript operators except JSToNumber have uniform handling. | 2433 // All JavaScript operators except JSToNumber have uniform handling. |
| 2462 #define OPCODE_CASE(name) case IrOpcode::k##name: | 2434 #define OPCODE_CASE(name) case IrOpcode::k##name: |
| 2463 JS_SIMPLE_BINOP_LIST(OPCODE_CASE) | 2435 JS_SIMPLE_BINOP_LIST(OPCODE_CASE) |
| 2464 JS_OTHER_UNOP_LIST(OPCODE_CASE) | 2436 JS_OTHER_UNOP_LIST(OPCODE_CASE) |
| 2465 JS_OBJECT_OP_LIST(OPCODE_CASE) | 2437 JS_OBJECT_OP_LIST(OPCODE_CASE) |
| 2466 JS_CONTEXT_OP_LIST(OPCODE_CASE) | 2438 JS_CONTEXT_OP_LIST(OPCODE_CASE) |
| 2467 JS_OTHER_OP_LIST(OPCODE_CASE) | 2439 JS_OTHER_OP_LIST(OPCODE_CASE) |
| 2468 #undef OPCODE_CASE | 2440 #undef OPCODE_CASE |
| 2469 case IrOpcode::kJSToInteger: | 2441 case IrOpcode::kJSToInteger: |
| 2470 case IrOpcode::kJSToLength: | 2442 case IrOpcode::kJSToLength: |
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3238 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3210 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
| 3239 Operator::kNoProperties); | 3211 Operator::kNoProperties); |
| 3240 to_number_operator_.set(common()->Call(desc)); | 3212 to_number_operator_.set(common()->Call(desc)); |
| 3241 } | 3213 } |
| 3242 return to_number_operator_.get(); | 3214 return to_number_operator_.get(); |
| 3243 } | 3215 } |
| 3244 | 3216 |
| 3245 } // namespace compiler | 3217 } // namespace compiler |
| 3246 } // namespace internal | 3218 } // namespace internal |
| 3247 } // namespace v8 | 3219 } // namespace v8 |
| OLD | NEW |