Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/compiler/wasm-compiler.cc

Issue 1804513002: [wasm] Int64Lowering of I64Div and I64Rem. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serializer-common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 break; 493 break;
494 // todo(ahaas): I added a list of missing instructions here to make merging 494 // todo(ahaas): I added a list of missing instructions here to make merging
495 // easier when I do them one by one. 495 // easier when I do them one by one.
496 // kExprI64Add: 496 // kExprI64Add:
497 case wasm::kExprI64Add: 497 case wasm::kExprI64Add:
498 op = m->Int64Add(); 498 op = m->Int64Add();
499 break; 499 break;
500 // kExprI64Sub: 500 // kExprI64Sub:
501 // kExprI64Mul: 501 // kExprI64Mul:
502 // kExprI64DivS: 502 // kExprI64DivS:
503 case wasm::kExprI64DivS:
504 return BuildI64DivS(left, right);
503 // kExprI64DivU: 505 // kExprI64DivU:
506 case wasm::kExprI64DivU:
507 return BuildI64DivU(left, right);
504 // kExprI64RemS: 508 // kExprI64RemS:
509 case wasm::kExprI64RemS:
510 return BuildI64RemS(left, right);
505 // kExprI64RemU: 511 // kExprI64RemU:
512 case wasm::kExprI64RemU:
513 return BuildI64RemU(left, right);
506 case wasm::kExprI64Ior: 514 case wasm::kExprI64Ior:
507 op = m->Word64Or(); 515 op = m->Word64Or();
508 break; 516 break;
509 // kExprI64Xor: 517 // kExprI64Xor:
510 case wasm::kExprI64Xor: 518 case wasm::kExprI64Xor:
511 op = m->Word64Xor(); 519 op = m->Word64Xor();
512 break; 520 break;
513 // kExprI64Shl: 521 // kExprI64Shl:
514 case wasm::kExprI64Shl: 522 case wasm::kExprI64Shl:
515 op = m->Word64Shl(); 523 op = m->Word64Shl();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 569
562 #if WASM_64 570 #if WASM_64
563 // Opcodes only supported on 64-bit platforms. 571 // Opcodes only supported on 64-bit platforms.
564 // TODO(titzer): query the machine operator builder here instead of #ifdef. 572 // TODO(titzer): query the machine operator builder here instead of #ifdef.
565 case wasm::kExprI64Sub: 573 case wasm::kExprI64Sub:
566 op = m->Int64Sub(); 574 op = m->Int64Sub();
567 break; 575 break;
568 case wasm::kExprI64Mul: 576 case wasm::kExprI64Mul:
569 op = m->Int64Mul(); 577 op = m->Int64Mul();
570 break; 578 break;
571 case wasm::kExprI64DivS: {
572 trap_->ZeroCheck64(kTrapDivByZero, right);
573 Node* before = *control_;
574 Node* denom_is_m1;
575 Node* denom_is_not_m1;
576 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
577 jsgraph()->Int64Constant(-1)),
578 &denom_is_m1, &denom_is_not_m1);
579 *control_ = denom_is_m1;
580 trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
581 std::numeric_limits<int64_t>::min());
582 if (*control_ != denom_is_m1) {
583 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2),
584 denom_is_not_m1, *control_);
585 } else {
586 *control_ = before;
587 }
588 return graph()->NewNode(m->Int64Div(), left, right, *control_);
589 }
590 case wasm::kExprI64DivU:
591 op = m->Uint64Div();
592 return graph()->NewNode(op, left, right,
593 trap_->ZeroCheck64(kTrapDivByZero, right));
594 case wasm::kExprI64RemS: {
595 trap_->ZeroCheck64(kTrapRemByZero, right);
596 Diamond d(jsgraph()->graph(), jsgraph()->common(),
597 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
598 jsgraph()->Int64Constant(-1)));
599
600 Node* rem = graph()->NewNode(m->Int64Mod(), left, right, d.if_false);
601
602 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
603 rem);
604 }
605 case wasm::kExprI64RemU:
606 op = m->Uint64Mod();
607 return graph()->NewNode(op, left, right,
608 trap_->ZeroCheck64(kTrapRemByZero, right));
609 case wasm::kExprI64Ror: 579 case wasm::kExprI64Ror:
610 op = m->Word64Ror(); 580 op = m->Word64Ror();
611 break; 581 break;
612 case wasm::kExprI64Rol: 582 case wasm::kExprI64Rol:
613 return BuildI64Rol(left, right); 583 return BuildI64Rol(left, right);
614 #endif 584 #endif
615 585
616 case wasm::kExprF32CopySign: 586 case wasm::kExprF32CopySign:
617 return BuildF32CopySign(left, right); 587 return BuildF32CopySign(left, right);
618 case wasm::kExprF64CopySign: 588 case wasm::kExprF64CopySign:
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1767 trap_->ZeroCheck32(kTrapFloatUnrepresentable, 1737 trap_->ZeroCheck32(kTrapFloatUnrepresentable,
1768 BuildCCall(sig_builder.Build(), args)); 1738 BuildCCall(sig_builder.Build(), args));
1769 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1739 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1770 Node* load = 1740 Node* load =
1771 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1741 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1772 *effect_, *control_); 1742 *effect_, *control_);
1773 *effect_ = load; 1743 *effect_ = load;
1774 return load; 1744 return load;
1775 } 1745 }
1776 1746
1747 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) {
1748 if (jsgraph()->machine()->Is32()) {
1749 return BuildDiv64Call(
1750 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()),
1751 MachineType::Int64(), kTrapDivByZero);
1752 }
1753 trap_->ZeroCheck64(kTrapDivByZero, right);
1754 Node* before = *control_;
1755 Node* denom_is_m1;
1756 Node* denom_is_not_m1;
1757 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1758 jsgraph()->Int64Constant(-1)),
1759 &denom_is_m1, &denom_is_not_m1);
1760 *control_ = denom_is_m1;
1761 trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
1762 std::numeric_limits<int64_t>::min());
1763 if (*control_ != denom_is_m1) {
1764 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1,
1765 *control_);
1766 } else {
1767 *control_ = before;
1768 }
1769 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right,
1770 *control_);
1771 }
1772
1773 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) {
1774 if (jsgraph()->machine()->Is32()) {
1775 return BuildDiv64Call(
1776 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()),
1777 MachineType::Int64(), kTrapRemByZero);
1778 }
1779 trap_->ZeroCheck64(kTrapRemByZero, right);
1780 Diamond d(jsgraph()->graph(), jsgraph()->common(),
1781 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1782 jsgraph()->Int64Constant(-1)));
1783
1784 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right,
1785 d.if_false);
1786
1787 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
1788 rem);
1789 }
1790
1791 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) {
1792 if (jsgraph()->machine()->Is32()) {
1793 return BuildDiv64Call(
1794 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()),
1795 MachineType::Int64(), kTrapDivByZero);
1796 }
1797 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right,
1798 trap_->ZeroCheck64(kTrapDivByZero, right));
1799 }
1800 Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) {
1801 if (jsgraph()->machine()->Is32()) {
1802 return BuildDiv64Call(
1803 left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()),
1804 MachineType::Int64(), kTrapRemByZero);
1805 }
1806 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right,
1807 trap_->ZeroCheck64(kTrapRemByZero, right));
1808 }
1809
1810 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
1811 ExternalReference ref,
1812 MachineType result_type, int trap_zero) {
1813 Node* stack_slot_dst = graph()->NewNode(
1814 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1815 Node* stack_slot_src = graph()->NewNode(
1816 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1817
1818 const Operator* store_op = jsgraph()->machine()->Store(
1819 StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier));
1820 *effect_ =
1821 graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1822 left, *effect_, *control_);
1823 *effect_ =
1824 graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0),
1825 right, *effect_, *control_);
1826
1827 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
1828 sig_builder.AddReturn(MachineType::Int32());
1829 sig_builder.AddParam(MachineType::Pointer());
1830 sig_builder.AddParam(MachineType::Pointer());
1831
1832 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1833 Node* args[] = {function, stack_slot_dst, stack_slot_src};
1834
1835 Node* call = BuildCCall(sig_builder.Build(), args);
1836
1837 // TODO(wasm): This can get simpler if we have a specialized runtime call to
1838 // throw WASM exceptions by trap code instead of by string.
1839 trap_->ZeroCheck32(static_cast<TrapReason>(trap_zero), call);
1840 trap_->TrapIfEq32(kTrapDivUnrepresentable, call, -1);
1841 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1842 Node* load =
1843 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1844 *effect_, *control_);
1845 *effect_ = load;
1846 return load;
1847 }
1848
1777 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1849 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1778 const size_t params = sig->parameter_count(); 1850 const size_t params = sig->parameter_count();
1779 const size_t extra = 2; // effect and control inputs. 1851 const size_t extra = 2; // effect and control inputs.
1780 const size_t count = 1 + params + extra; 1852 const size_t count = 1 + params + extra;
1781 1853
1782 // Reallocate the buffer to make space for extra inputs. 1854 // Reallocate the buffer to make space for extra inputs.
1783 args = Realloc(args, count); 1855 args = Realloc(args, count);
1784 1856
1785 // Add effect and control inputs. 1857 // Add effect and control inputs.
1786 args[params + 1] = *effect_; 1858 args[params + 1] = *effect_;
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2575 static_cast<int>(function.code_end_offset - function.code_start_offset), 2647 static_cast<int>(function.code_end_offset - function.code_start_offset),
2576 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms); 2648 decode_ms, static_cast<int>(graph.NodeCount()), compile_ms);
2577 } 2649 }
2578 return code; 2650 return code;
2579 } 2651 }
2580 2652
2581 2653
2582 } // namespace compiler 2654 } // namespace compiler
2583 } // namespace internal 2655 } // namespace internal
2584 } // namespace v8 2656 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/snapshot/serializer-common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698