| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
| 8 | 8 |
| 9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 | 1472 |
| 1473 Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input, | 1473 Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input, |
| 1474 wasm::WasmCodePosition position) { | 1474 wasm::WasmCodePosition position) { |
| 1475 if (jsgraph()->machine()->Is32()) { | 1475 if (jsgraph()->machine()->Is32()) { |
| 1476 return BuildFloatToIntConversionInstruction( | 1476 return BuildFloatToIntConversionInstruction( |
| 1477 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), | 1477 input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), |
| 1478 MachineRepresentation::kFloat32, MachineType::Int64(), position); | 1478 MachineRepresentation::kFloat32, MachineType::Int64(), position); |
| 1479 } else { | 1479 } else { |
| 1480 Node* trunc = graph()->NewNode( | 1480 Node* trunc = graph()->NewNode( |
| 1481 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); | 1481 jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); |
| 1482 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 1482 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc, |
| 1483 Node* overflow = | 1483 graph()->start()); |
| 1484 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 1484 Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc, |
| 1485 graph()->start()); |
| 1485 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); | 1486 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1486 return result; | 1487 return result; |
| 1487 } | 1488 } |
| 1488 } | 1489 } |
| 1489 | 1490 |
| 1490 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input, | 1491 Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input, |
| 1491 wasm::WasmCodePosition position) { | 1492 wasm::WasmCodePosition position) { |
| 1492 if (jsgraph()->machine()->Is32()) { | 1493 if (jsgraph()->machine()->Is32()) { |
| 1493 return BuildFloatToIntConversionInstruction( | 1494 return BuildFloatToIntConversionInstruction( |
| 1494 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), | 1495 input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), |
| 1495 MachineRepresentation::kFloat32, MachineType::Int64(), position); | 1496 MachineRepresentation::kFloat32, MachineType::Int64(), position); |
| 1496 } else { | 1497 } else { |
| 1497 Node* trunc = graph()->NewNode( | 1498 Node* trunc = graph()->NewNode( |
| 1498 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); | 1499 jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); |
| 1499 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 1500 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc, |
| 1500 Node* overflow = | 1501 graph()->start()); |
| 1501 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 1502 Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc, |
| 1503 graph()->start()); |
| 1502 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); | 1504 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1503 return result; | 1505 return result; |
| 1504 } | 1506 } |
| 1505 } | 1507 } |
| 1506 | 1508 |
| 1507 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input, | 1509 Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input, |
| 1508 wasm::WasmCodePosition position) { | 1510 wasm::WasmCodePosition position) { |
| 1509 if (jsgraph()->machine()->Is32()) { | 1511 if (jsgraph()->machine()->Is32()) { |
| 1510 return BuildFloatToIntConversionInstruction( | 1512 return BuildFloatToIntConversionInstruction( |
| 1511 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), | 1513 input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), |
| 1512 MachineRepresentation::kFloat64, MachineType::Int64(), position); | 1514 MachineRepresentation::kFloat64, MachineType::Int64(), position); |
| 1513 } else { | 1515 } else { |
| 1514 Node* trunc = graph()->NewNode( | 1516 Node* trunc = graph()->NewNode( |
| 1515 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); | 1517 jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); |
| 1516 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 1518 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc, |
| 1517 Node* overflow = | 1519 graph()->start()); |
| 1518 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 1520 Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc, |
| 1521 graph()->start()); |
| 1519 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); | 1522 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1520 return result; | 1523 return result; |
| 1521 } | 1524 } |
| 1522 } | 1525 } |
| 1523 | 1526 |
| 1524 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input, | 1527 Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input, |
| 1525 wasm::WasmCodePosition position) { | 1528 wasm::WasmCodePosition position) { |
| 1526 if (jsgraph()->machine()->Is32()) { | 1529 if (jsgraph()->machine()->Is32()) { |
| 1527 return BuildFloatToIntConversionInstruction( | 1530 return BuildFloatToIntConversionInstruction( |
| 1528 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), | 1531 input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), |
| 1529 MachineRepresentation::kFloat64, MachineType::Int64(), position); | 1532 MachineRepresentation::kFloat64, MachineType::Int64(), position); |
| 1530 } else { | 1533 } else { |
| 1531 Node* trunc = graph()->NewNode( | 1534 Node* trunc = graph()->NewNode( |
| 1532 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); | 1535 jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); |
| 1533 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); | 1536 Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc, |
| 1534 Node* overflow = | 1537 graph()->start()); |
| 1535 graph()->NewNode(jsgraph()->common()->Projection(1), trunc); | 1538 Node* overflow = graph()->NewNode(jsgraph()->common()->Projection(1), trunc, |
| 1539 graph()->start()); |
| 1536 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); | 1540 trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1537 return result; | 1541 return result; |
| 1538 } | 1542 } |
| 1539 } | 1543 } |
| 1540 | 1544 |
| 1541 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( | 1545 Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( |
| 1542 Node* input, ExternalReference ref, | 1546 Node* input, ExternalReference ref, |
| 1543 MachineRepresentation parameter_representation, | 1547 MachineRepresentation parameter_representation, |
| 1544 const MachineType result_type, wasm::WasmCodePosition position) { | 1548 const MachineType result_type, wasm::WasmCodePosition position) { |
| 1545 Node* stack_slot_param = graph()->NewNode( | 1549 Node* stack_slot_param = graph()->NewNode( |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1968 } | 1972 } |
| 1969 | 1973 |
| 1970 Node* WasmGraphBuilder::BuildChangeInt32ToTagged(Node* value) { | 1974 Node* WasmGraphBuilder::BuildChangeInt32ToTagged(Node* value) { |
| 1971 MachineOperatorBuilder* machine = jsgraph()->machine(); | 1975 MachineOperatorBuilder* machine = jsgraph()->machine(); |
| 1972 CommonOperatorBuilder* common = jsgraph()->common(); | 1976 CommonOperatorBuilder* common = jsgraph()->common(); |
| 1973 | 1977 |
| 1974 if (machine->Is64()) { | 1978 if (machine->Is64()) { |
| 1975 return BuildChangeInt32ToSmi(value); | 1979 return BuildChangeInt32ToSmi(value); |
| 1976 } | 1980 } |
| 1977 | 1981 |
| 1978 Node* add = graph()->NewNode(machine->Int32AddWithOverflow(), value, value); | 1982 Node* add = graph()->NewNode(machine->Int32AddWithOverflow(), value, value, |
| 1983 graph()->start()); |
| 1979 | 1984 |
| 1980 Node* ovf = graph()->NewNode(common->Projection(1), add); | 1985 Node* ovf = graph()->NewNode(common->Projection(1), add, graph()->start()); |
| 1981 Node* branch = graph()->NewNode(common->Branch(BranchHint::kFalse), ovf, | 1986 Node* branch = graph()->NewNode(common->Branch(BranchHint::kFalse), ovf, |
| 1982 graph()->start()); | 1987 graph()->start()); |
| 1983 | 1988 |
| 1984 Node* if_true = graph()->NewNode(common->IfTrue(), branch); | 1989 Node* if_true = graph()->NewNode(common->IfTrue(), branch); |
| 1985 Node* vtrue = BuildAllocateHeapNumberWithValue( | 1990 Node* vtrue = BuildAllocateHeapNumberWithValue( |
| 1986 graph()->NewNode(machine->ChangeInt32ToFloat64(), value), if_true); | 1991 graph()->NewNode(machine->ChangeInt32ToFloat64(), value), if_true); |
| 1987 | 1992 |
| 1988 Node* if_false = graph()->NewNode(common->IfFalse(), branch); | 1993 Node* if_false = graph()->NewNode(common->IfFalse(), branch); |
| 1989 Node* vfalse = graph()->NewNode(common->Projection(0), add); | 1994 Node* vfalse = graph()->NewNode(common->Projection(0), add, if_false); |
| 1990 | 1995 |
| 1991 Node* merge = graph()->NewNode(common->Merge(2), if_true, if_false); | 1996 Node* merge = graph()->NewNode(common->Merge(2), if_true, if_false); |
| 1992 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), | 1997 Node* phi = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), |
| 1993 vtrue, vfalse, merge); | 1998 vtrue, vfalse, merge); |
| 1994 return phi; | 1999 return phi; |
| 1995 } | 2000 } |
| 1996 | 2001 |
| 1997 Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) { | 2002 Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) { |
| 1998 MachineOperatorBuilder* machine = jsgraph()->machine(); | 2003 MachineOperatorBuilder* machine = jsgraph()->machine(); |
| 1999 CommonOperatorBuilder* common = jsgraph()->common(); | 2004 CommonOperatorBuilder* common = jsgraph()->common(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2032 | 2037 |
| 2033 // We need to create a box for negative 0. | 2038 // We need to create a box for negative 0. |
| 2034 if_smi = graph()->NewNode(common->Merge(2), if_notzero, if_notnegative); | 2039 if_smi = graph()->NewNode(common->Merge(2), if_notzero, if_notnegative); |
| 2035 if_box = graph()->NewNode(common->Merge(2), if_box, if_negative); | 2040 if_box = graph()->NewNode(common->Merge(2), if_box, if_negative); |
| 2036 | 2041 |
| 2037 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit | 2042 // On 64-bit machines we can just wrap the 32-bit integer in a smi, for 32-bit |
| 2038 // machines we need to deal with potential overflow and fallback to boxing. | 2043 // machines we need to deal with potential overflow and fallback to boxing. |
| 2039 if (machine->Is64()) { | 2044 if (machine->Is64()) { |
| 2040 vsmi = BuildChangeInt32ToSmi(value32); | 2045 vsmi = BuildChangeInt32ToSmi(value32); |
| 2041 } else { | 2046 } else { |
| 2042 Node* smi_tag = | 2047 Node* smi_tag = graph()->NewNode(machine->Int32AddWithOverflow(), value32, |
| 2043 graph()->NewNode(machine->Int32AddWithOverflow(), value32, value32); | 2048 value32, if_smi); |
| 2044 | 2049 |
| 2045 Node* check_ovf = graph()->NewNode(common->Projection(1), smi_tag); | 2050 Node* check_ovf = graph()->NewNode(common->Projection(1), smi_tag, if_smi); |
| 2046 Node* branch_ovf = | 2051 Node* branch_ovf = |
| 2047 graph()->NewNode(common->Branch(BranchHint::kFalse), check_ovf, if_smi); | 2052 graph()->NewNode(common->Branch(BranchHint::kFalse), check_ovf, if_smi); |
| 2048 | 2053 |
| 2049 Node* if_ovf = graph()->NewNode(common->IfTrue(), branch_ovf); | 2054 Node* if_ovf = graph()->NewNode(common->IfTrue(), branch_ovf); |
| 2050 if_box = graph()->NewNode(common->Merge(2), if_ovf, if_box); | 2055 if_box = graph()->NewNode(common->Merge(2), if_ovf, if_box); |
| 2051 | 2056 |
| 2052 if_smi = graph()->NewNode(common->IfFalse(), branch_ovf); | 2057 if_smi = graph()->NewNode(common->IfFalse(), branch_ovf); |
| 2053 vsmi = graph()->NewNode(common->Projection(0), smi_tag); | 2058 vsmi = graph()->NewNode(common->Projection(0), smi_tag, if_smi); |
| 2054 } | 2059 } |
| 2055 | 2060 |
| 2056 // Allocate the box for the {value}. | 2061 // Allocate the box for the {value}. |
| 2057 vbox = BuildAllocateHeapNumberWithValue(value, if_box); | 2062 vbox = BuildAllocateHeapNumberWithValue(value, if_box); |
| 2058 | 2063 |
| 2059 Node* control = graph()->NewNode(common->Merge(2), if_smi, if_box); | 2064 Node* control = graph()->NewNode(common->Merge(2), if_smi, if_box); |
| 2060 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi, | 2065 value = graph()->NewNode(common->Phi(MachineRepresentation::kTagged, 2), vsmi, |
| 2061 vbox, control); | 2066 vbox, control); |
| 2062 return value; | 2067 return value; |
| 2063 } | 2068 } |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2376 CallDescriptor* desc = | 2381 CallDescriptor* desc = |
| 2377 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); | 2382 wasm::ModuleEnv::GetWasmCallDescriptor(jsgraph()->zone(), sig); |
| 2378 if (jsgraph()->machine()->Is32()) { | 2383 if (jsgraph()->machine()->Is32()) { |
| 2379 desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc); | 2384 desc = wasm::ModuleEnv::GetI32WasmCallDescriptor(jsgraph()->zone(), desc); |
| 2380 } | 2385 } |
| 2381 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); | 2386 Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), count, args); |
| 2382 Node* retval = call; | 2387 Node* retval = call; |
| 2383 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && | 2388 if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
| 2384 sig->GetReturn(0) == wasm::kAstI64) { | 2389 sig->GetReturn(0) == wasm::kAstI64) { |
| 2385 // The return values comes as two values, we pick the low word. | 2390 // The return values comes as two values, we pick the low word. |
| 2386 retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval); | 2391 retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval, |
| 2392 graph()->start()); |
| 2387 } | 2393 } |
| 2388 Node* jsval = | 2394 Node* jsval = |
| 2389 ToJS(retval, context, | 2395 ToJS(retval, context, |
| 2390 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); | 2396 sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| 2391 Node* ret = | 2397 Node* ret = |
| 2392 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); | 2398 graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
| 2393 | 2399 |
| 2394 MergeControlToEnd(jsgraph(), ret); | 2400 MergeControlToEnd(jsgraph(), ret); |
| 2395 } | 2401 } |
| 2396 | 2402 |
| (...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3264 function_->code_start_offset), | 3270 function_->code_start_offset), |
| 3265 compile_ms); | 3271 compile_ms); |
| 3266 } | 3272 } |
| 3267 | 3273 |
| 3268 return code; | 3274 return code; |
| 3269 } | 3275 } |
| 3270 | 3276 |
| 3271 } // namespace compiler | 3277 } // namespace compiler |
| 3272 } // namespace internal | 3278 } // namespace internal |
| 3273 } // namespace v8 | 3279 } // namespace v8 |
| OLD | NEW |