| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/simplified-operator.h" | 5 #include "src/compiler/simplified-operator.h" |
| 6 | 6 |
| 7 #include "src/base/lazy-instance.h" | 7 #include "src/base/lazy-instance.h" |
| 8 #include "src/compiler/opcodes.h" | 8 #include "src/compiler/opcodes.h" |
| 9 #include "src/compiler/operator.h" | 9 #include "src/compiler/operator.h" |
| 10 #include "src/types-inl.h" | 10 #include "src/types-inl.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 name->Print(os); | 50 name->Print(os); |
| 51 os << ", "; | 51 os << ", "; |
| 52 } | 52 } |
| 53 #endif | 53 #endif |
| 54 access.type->PrintTo(os); | 54 access.type->PrintTo(os); |
| 55 os << ", " << access.machine_type << "]"; | 55 os << ", " << access.machine_type << "]"; |
| 56 return os; | 56 return os; |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 std::ostream& operator<<(std::ostream& os, BoundsCheckMode bounds_check_mode) { | 60 const FieldAccess& FieldAccessOf(const Operator* op) { |
| 61 switch (bounds_check_mode) { | 61 DCHECK_NOT_NULL(op); |
| 62 case kNoBoundsCheck: | 62 DCHECK(op->opcode() == IrOpcode::kLoadField || |
| 63 return os << "no bounds check"; | 63 op->opcode() == IrOpcode::kStoreField); |
| 64 case kTypedArrayBoundsCheck: | 64 return OpParameter<FieldAccess>(op); |
| 65 return os << "ignore out of bounds"; | |
| 66 } | |
| 67 UNREACHABLE(); | |
| 68 return os; | |
| 69 } | 65 } |
| 70 | 66 |
| 71 | 67 |
| 72 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { | 68 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) { |
| 73 return lhs.base_is_tagged == rhs.base_is_tagged && | 69 return lhs.base_is_tagged == rhs.base_is_tagged && |
| 74 lhs.header_size == rhs.header_size && | 70 lhs.header_size == rhs.header_size && |
| 75 lhs.machine_type == rhs.machine_type; | 71 lhs.machine_type == rhs.machine_type; |
| 76 } | 72 } |
| 77 | 73 |
| 78 | 74 |
| 79 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) { | 75 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) { |
| 80 return !(lhs == rhs); | 76 return !(lhs == rhs); |
| 81 } | 77 } |
| 82 | 78 |
| 83 | 79 |
| 84 size_t hash_value(ElementAccess const& access) { | 80 size_t hash_value(ElementAccess const& access) { |
| 85 return base::hash_combine(access.base_is_tagged, access.header_size, | 81 return base::hash_combine(access.base_is_tagged, access.header_size, |
| 86 access.machine_type); | 82 access.machine_type); |
| 87 } | 83 } |
| 88 | 84 |
| 89 | 85 |
| 90 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { | 86 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) { |
| 91 os << access.base_is_tagged << ", " << access.header_size << ", "; | 87 os << access.base_is_tagged << ", " << access.header_size << ", "; |
| 92 access.type->PrintTo(os); | 88 access.type->PrintTo(os); |
| 93 os << ", " << access.machine_type << ", " << access.bounds_check; | 89 os << ", " << access.machine_type; |
| 94 return os; | 90 return os; |
| 95 } | 91 } |
| 96 | 92 |
| 97 | 93 |
| 98 const FieldAccess& FieldAccessOf(const Operator* op) { | |
| 99 DCHECK_NOT_NULL(op); | |
| 100 DCHECK(op->opcode() == IrOpcode::kLoadField || | |
| 101 op->opcode() == IrOpcode::kStoreField); | |
| 102 return OpParameter<FieldAccess>(op); | |
| 103 } | |
| 104 | |
| 105 | |
| 106 const ElementAccess& ElementAccessOf(const Operator* op) { | 94 const ElementAccess& ElementAccessOf(const Operator* op) { |
| 107 DCHECK_NOT_NULL(op); | 95 DCHECK_NOT_NULL(op); |
| 108 DCHECK(op->opcode() == IrOpcode::kLoadElement || | 96 DCHECK(op->opcode() == IrOpcode::kLoadElement || |
| 109 op->opcode() == IrOpcode::kStoreElement); | 97 op->opcode() == IrOpcode::kStoreElement); |
| 110 return OpParameter<ElementAccess>(op); | 98 return OpParameter<ElementAccess>(op); |
| 111 } | 99 } |
| 112 | 100 |
| 113 | 101 |
| 102 MachineType BufferAccess::machine_type() const { |
| 103 switch (external_array_type()) { |
| 104 case kExternalInt8Array: |
| 105 return kMachInt8; |
| 106 case kExternalUint8Array: |
| 107 case kExternalUint8ClampedArray: |
| 108 return kMachUint8; |
| 109 case kExternalInt16Array: |
| 110 return kMachInt16; |
| 111 case kExternalUint16Array: |
| 112 return kMachUint16; |
| 113 case kExternalInt32Array: |
| 114 return kMachInt32; |
| 115 case kExternalUint32Array: |
| 116 return kMachUint32; |
| 117 case kExternalFloat32Array: |
| 118 return kMachFloat32; |
| 119 case kExternalFloat64Array: |
| 120 return kMachFloat64; |
| 121 } |
| 122 UNREACHABLE(); |
| 123 return kMachNone; |
| 124 } |
| 125 |
| 126 |
| 127 bool operator==(BufferAccess const& lhs, BufferAccess const& rhs) { |
| 128 return lhs.external_array_type() == rhs.external_array_type() && |
| 129 lhs.guard_size() == rhs.guard_size(); |
| 130 } |
| 131 |
| 132 |
| 133 bool operator!=(BufferAccess const& lhs, BufferAccess const& rhs) { |
| 134 return !(lhs == rhs); |
| 135 } |
| 136 |
| 137 |
| 138 size_t hash_value(BufferAccess const& access) { |
| 139 return base::hash_combine(access.external_array_type(), access.guard_size()); |
| 140 } |
| 141 |
| 142 |
| 143 std::ostream& operator<<(std::ostream& os, BufferAccess const& access) { |
| 144 switch (access.external_array_type()) { |
| 145 #define CASE(Type, type, TYPE, c_type, element_size) \ |
| 146 case kExternal##Type##Array: \ |
| 147 os << #Type; \ |
| 148 break; |
| 149 TYPED_ARRAYS(CASE) |
| 150 #undef CASE |
| 151 } |
| 152 if (access.guard_size()) { |
| 153 os << "#" << access.guard_size(); |
| 154 } |
| 155 return os; |
| 156 } |
| 157 |
| 158 |
| 159 BufferAccess const& BufferAccessOf(const Operator* op) { |
| 160 DCHECK(op->opcode() == IrOpcode::kLoadBuffer || |
| 161 op->opcode() == IrOpcode::kStoreBuffer); |
| 162 return OpParameter<BufferAccess>(op); |
| 163 } |
| 164 |
| 165 |
| 114 #define PURE_OP_LIST(V) \ | 166 #define PURE_OP_LIST(V) \ |
| 115 V(BooleanNot, Operator::kNoProperties, 1) \ | 167 V(BooleanNot, Operator::kNoProperties, 1) \ |
| 116 V(BooleanToNumber, Operator::kNoProperties, 1) \ | 168 V(BooleanToNumber, Operator::kNoProperties, 1) \ |
| 117 V(NumberEqual, Operator::kCommutative, 2) \ | 169 V(NumberEqual, Operator::kCommutative, 2) \ |
| 118 V(NumberLessThan, Operator::kNoProperties, 2) \ | 170 V(NumberLessThan, Operator::kNoProperties, 2) \ |
| 119 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ | 171 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ |
| 120 V(NumberAdd, Operator::kCommutative, 2) \ | 172 V(NumberAdd, Operator::kCommutative, 2) \ |
| 121 V(NumberSubtract, Operator::kNoProperties, 2) \ | 173 V(NumberSubtract, Operator::kNoProperties, 2) \ |
| 122 V(NumberMultiply, Operator::kCommutative, 2) \ | 174 V(NumberMultiply, Operator::kCommutative, 2) \ |
| 123 V(NumberDivide, Operator::kNoProperties, 2) \ | 175 V(NumberDivide, Operator::kNoProperties, 2) \ |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 // TODO(titzer): What about the type parameter? | 223 // TODO(titzer): What about the type parameter? |
| 172 return new (zone()) Operator(IrOpcode::kReferenceEqual, | 224 return new (zone()) Operator(IrOpcode::kReferenceEqual, |
| 173 Operator::kCommutative | Operator::kPure, | 225 Operator::kCommutative | Operator::kPure, |
| 174 "ReferenceEqual", 2, 0, 0, 1, 0, 0); | 226 "ReferenceEqual", 2, 0, 0, 1, 0, 0); |
| 175 } | 227 } |
| 176 | 228 |
| 177 | 229 |
| 178 #define ACCESS_OP_LIST(V) \ | 230 #define ACCESS_OP_LIST(V) \ |
| 179 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 231 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
| 180 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 232 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
| 181 V(LoadElement, ElementAccess, Operator::kNoWrite, 3, 0, 1) \ | 233 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
| 182 V(StoreElement, ElementAccess, Operator::kNoRead, 4, 1, 0) | 234 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ |
| 235 V(LoadBuffer, BufferAccess, Operator::kNoWrite, 3, 1, 1) \ |
| 236 V(StoreBuffer, BufferAccess, Operator::kNoRead, 4, 1, 0) |
| 183 | 237 |
| 184 | 238 |
| 185 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 239 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
| 186 output_count) \ | 240 output_count) \ |
| 187 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 241 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
| 188 return new (zone()) \ | 242 return new (zone()) \ |
| 189 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ | 243 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ |
| 190 #Name, value_input_count, 1, control_input_count, \ | 244 #Name, value_input_count, 1, control_input_count, \ |
| 191 output_count, 1, 0, access); \ | 245 output_count, 1, 0, access); \ |
| 192 } | 246 } |
| 193 ACCESS_OP_LIST(ACCESS) | 247 ACCESS_OP_LIST(ACCESS) |
| 194 #undef ACCESS | 248 #undef ACCESS |
| 195 | 249 |
| 250 |
| 251 const Operator* SimplifiedOperatorBuilder::BoundsCheck(size_t guard) { |
| 252 return new (zone()) Operator1<size_t>(IrOpcode::kBoundsCheck, Operator::kPure, |
| 253 "BoundsCheck", 2, 0, 0, 1, 0, 0, guard); |
| 254 } |
| 255 |
| 196 } // namespace compiler | 256 } // namespace compiler |
| 197 } // namespace internal | 257 } // namespace internal |
| 198 } // namespace v8 | 258 } // namespace v8 |
| OLD | NEW |