| 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 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 5 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
| 6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
| 7 | 7 |
| 8 #include "src/compiler/machine-operator.h" | 8 #include "src/compiler/machine-type.h" |
| 9 #include "src/compiler/opcodes.h" | |
| 10 #include "src/compiler/operator.h" | |
| 11 #include "src/handles.h" | 9 #include "src/handles.h" |
| 12 #include "src/zone.h" | |
| 13 | 10 |
| 14 namespace v8 { | 11 namespace v8 { |
| 15 namespace internal { | 12 namespace internal { |
| 16 | 13 |
| 17 // Forward declarations. | 14 // Forward declarations. |
| 18 template <class> | 15 template <class> |
| 19 class TypeImpl; | 16 class TypeImpl; |
| 20 struct ZoneTypeConfig; | 17 struct ZoneTypeConfig; |
| 21 typedef TypeImpl<ZoneTypeConfig> Type; | 18 typedef TypeImpl<ZoneTypeConfig> Type; |
| 19 class Zone; |
| 22 | 20 |
| 23 | 21 |
| 24 namespace compiler { | 22 namespace compiler { |
| 25 | 23 |
| 24 // Forward declarations. |
| 25 class Operator; |
| 26 struct SimplifiedOperatorBuilderImpl; |
| 27 |
| 28 |
| 26 enum BaseTaggedness { kUntaggedBase, kTaggedBase }; | 29 enum BaseTaggedness { kUntaggedBase, kTaggedBase }; |
| 27 | 30 |
| 28 // An access descriptor for loads/stores of fixed structures like field | 31 // An access descriptor for loads/stores of fixed structures like field |
| 29 // accesses of heap objects. Accesses from either tagged or untagged base | 32 // accesses of heap objects. Accesses from either tagged or untagged base |
| 30 // pointers are supported; untagging is done automatically during lowering. | 33 // pointers are supported; untagging is done automatically during lowering. |
| 31 struct FieldAccess { | 34 struct FieldAccess { |
| 32 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. | 35 BaseTaggedness base_is_tagged; // specifies if the base pointer is tagged. |
| 33 int offset; // offset of the field, without tag. | 36 int offset; // offset of the field, without tag. |
| 34 Handle<Name> name; // debugging only. | 37 Handle<Name> name; // debugging only. |
| 35 Type* type; // type of the field. | 38 Type* type; // type of the field. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 50 MachineType machine_type; // machine type of the element. | 53 MachineType machine_type; // machine type of the element. |
| 51 | 54 |
| 52 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } | 55 int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; } |
| 53 }; | 56 }; |
| 54 | 57 |
| 55 | 58 |
| 56 // If the accessed object is not a heap object, add this to the header_size. | 59 // If the accessed object is not a heap object, add this to the header_size. |
| 57 static const int kNonHeapObjectHeaderSize = kHeapObjectTag; | 60 static const int kNonHeapObjectHeaderSize = kHeapObjectTag; |
| 58 | 61 |
| 59 | 62 |
| 60 // Specialization for static parameters of type {FieldAccess}. | 63 const FieldAccess& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT; |
| 61 template <> | 64 const ElementAccess& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT; |
| 62 struct StaticParameterTraits<FieldAccess> { | |
| 63 static OStream& PrintTo(OStream& os, const FieldAccess& val) { // NOLINT | |
| 64 return os << val.offset; | |
| 65 } | |
| 66 static int HashCode(const FieldAccess& val) { | |
| 67 return (val.offset < 16) | (val.machine_type & 0xffff); | |
| 68 } | |
| 69 static bool Equals(const FieldAccess& lhs, const FieldAccess& rhs); | |
| 70 }; | |
| 71 | |
| 72 | |
| 73 // Specialization for static parameters of type {ElementAccess}. | |
| 74 template <> | |
| 75 struct StaticParameterTraits<ElementAccess> { | |
| 76 static OStream& PrintTo(OStream& os, const ElementAccess& val) { // NOLINT | |
| 77 return os << val.header_size; | |
| 78 } | |
| 79 static int HashCode(const ElementAccess& val) { | |
| 80 return (val.header_size < 16) | (val.machine_type & 0xffff); | |
| 81 } | |
| 82 static bool Equals(const ElementAccess& lhs, const ElementAccess& rhs); | |
| 83 }; | |
| 84 | |
| 85 | |
| 86 inline const FieldAccess FieldAccessOf(const Operator* op) { | |
| 87 DCHECK(op->opcode() == IrOpcode::kLoadField || | |
| 88 op->opcode() == IrOpcode::kStoreField); | |
| 89 return OpParameter<FieldAccess>(op); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 inline const ElementAccess ElementAccessOf(const Operator* op) { | |
| 94 DCHECK(op->opcode() == IrOpcode::kLoadElement || | |
| 95 op->opcode() == IrOpcode::kStoreElement); | |
| 96 return OpParameter<ElementAccess>(op); | |
| 97 } | |
| 98 | 65 |
| 99 | 66 |
| 100 // Interface for building simplified operators, which represent the | 67 // Interface for building simplified operators, which represent the |
| 101 // medium-level operations of V8, including adding numbers, allocating objects, | 68 // medium-level operations of V8, including adding numbers, allocating objects, |
| 102 // indexing into objects and arrays, etc. | 69 // indexing into objects and arrays, etc. |
| 103 // All operators are typed but many are representation independent. | 70 // All operators are typed but many are representation independent. |
| 104 | 71 |
| 105 // Number values from JS can be in one of these representations: | 72 // Number values from JS can be in one of these representations: |
| 106 // - Tagged: word-sized integer that is either | 73 // - Tagged: word-sized integer that is either |
| 107 // - a signed small integer (31 or 32 bits plus a tag) | 74 // - a signed small integer (31 or 32 bits plus a tag) |
| 108 // - a tagged pointer to a HeapNumber object that has a float64 field | 75 // - a tagged pointer to a HeapNumber object that has a float64 field |
| 109 // - Int32: an untagged signed 32-bit integer | 76 // - Int32: an untagged signed 32-bit integer |
| 110 // - Uint32: an untagged unsigned 32-bit integer | 77 // - Uint32: an untagged unsigned 32-bit integer |
| 111 // - Float64: an untagged float64 | 78 // - Float64: an untagged float64 |
| 112 | 79 |
| 113 // Additional representations for intermediate code or non-JS code: | 80 // Additional representations for intermediate code or non-JS code: |
| 114 // - Int64: an untagged signed 64-bit integer | 81 // - Int64: an untagged signed 64-bit integer |
| 115 // - Uint64: an untagged unsigned 64-bit integer | 82 // - Uint64: an untagged unsigned 64-bit integer |
| 116 // - Float32: an untagged float32 | 83 // - Float32: an untagged float32 |
| 117 | 84 |
| 118 // Boolean values can be: | 85 // Boolean values can be: |
| 119 // - Bool: a tagged pointer to either the canonical JS #false or | 86 // - Bool: a tagged pointer to either the canonical JS #false or |
| 120 // the canonical JS #true object | 87 // the canonical JS #true object |
| 121 // - Bit: an untagged integer 0 or 1, but word-sized | 88 // - Bit: an untagged integer 0 or 1, but word-sized |
| 122 class SimplifiedOperatorBuilder { | 89 class SimplifiedOperatorBuilder FINAL { |
| 123 public: | 90 public: |
| 124 explicit inline SimplifiedOperatorBuilder(Zone* zone) : zone_(zone) {} | 91 explicit SimplifiedOperatorBuilder(Zone* zone); |
| 125 | 92 |
| 126 #define SIMPLE(name, properties, inputs, outputs) \ | 93 const Operator* BooleanNot() const WARN_UNUSED_RESULT; |
| 127 return new (zone_) \ | |
| 128 SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name); | |
| 129 | 94 |
| 130 #define OP1(name, ptype, pname, properties, inputs, outputs) \ | 95 const Operator* NumberEqual() const WARN_UNUSED_RESULT; |
| 131 return new (zone_) \ | 96 const Operator* NumberLessThan() const WARN_UNUSED_RESULT; |
| 132 Operator1<ptype>(IrOpcode::k##name, properties | Operator::kNoThrow, \ | 97 const Operator* NumberLessThanOrEqual() const WARN_UNUSED_RESULT; |
| 133 inputs, outputs, #name, pname) | 98 const Operator* NumberAdd() const WARN_UNUSED_RESULT; |
| 99 const Operator* NumberSubtract() const WARN_UNUSED_RESULT; |
| 100 const Operator* NumberMultiply() const WARN_UNUSED_RESULT; |
| 101 const Operator* NumberDivide() const WARN_UNUSED_RESULT; |
| 102 const Operator* NumberModulus() const WARN_UNUSED_RESULT; |
| 103 const Operator* NumberToInt32() const WARN_UNUSED_RESULT; |
| 104 const Operator* NumberToUint32() const WARN_UNUSED_RESULT; |
| 134 | 105 |
| 135 #define UNOP(name) SIMPLE(name, Operator::kPure, 1, 1) | 106 const Operator* ReferenceEqual(Type* type) const WARN_UNUSED_RESULT; |
| 136 #define BINOP(name) SIMPLE(name, Operator::kPure, 2, 1) | |
| 137 | 107 |
| 138 const Operator* BooleanNot() const { UNOP(BooleanNot); } | 108 const Operator* StringEqual() const WARN_UNUSED_RESULT; |
| 109 const Operator* StringLessThan() const WARN_UNUSED_RESULT; |
| 110 const Operator* StringLessThanOrEqual() const WARN_UNUSED_RESULT; |
| 111 const Operator* StringAdd() const WARN_UNUSED_RESULT; |
| 139 | 112 |
| 140 const Operator* NumberEqual() const { BINOP(NumberEqual); } | 113 const Operator* ChangeTaggedToInt32() const WARN_UNUSED_RESULT; |
| 141 const Operator* NumberLessThan() const { BINOP(NumberLessThan); } | 114 const Operator* ChangeTaggedToUint32() const WARN_UNUSED_RESULT; |
| 142 const Operator* NumberLessThanOrEqual() const { | 115 const Operator* ChangeTaggedToFloat64() const WARN_UNUSED_RESULT; |
| 143 BINOP(NumberLessThanOrEqual); | 116 const Operator* ChangeInt32ToTagged() const WARN_UNUSED_RESULT; |
| 144 } | 117 const Operator* ChangeUint32ToTagged() const WARN_UNUSED_RESULT; |
| 145 const Operator* NumberAdd() const { BINOP(NumberAdd); } | 118 const Operator* ChangeFloat64ToTagged() const WARN_UNUSED_RESULT; |
| 146 const Operator* NumberSubtract() const { BINOP(NumberSubtract); } | 119 const Operator* ChangeBoolToBit() const WARN_UNUSED_RESULT; |
| 147 const Operator* NumberMultiply() const { BINOP(NumberMultiply); } | 120 const Operator* ChangeBitToBool() const WARN_UNUSED_RESULT; |
| 148 const Operator* NumberDivide() const { BINOP(NumberDivide); } | |
| 149 const Operator* NumberModulus() const { BINOP(NumberModulus); } | |
| 150 const Operator* NumberToInt32() const { UNOP(NumberToInt32); } | |
| 151 const Operator* NumberToUint32() const { UNOP(NumberToUint32); } | |
| 152 | 121 |
| 153 const Operator* ReferenceEqual(Type* type) const { BINOP(ReferenceEqual); } | 122 const Operator* LoadField(const FieldAccess&) const WARN_UNUSED_RESULT; |
| 154 | 123 const Operator* StoreField(const FieldAccess&) const WARN_UNUSED_RESULT; |
| 155 const Operator* StringEqual() const { BINOP(StringEqual); } | 124 const Operator* LoadElement(const ElementAccess&) const WARN_UNUSED_RESULT; |
| 156 const Operator* StringLessThan() const { BINOP(StringLessThan); } | 125 const Operator* StoreElement(const ElementAccess&) const WARN_UNUSED_RESULT; |
| 157 const Operator* StringLessThanOrEqual() const { | |
| 158 BINOP(StringLessThanOrEqual); | |
| 159 } | |
| 160 const Operator* StringAdd() const { BINOP(StringAdd); } | |
| 161 | |
| 162 const Operator* ChangeTaggedToInt32() const { UNOP(ChangeTaggedToInt32); } | |
| 163 const Operator* ChangeTaggedToUint32() const { UNOP(ChangeTaggedToUint32); } | |
| 164 const Operator* ChangeTaggedToFloat64() const { UNOP(ChangeTaggedToFloat64); } | |
| 165 const Operator* ChangeInt32ToTagged() const { UNOP(ChangeInt32ToTagged); } | |
| 166 const Operator* ChangeUint32ToTagged() const { UNOP(ChangeUint32ToTagged); } | |
| 167 const Operator* ChangeFloat64ToTagged() const { UNOP(ChangeFloat64ToTagged); } | |
| 168 const Operator* ChangeBoolToBit() const { UNOP(ChangeBoolToBit); } | |
| 169 const Operator* ChangeBitToBool() const { UNOP(ChangeBitToBool); } | |
| 170 | |
| 171 const Operator* LoadField(const FieldAccess& access) const { | |
| 172 OP1(LoadField, FieldAccess, access, Operator::kNoWrite, 1, 1); | |
| 173 } | |
| 174 const Operator* StoreField(const FieldAccess& access) const { | |
| 175 OP1(StoreField, FieldAccess, access, Operator::kNoRead, 2, 0); | |
| 176 } | |
| 177 const Operator* LoadElement(const ElementAccess& access) const { | |
| 178 OP1(LoadElement, ElementAccess, access, Operator::kNoWrite, 2, 1); | |
| 179 } | |
| 180 const Operator* StoreElement(const ElementAccess& access) const { | |
| 181 OP1(StoreElement, ElementAccess, access, Operator::kNoRead, 3, 0); | |
| 182 } | |
| 183 | |
| 184 #undef BINOP | |
| 185 #undef UNOP | |
| 186 #undef OP1 | |
| 187 #undef SIMPLE | |
| 188 | 126 |
| 189 private: | 127 private: |
| 190 Zone* zone_; | 128 Zone* zone() const { return zone_; } |
| 129 |
| 130 const SimplifiedOperatorBuilderImpl& impl_; |
| 131 Zone* const zone_; |
| 132 |
| 133 DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder); |
| 191 }; | 134 }; |
| 192 } | 135 |
| 193 } | 136 } // namespace compiler |
| 194 } // namespace v8::internal::compiler | 137 } // namespace internal |
| 138 } // namespace v8 |
| 195 | 139 |
| 196 #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ | 140 #endif // V8_COMPILER_SIMPLIFIED_OPERATOR_H_ |
| OLD | NEW |