| 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/machine-operator-reducer.h" | 5 #include "src/compiler/machine-operator-reducer.h" |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/compiler/diamond.h" | 10 #include "src/compiler/diamond.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 // (x + K) & K => (x & K) + K | 145 // (x + K) & K => (x & K) + K |
| 146 return Replace(graph()->NewNode( | 146 return Replace(graph()->NewNode( |
| 147 machine()->Int32Add(), | 147 machine()->Int32Add(), |
| 148 graph()->NewNode(machine()->Word32And(), mleft.left().node(), | 148 graph()->NewNode(machine()->Word32And(), mleft.left().node(), |
| 149 m.right().node()), | 149 m.right().node()), |
| 150 mleft.right().node())); | 150 mleft.right().node())); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 break; | 153 break; |
| 154 } | 154 } |
| 155 case IrOpcode::kWord32Or: { | 155 case IrOpcode::kWord32Or: |
| 156 Int32BinopMatcher m(node); | 156 return ReduceWord32Or(node); |
| 157 if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x | |
| 158 if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1 | |
| 159 if (m.IsFoldable()) { // K | K => K | |
| 160 return ReplaceInt32(m.left().Value() | m.right().Value()); | |
| 161 } | |
| 162 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x | |
| 163 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { | |
| 164 Int32BinopMatcher mleft(m.left().node()); | |
| 165 Int32BinopMatcher mright(m.right().node()); | |
| 166 if (mleft.left().node() == mright.left().node()) { | |
| 167 // TODO(turbofan): here we are matching rotate left, shall we add | |
| 168 // support for rotate right? | |
| 169 // (x << y) | (x >>> (32 - y)) => x ror (32 - y) | |
| 170 if (mright.right().IsInt32Sub()) { | |
| 171 Int32BinopMatcher mrightright(mright.right().node()); | |
| 172 if (mrightright.left().Is(32) && | |
| 173 mrightright.right().node() == mleft.right().node()) { | |
| 174 node->set_op(machine()->Word32Ror()); | |
| 175 node->ReplaceInput(0, mleft.left().node()); | |
| 176 node->ReplaceInput(1, mright.right().node()); | |
| 177 return Changed(node); | |
| 178 } | |
| 179 } | |
| 180 // (x << K) | (x >>> (32 - K)) => x ror (32 - K) | |
| 181 if (mleft.right().IsInRange(0, 31) && | |
| 182 mright.right().Is(32 - mleft.right().Value())) { | |
| 183 node->set_op(machine()->Word32Ror()); | |
| 184 node->ReplaceInput(0, mleft.left().node()); | |
| 185 node->ReplaceInput(1, mright.right().node()); | |
| 186 return Changed(node); | |
| 187 } | |
| 188 } | |
| 189 } | |
| 190 if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { | |
| 191 // (x >>> (32 - y)) | (x << y) => x ror (32 -y) | |
| 192 Int32BinopMatcher mleft(m.left().node()); | |
| 193 Int32BinopMatcher mright(m.right().node()); | |
| 194 if (mleft.left().node() == mright.left().node()) { | |
| 195 if (mleft.right().IsInt32Sub()) { | |
| 196 Int32BinopMatcher mleftright(mleft.right().node()); | |
| 197 if (mleftright.left().Is(32) && | |
| 198 mleftright.right().node() == mright.right().node()) { | |
| 199 node->set_op(machine()->Word32Ror()); | |
| 200 node->ReplaceInput(0, mright.left().node()); | |
| 201 node->ReplaceInput(1, mleft.right().node()); | |
| 202 return Changed(node); | |
| 203 } | |
| 204 } | |
| 205 // (x >>> (32 - K)) | (x << K) => x ror (32 - K) | |
| 206 if (mright.right().IsInRange(0, 31) && | |
| 207 mleft.right().Is(32 - mright.right().Value())) { | |
| 208 node->set_op(machine()->Word32Ror()); | |
| 209 node->ReplaceInput(0, mright.left().node()); | |
| 210 node->ReplaceInput(1, mleft.right().node()); | |
| 211 return Changed(node); | |
| 212 } | |
| 213 } | |
| 214 } | |
| 215 break; | |
| 216 } | |
| 217 case IrOpcode::kWord32Xor: { | 157 case IrOpcode::kWord32Xor: { |
| 218 Int32BinopMatcher m(node); | 158 Int32BinopMatcher m(node); |
| 219 if (m.right().Is(0)) return Replace(m.left().node()); // x ^ 0 => x | 159 if (m.right().Is(0)) return Replace(m.left().node()); // x ^ 0 => x |
| 220 if (m.IsFoldable()) { // K ^ K => K | 160 if (m.IsFoldable()) { // K ^ K => K |
| 221 return ReplaceInt32(m.left().Value() ^ m.right().Value()); | 161 return ReplaceInt32(m.left().Value() ^ m.right().Value()); |
| 222 } | 162 } |
| 223 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x ^ x => 0 | 163 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x ^ x => 0 |
| 224 if (m.left().IsWord32Xor() && m.right().Is(-1)) { | 164 if (m.left().IsWord32Xor() && m.right().Is(-1)) { |
| 225 Int32BinopMatcher mleft(m.left().node()); | 165 Int32BinopMatcher mleft(m.left().node()); |
| 226 if (mleft.right().Is(-1)) { // (x ^ -1) ^ -1 => x | 166 if (mleft.right().Is(-1)) { // (x ^ -1) ^ -1 => x |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 if (mright.right().Is(0x1f)) { | 774 if (mright.right().Is(0x1f)) { |
| 835 node->ReplaceInput(1, mright.left().node()); | 775 node->ReplaceInput(1, mright.left().node()); |
| 836 return Changed(node); | 776 return Changed(node); |
| 837 } | 777 } |
| 838 } | 778 } |
| 839 } | 779 } |
| 840 return NoChange(); | 780 return NoChange(); |
| 841 } | 781 } |
| 842 | 782 |
| 843 | 783 |
| 784 Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) { |
| 785 DCHECK(node->opcode() == IrOpcode::kWord32Or); |
| 786 |
| 787 Int32BinopMatcher m(node); |
| 788 if (m.right().Is(0)) return Replace(m.left().node()); // x | 0 => x |
| 789 if (m.right().Is(-1)) return Replace(m.right().node()); // x | -1 => -1 |
| 790 if (m.IsFoldable()) { // K | K => K |
| 791 return ReplaceInt32(m.left().Value() | m.right().Value()); |
| 792 } |
| 793 if (m.LeftEqualsRight()) return Replace(m.left().node()); // x | x => x |
| 794 |
| 795 Node* shl = NULL; |
| 796 Node* shr = NULL; |
| 797 // Recognize rotation, we are matching either: |
| 798 // * x << y | x >>> (32 - y) => x ror (32 - y), i.e x rol y |
| 799 // * x << (32 - y) | x >>> y => x ror y |
| 800 // as well as their commuted form. |
| 801 if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) { |
| 802 shl = m.left().node(); |
| 803 shr = m.right().node(); |
| 804 } else if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) { |
| 805 shl = m.right().node(); |
| 806 shr = m.left().node(); |
| 807 } else { |
| 808 return NoChange(); |
| 809 } |
| 810 |
| 811 Int32BinopMatcher mshl(shl); |
| 812 Int32BinopMatcher mshr(shr); |
| 813 if (mshl.left().node() != mshr.left().node()) return NoChange(); |
| 814 |
| 815 if (mshl.right().HasValue() && mshr.right().HasValue()) { |
| 816 // Case where y is a constant. |
| 817 if (mshl.right().Value() + mshr.right().Value() != 32) return NoChange(); |
| 818 } else { |
| 819 Node* sub = NULL; |
| 820 Node* y = NULL; |
| 821 if (mshl.right().IsInt32Sub()) { |
| 822 sub = mshl.right().node(); |
| 823 y = mshr.right().node(); |
| 824 } else if (mshr.right().IsInt32Sub()) { |
| 825 sub = mshr.right().node(); |
| 826 y = mshl.right().node(); |
| 827 } else { |
| 828 return NoChange(); |
| 829 } |
| 830 |
| 831 Int32BinopMatcher msub(sub); |
| 832 if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); |
| 833 } |
| 834 |
| 835 node->set_op(machine()->Word32Ror()); |
| 836 node->ReplaceInput(0, mshl.left().node()); |
| 837 node->ReplaceInput(1, mshr.right().node()); |
| 838 return Changed(node); |
| 839 } |
| 840 |
| 841 |
| 844 CommonOperatorBuilder* MachineOperatorReducer::common() const { | 842 CommonOperatorBuilder* MachineOperatorReducer::common() const { |
| 845 return jsgraph()->common(); | 843 return jsgraph()->common(); |
| 846 } | 844 } |
| 847 | 845 |
| 848 | 846 |
| 849 MachineOperatorBuilder* MachineOperatorReducer::machine() const { | 847 MachineOperatorBuilder* MachineOperatorReducer::machine() const { |
| 850 return jsgraph()->machine(); | 848 return jsgraph()->machine(); |
| 851 } | 849 } |
| 852 | 850 |
| 853 | 851 |
| 854 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } | 852 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } |
| 855 | 853 |
| 856 } // namespace compiler | 854 } // namespace compiler |
| 857 } // namespace internal | 855 } // namespace internal |
| 858 } // namespace v8 | 856 } // namespace v8 |
| OLD | NEW |