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

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: 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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 break; 490 break;
491 case wasm::kExprI64And: 491 case wasm::kExprI64And:
492 op = m->Word64And(); 492 op = m->Word64And();
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 // kExprI64Sub: 497 // kExprI64Sub:
498 // kExprI64Mul: 498 // kExprI64Mul:
499 // kExprI64DivS: 499 // kExprI64DivS:
500 case wasm::kExprI64DivS:
501 return BuildI64DivS(left, right);
500 // kExprI64DivU: 502 // kExprI64DivU:
503 case wasm::kExprI64DivU:
504 return BuildI64DivU(left, right);
501 // kExprI64RemS: 505 // kExprI64RemS:
506 case wasm::kExprI64RemS:
507 return BuildI64RemS(left, right);
502 // kExprI64RemU: 508 // kExprI64RemU:
509 case wasm::kExprI64RemU:
510 return BuildI64RemU(left, right);
503 case wasm::kExprI64Ior: 511 case wasm::kExprI64Ior:
504 op = m->Word64Or(); 512 op = m->Word64Or();
505 break; 513 break;
506 // kExprI64Xor: 514 // kExprI64Xor:
507 case wasm::kExprI64Xor: 515 case wasm::kExprI64Xor:
508 op = m->Word64Xor(); 516 op = m->Word64Xor();
509 break; 517 break;
510 // kExprI64Shl: 518 // kExprI64Shl:
511 case wasm::kExprI64Shl: 519 case wasm::kExprI64Shl:
512 op = m->Word64Shl(); 520 op = m->Word64Shl();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 // TODO(titzer): query the machine operator builder here instead of #ifdef. 569 // TODO(titzer): query the machine operator builder here instead of #ifdef.
562 case wasm::kExprI64Add: 570 case wasm::kExprI64Add:
563 op = m->Int64Add(); 571 op = m->Int64Add();
564 break; 572 break;
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 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1764 trap_->ZeroCheck32(kTrapFloatUnrepresentable, 1734 trap_->ZeroCheck32(kTrapFloatUnrepresentable,
1765 BuildCCall(sig_builder.Build(), args)); 1735 BuildCCall(sig_builder.Build(), args));
1766 const Operator* load_op = jsgraph()->machine()->Load(result_type); 1736 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1767 Node* load = 1737 Node* load =
1768 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), 1738 graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0),
1769 *effect_, *control_); 1739 *effect_, *control_);
1770 *effect_ = load; 1740 *effect_ = load;
1771 return load; 1741 return load;
1772 } 1742 }
1773 1743
1744 Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) {
1745 if (jsgraph()->machine()->Is32()) {
1746 return BuildDiv64Call(
1747 left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()),
1748 MachineType::Int64(), kTrapDivByZero);
1749 } else {
1750 trap_->ZeroCheck64(kTrapDivByZero, right);
titzer 2016/03/14 11:03:22 Style nit: leave the else clause unnested.
ahaas 2016/03/14 12:38:12 Done.
1751 Node* before = *control_;
1752 Node* denom_is_m1;
1753 Node* denom_is_not_m1;
1754 Branch(graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1755 jsgraph()->Int64Constant(-1)),
1756 &denom_is_m1, &denom_is_not_m1);
1757 *control_ = denom_is_m1;
1758 trap_->TrapIfEq64(kTrapDivUnrepresentable, left,
1759 std::numeric_limits<int64_t>::min());
1760 if (*control_ != denom_is_m1) {
1761 *control_ = graph()->NewNode(jsgraph()->common()->Merge(2),
1762 denom_is_not_m1, *control_);
1763 } else {
1764 *control_ = before;
1765 }
1766 return graph()->NewNode(jsgraph()->machine()->Int64Div(), left, right,
1767 *control_);
1768 }
1769 }
1770
1771 Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) {
1772 if (jsgraph()->machine()->Is32()) {
1773 return BuildDiv64Call(
1774 left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()),
1775 MachineType::Int64(), kTrapRemByZero);
1776 } else {
1777 trap_->ZeroCheck64(kTrapRemByZero, right);
1778 Diamond d(jsgraph()->graph(), jsgraph()->common(),
1779 graph()->NewNode(jsgraph()->machine()->Word64Equal(), right,
1780 jsgraph()->Int64Constant(-1)));
1781
1782 Node* rem = graph()->NewNode(jsgraph()->machine()->Int64Mod(), left, right,
1783 d.if_false);
1784
1785 return d.Phi(MachineRepresentation::kWord64, jsgraph()->Int64Constant(0),
1786 rem);
1787 }
1788 }
1789
1790 Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) {
1791 if (jsgraph()->machine()->Is32()) {
1792 return BuildDiv64Call(
1793 left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()),
1794 MachineType::Int64(), kTrapDivByZero);
1795 } else {
1796 return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right,
1797 trap_->ZeroCheck64(kTrapDivByZero, right));
1798 }
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 } else {
1806 return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right,
1807 trap_->ZeroCheck64(kTrapRemByZero, right));
1808 }
1809 }
1810
1811 Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right,
1812 ExternalReference ref,
1813 MachineType result_type, int trap_zero) {
1814 Node* stack_slot_dst = graph()->NewNode(
1815 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1816 Node* stack_slot_src = graph()->NewNode(
1817 jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64));
1818
1819 const Operator* store_op = jsgraph()->machine()->Store(
1820 StoreRepresentation(MachineRepresentation::kWord64, kNoWriteBarrier));
1821 *effect_ =
1822 graph()->NewNode(store_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1823 left, *effect_, *control_);
1824 *effect_ =
1825 graph()->NewNode(store_op, stack_slot_src, jsgraph()->Int32Constant(0),
1826 right, *effect_, *control_);
1827
1828 MachineSignature::Builder sig_builder(jsgraph()->zone(), 1, 2);
1829 sig_builder.AddReturn(MachineType::Int32());
1830 sig_builder.AddParam(MachineType::Pointer());
1831 sig_builder.AddParam(MachineType::Pointer());
1832
1833 Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref));
1834 Node* args[] = {function, stack_slot_dst, stack_slot_src};
1835
1836 Node* call = BuildCCall(sig_builder.Build(), args);
1837 trap_->ZeroCheck32(static_cast<TrapReason>(trap_zero), call);
titzer 2016/03/14 11:03:22 Can you leave a TODO here? This can get simpler if
ahaas 2016/03/14 12:38:12 Done.
1838 trap_->TrapIfEq32(kTrapDivUnrepresentable, call, -1);
1839 const Operator* load_op = jsgraph()->machine()->Load(result_type);
1840 Node* load =
1841 graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0),
1842 *effect_, *control_);
1843 *effect_ = load;
1844 return load;
1845 }
1846
1774 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { 1847 Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) {
1775 const size_t params = sig->parameter_count(); 1848 const size_t params = sig->parameter_count();
1776 const size_t extra = 2; // effect and control inputs. 1849 const size_t extra = 2; // effect and control inputs.
1777 const size_t count = 1 + params + extra; 1850 const size_t count = 1 + params + extra;
1778 1851
1779 // Reallocate the buffer to make space for extra inputs. 1852 // Reallocate the buffer to make space for extra inputs.
1780 args = Realloc(args, count); 1853 args = Realloc(args, count);
1781 1854
1782 // Add effect and control inputs. 1855 // Add effect and control inputs.
1783 args[params + 1] = *effect_; 1856 args[params + 1] = *effect_;
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2571 static_cast<int>(function.code_end_offset - function.code_start_offset), 2644 static_cast<int>(function.code_end_offset - function.code_start_offset),
2572 decode_ms, compile_ms); 2645 decode_ms, compile_ms);
2573 } 2646 }
2574 return code; 2647 return code;
2575 } 2648 }
2576 2649
2577 2650
2578 } // namespace compiler 2651 } // namespace compiler
2579 } // namespace internal 2652 } // namespace internal
2580 } // namespace v8 2653 } // 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