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 |