Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / simplified-operator.cc
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
3 // found in the LICENSE file.
4
5 #include "src/compiler/simplified-operator.h"
6
7 #include "src/base/lazy-instance.h"
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
10 #include "src/types-inl.h"
11
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15
16 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
17   switch (base_taggedness) {
18     case kUntaggedBase:
19       return os << "untagged base";
20     case kTaggedBase:
21       return os << "tagged base";
22   }
23   UNREACHABLE();
24   return os;
25 }
26
27
28 bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
29   return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
30          lhs.machine_type == rhs.machine_type;
31 }
32
33
34 bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
35   return !(lhs == rhs);
36 }
37
38
39 size_t hash_value(FieldAccess const& access) {
40   return base::hash_combine(access.base_is_tagged, access.offset,
41                             access.machine_type);
42 }
43
44
45 std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
46   os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
47 #ifdef OBJECT_PRINT
48   Handle<Name> name;
49   if (access.name.ToHandle(&name)) {
50     name->Print(os);
51     os << ", ";
52   }
53 #endif
54   access.type->PrintTo(os);
55   os << ", " << access.machine_type << "]";
56   return os;
57 }
58
59
60 std::ostream& operator<<(std::ostream& os, BoundsCheckMode bounds_check_mode) {
61   switch (bounds_check_mode) {
62     case kNoBoundsCheck:
63       return os << "no bounds check";
64     case kTypedArrayBoundsCheck:
65       return os << "ignore out of bounds";
66   }
67   UNREACHABLE();
68   return os;
69 }
70
71
72 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
73   return lhs.base_is_tagged == rhs.base_is_tagged &&
74          lhs.header_size == rhs.header_size &&
75          lhs.machine_type == rhs.machine_type;
76 }
77
78
79 bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
80   return !(lhs == rhs);
81 }
82
83
84 size_t hash_value(ElementAccess const& access) {
85   return base::hash_combine(access.base_is_tagged, access.header_size,
86                             access.machine_type);
87 }
88
89
90 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
91   os << access.base_is_tagged << ", " << access.header_size << ", ";
92   access.type->PrintTo(os);
93   os << ", " << access.machine_type << ", " << access.bounds_check;
94   return os;
95 }
96
97
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) {
107   DCHECK_NOT_NULL(op);
108   DCHECK(op->opcode() == IrOpcode::kLoadElement ||
109          op->opcode() == IrOpcode::kStoreElement);
110   return OpParameter<ElementAccess>(op);
111 }
112
113
114 #define PURE_OP_LIST(V)                                \
115   V(BooleanNot, Operator::kNoProperties, 1)            \
116   V(BooleanToNumber, Operator::kNoProperties, 1)       \
117   V(NumberEqual, Operator::kCommutative, 2)            \
118   V(NumberLessThan, Operator::kNoProperties, 2)        \
119   V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \
120   V(NumberAdd, Operator::kCommutative, 2)              \
121   V(NumberSubtract, Operator::kNoProperties, 2)        \
122   V(NumberMultiply, Operator::kCommutative, 2)         \
123   V(NumberDivide, Operator::kNoProperties, 2)          \
124   V(NumberModulus, Operator::kNoProperties, 2)         \
125   V(NumberToInt32, Operator::kNoProperties, 1)         \
126   V(NumberToUint32, Operator::kNoProperties, 1)        \
127   V(StringEqual, Operator::kCommutative, 2)            \
128   V(StringLessThan, Operator::kNoProperties, 2)        \
129   V(StringLessThanOrEqual, Operator::kNoProperties, 2) \
130   V(StringAdd, Operator::kNoProperties, 2)             \
131   V(ChangeTaggedToInt32, Operator::kNoProperties, 1)   \
132   V(ChangeTaggedToUint32, Operator::kNoProperties, 1)  \
133   V(ChangeTaggedToFloat64, Operator::kNoProperties, 1) \
134   V(ChangeInt32ToTagged, Operator::kNoProperties, 1)   \
135   V(ChangeUint32ToTagged, Operator::kNoProperties, 1)  \
136   V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
137   V(ChangeBoolToBit, Operator::kNoProperties, 1)       \
138   V(ChangeBitToBool, Operator::kNoProperties, 1)       \
139   V(ObjectIsSmi, Operator::kNoProperties, 1)           \
140   V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
141
142
143 struct SimplifiedOperatorGlobalCache FINAL {
144 #define PURE(Name, properties, input_count)                                \
145   struct Name##Operator FINAL : public Operator {                          \
146     Name##Operator()                                                       \
147         : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
148                    input_count, 0, 0, 1, 0, 0) {}                          \
149   };                                                                       \
150   Name##Operator k##Name;
151   PURE_OP_LIST(PURE)
152 #undef PURE
153 };
154
155
156 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache =
157     LAZY_INSTANCE_INITIALIZER;
158
159
160 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
161     : cache_(kCache.Get()), zone_(zone) {}
162
163
164 #define PURE(Name, properties, input_count) \
165   const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
166 PURE_OP_LIST(PURE)
167 #undef PURE
168
169
170 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
171   // TODO(titzer): What about the type parameter?
172   return new (zone()) Operator(IrOpcode::kReferenceEqual,
173                                Operator::kCommutative | Operator::kPure,
174                                "ReferenceEqual", 2, 0, 0, 1, 0, 0);
175 }
176
177
178 #define ACCESS_OP_LIST(V)                                    \
179   V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1)     \
180   V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0)     \
181   V(LoadElement, ElementAccess, Operator::kNoWrite, 3, 0, 1) \
182   V(StoreElement, ElementAccess, Operator::kNoRead, 4, 1, 0)
183
184
185 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
186                output_count)                                                   \
187   const Operator* SimplifiedOperatorBuilder::Name(const Type& access) {        \
188     return new (zone())                                                        \
189         Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties,    \
190                         #Name, value_input_count, 1, control_input_count,      \
191                         output_count, 1, 0, access);                           \
192   }
193 ACCESS_OP_LIST(ACCESS)
194 #undef ACCESS
195
196 }  // namespace compiler
197 }  // namespace internal
198 }  // namespace v8