blob: 3ea99d40a64415c3571b21f2195d2f6b9384c28a [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
29#define V8_HYDROGEN_INSTRUCTIONS_H_
30
31#include "v8.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000032
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "allocation.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "code-stubs.h"
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +000035#include "data-flow.h"
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +000036#include "small-pointer-list.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000037#include "string-stream.h"
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000038#include "v8conversions.h"
39#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000040#include "zone.h"
41
42namespace v8 {
43namespace internal {
44
45// Forward declarations.
46class HBasicBlock;
47class HEnvironment;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +000048class HInferRepresentation;
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049class HInstruction;
50class HLoopInformation;
51class HValue;
52class LInstruction;
53class LChunkBuilder;
54
55
ricow@chromium.orgdcebac02011-04-20 09:44:50 +000056#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000057 V(BinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 V(ControlInstruction) \
60 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061
62
63#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
kmillikin@chromium.org31b12772011-02-02 16:08:26 +000064 V(AbnormalExit) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000065 V(AccessArgumentsAt) \
66 V(Add) \
danno@chromium.org94b0d6f2013-02-04 13:33:20 +000067 V(Allocate) \
ulan@chromium.org967e2702012-02-28 09:49:15 +000068 V(AllocateObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 V(ApplyArguments) \
70 V(ArgumentsElements) \
71 V(ArgumentsLength) \
72 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000073 V(ArrayLiteral) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000074 V(Bitwise) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000075 V(BitNot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000076 V(BlockEntry) \
77 V(BoundsCheck) \
svenpanne@chromium.org876cca82013-03-18 14:43:20 +000078 V(BoundsCheckBaseIndexInformation) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000079 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000080 V(CallConstantFunction) \
81 V(CallFunction) \
82 V(CallGlobal) \
83 V(CallKeyed) \
84 V(CallKnownGlobal) \
85 V(CallNamed) \
86 V(CallNew) \
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +000087 V(CallNewArray) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000088 V(CallRuntime) \
89 V(CallStub) \
90 V(Change) \
91 V(CheckFunction) \
92 V(CheckInstanceType) \
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000093 V(CheckMaps) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000094 V(CheckNonSmi) \
95 V(CheckPrototypeMaps) \
96 V(CheckSmi) \
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +000097 V(CheckSmiOrInt32) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000098 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000099 V(ClassOfTestAndBranch) \
100 V(CompareIDAndBranch) \
101 V(CompareGeneric) \
102 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000103 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000104 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000105 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000106 V(Context) \
yangguo@chromium.org56454712012-02-16 15:33:53 +0000107 V(DeclareGlobals) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(DeleteProperty) \
109 V(Deoptimize) \
110 V(Div) \
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000111 V(DummyUse) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000112 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(EnterInlined) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000114 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000115 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000117 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 V(GlobalObject) \
119 V(GlobalReceiver) \
120 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000121 V(HasCachedArrayIndexAndBranch) \
122 V(HasInstanceTypeAndBranch) \
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000123 V(InductionVariableAnnotation) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000124 V(In) \
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000125 V(InnerAllocatedObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000127 V(InstanceOfKnownGlobal) \
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000128 V(InstanceSize) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000129 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000130 V(IsConstructCallAndBranch) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000131 V(IsNilAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000132 V(IsObjectAndBranch) \
erikcorry0ad885c2011-11-21 13:51:57 +0000133 V(IsStringAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000134 V(IsSmiAndBranch) \
135 V(IsUndetectableAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000137 V(LoadContextSlot) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000138 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000139 V(LoadFunctionPrototype) \
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000140 V(LoadGlobalCell) \
141 V(LoadGlobalGeneric) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000142 V(LoadKeyed) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143 V(LoadKeyedGeneric) \
144 V(LoadNamedField) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000145 V(LoadNamedFieldPolymorphic) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000146 V(LoadNamedGeneric) \
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000147 V(MapEnumLength) \
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000148 V(MathFloorOfDiv) \
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000149 V(MathMinMax) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150 V(Mod) \
151 V(Mul) \
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000152 V(NumericConstraint) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000153 V(ObjectLiteral) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000155 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000157 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(PushArgument) \
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000159 V(Random) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(RegExpLiteral) \
161 V(Return) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000162 V(Ror) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163 V(Sar) \
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +0000164 V(SeqStringSetChar) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000165 V(Shl) \
166 V(Shr) \
167 V(Simulate) \
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000168 V(SoftDeoptimize) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000169 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000170 V(StoreContextSlot) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000171 V(StoreGlobalCell) \
172 V(StoreGlobalGeneric) \
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000173 V(StoreKeyed) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000174 V(StoreKeyedGeneric) \
175 V(StoreNamedField) \
176 V(StoreNamedGeneric) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000177 V(StringAdd) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000178 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000179 V(StringCharFromCode) \
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000180 V(StringCompareAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000181 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000182 V(Sub) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000183 V(ThisFunction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000184 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000185 V(ToFastProperties) \
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000186 V(TransitionElementsKind) \
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000187 V(TrapAllocationMemento) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000188 V(Typeof) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000189 V(TypeofIsAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000190 V(UnaryMathOperation) \
191 V(UnknownOSRValue) \
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000192 V(UseConst) \
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +0000193 V(ValueOf) \
194 V(ForInPrepareMap) \
195 V(ForInCacheArray) \
196 V(CheckMapValue) \
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000197 V(LoadFieldByIndex) \
yangguo@chromium.org154ff992012-03-13 08:09:54 +0000198 V(DateField) \
199 V(WrapReceiver)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000201#define GVN_TRACKED_FLAG_LIST(V) \
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000202 V(Maps) \
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000203 V(NewSpacePromotion)
204
205#define GVN_UNTRACKED_FLAG_LIST(V) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206 V(Calls) \
207 V(InobjectFields) \
208 V(BackingStoreFields) \
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000209 V(DoubleFields) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000210 V(ElementsKind) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000211 V(ElementsPointer) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000213 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000214 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215 V(GlobalVars) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000217 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 V(OsrEntries)
219
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000220#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000221 virtual bool Is##type() const { return true; } \
222 static H##type* cast(HValue* value) { \
223 ASSERT(value->Is##type()); \
224 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000225 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226
227
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000228#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000230 static H##type* cast(HValue* value) { \
231 ASSERT(value->Is##type()); \
232 return reinterpret_cast<H##type*>(value); \
233 } \
234 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000235
236
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237class Range: public ZoneObject {
238 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000239 Range()
240 : lower_(kMinInt),
241 upper_(kMaxInt),
242 next_(NULL),
243 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244
245 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000246 : lower_(lower),
247 upper_(upper),
248 next_(NULL),
249 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000250
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251 int32_t upper() const { return upper_; }
252 int32_t lower() const { return lower_; }
253 Range* next() const { return next_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000254 Range* CopyClearLower(Zone* zone) const {
255 return new(zone) Range(kMinInt, upper_);
256 }
257 Range* CopyClearUpper(Zone* zone) const {
258 return new(zone) Range(lower_, kMaxInt);
259 }
260 Range* Copy(Zone* zone) const {
261 Range* result = new(zone) Range(lower_, upper_);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000262 result->set_can_be_minus_zero(CanBeMinusZero());
263 return result;
264 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000265 int32_t Mask() const;
266 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
267 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
268 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
269 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000270 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000271 bool IsMostGeneric() const {
272 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
273 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000274 bool IsInSmiRange() const {
275 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000276 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000277 void KeepOrder();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000278#ifdef DEBUG
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000279 void Verify() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000280#endif
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000281
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000282 void StackUpon(Range* other) {
283 Intersect(other);
284 next_ = other;
285 }
286
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000287 void Intersect(Range* other);
288 void Union(Range* other);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000289 void CombinedMax(Range* other);
290 void CombinedMin(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000291
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000292 void AddConstant(int32_t value);
293 void Sar(int32_t value);
294 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000295 bool AddAndCheckOverflow(Range* other);
296 bool SubAndCheckOverflow(Range* other);
297 bool MulAndCheckOverflow(Range* other);
298
299 private:
300 int32_t lower_;
301 int32_t upper_;
302 Range* next_;
303 bool can_be_minus_zero_;
304};
305
306
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000307class UniqueValueId {
308 public:
309 UniqueValueId() : raw_address_(NULL) { }
310
311 explicit UniqueValueId(Object* object) {
312 raw_address_ = reinterpret_cast<Address>(object);
313 ASSERT(IsInitialized());
314 }
315
316 explicit UniqueValueId(Handle<Object> handle) {
317 static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1);
318 if (handle.is_null()) {
319 raw_address_ = kEmptyHandleSentinel;
320 } else {
321 raw_address_ = reinterpret_cast<Address>(*handle);
322 ASSERT_NE(kEmptyHandleSentinel, raw_address_);
323 }
324 ASSERT(IsInitialized());
325 }
326
327 bool IsInitialized() const { return raw_address_ != NULL; }
328
329 bool operator==(const UniqueValueId& other) const {
330 ASSERT(IsInitialized() && other.IsInitialized());
331 return raw_address_ == other.raw_address_;
332 }
333
334 bool operator!=(const UniqueValueId& other) const {
335 ASSERT(IsInitialized() && other.IsInitialized());
336 return raw_address_ != other.raw_address_;
337 }
338
339 intptr_t Hashcode() const {
340 ASSERT(IsInitialized());
341 return reinterpret_cast<intptr_t>(raw_address_);
342 }
343
344 private:
345 Address raw_address_;
346};
347
348
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000349class HType {
350 public:
351 HType() : type_(kUninitialized) { }
352
353 static HType Tagged() { return HType(kTagged); }
354 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
355 static HType TaggedNumber() { return HType(kTaggedNumber); }
356 static HType Smi() { return HType(kSmi); }
357 static HType HeapNumber() { return HType(kHeapNumber); }
358 static HType String() { return HType(kString); }
359 static HType Boolean() { return HType(kBoolean); }
360 static HType NonPrimitive() { return HType(kNonPrimitive); }
361 static HType JSArray() { return HType(kJSArray); }
362 static HType JSObject() { return HType(kJSObject); }
363 static HType Uninitialized() { return HType(kUninitialized); }
364
365 // Return the weakest (least precise) common type.
366 HType Combine(HType other) {
367 return HType(static_cast<Type>(type_ & other.type_));
368 }
369
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000370 bool Equals(const HType& other) const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000371 return type_ == other.type_;
372 }
373
374 bool IsSubtypeOf(const HType& other) {
375 return Combine(other).Equals(other);
376 }
377
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000378 bool IsTagged() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000379 ASSERT(type_ != kUninitialized);
380 return ((type_ & kTagged) == kTagged);
381 }
382
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000383 bool IsTaggedPrimitive() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000384 ASSERT(type_ != kUninitialized);
385 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
386 }
387
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000388 bool IsTaggedNumber() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000389 ASSERT(type_ != kUninitialized);
390 return ((type_ & kTaggedNumber) == kTaggedNumber);
391 }
392
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000393 bool IsSmi() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000394 ASSERT(type_ != kUninitialized);
395 return ((type_ & kSmi) == kSmi);
396 }
397
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000398 bool IsHeapNumber() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000399 ASSERT(type_ != kUninitialized);
400 return ((type_ & kHeapNumber) == kHeapNumber);
401 }
402
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000403 bool IsString() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000404 ASSERT(type_ != kUninitialized);
405 return ((type_ & kString) == kString);
406 }
407
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000408 bool IsBoolean() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000409 ASSERT(type_ != kUninitialized);
410 return ((type_ & kBoolean) == kBoolean);
411 }
412
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000413 bool IsNonPrimitive() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000414 ASSERT(type_ != kUninitialized);
415 return ((type_ & kNonPrimitive) == kNonPrimitive);
416 }
417
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000418 bool IsJSArray() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000419 ASSERT(type_ != kUninitialized);
420 return ((type_ & kJSArray) == kJSArray);
421 }
422
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000423 bool IsJSObject() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000424 ASSERT(type_ != kUninitialized);
425 return ((type_ & kJSObject) == kJSObject);
426 }
427
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000428 bool IsUninitialized() const {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000429 return type_ == kUninitialized;
430 }
431
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000432 bool IsHeapObject() const {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000433 ASSERT(type_ != kUninitialized);
434 return IsHeapNumber() || IsString() || IsNonPrimitive();
435 }
436
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +0000437 static HType TypeFromValue(Handle<Object> value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000438
439 const char* ToString();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000440
441 private:
442 enum Type {
443 kTagged = 0x1, // 0000 0000 0000 0001
444 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
445 kTaggedNumber = 0xd, // 0000 0000 0000 1101
446 kSmi = 0x1d, // 0000 0000 0001 1101
447 kHeapNumber = 0x2d, // 0000 0000 0010 1101
448 kString = 0x45, // 0000 0000 0100 0101
449 kBoolean = 0x85, // 0000 0000 1000 0101
450 kNonPrimitive = 0x101, // 0000 0001 0000 0001
451 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000452 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000453 kUninitialized = 0x1fff // 0001 1111 1111 1111
454 };
455
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000456 // Make sure type fits in int16.
457 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
458
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000459 explicit HType(Type t) : type_(t) { }
460
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000461 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000462};
463
464
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000465class HUseListNode: public ZoneObject {
466 public:
467 HUseListNode(HValue* value, int index, HUseListNode* tail)
468 : tail_(tail), value_(value), index_(index) {
469 }
470
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000471 HUseListNode* tail();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000472 HValue* value() const { return value_; }
473 int index() const { return index_; }
474
475 void set_tail(HUseListNode* list) { tail_ = list; }
476
477#ifdef DEBUG
478 void Zap() {
479 tail_ = reinterpret_cast<HUseListNode*>(1);
480 value_ = NULL;
481 index_ = -1;
482 }
483#endif
484
485 private:
486 HUseListNode* tail_;
487 HValue* value_;
488 int index_;
489};
490
491
492// We reuse use list nodes behind the scenes as uses are added and deleted.
493// This class is the safe way to iterate uses while deleting them.
494class HUseIterator BASE_EMBEDDED {
495 public:
496 bool Done() { return current_ == NULL; }
497 void Advance();
498
499 HValue* value() {
500 ASSERT(!Done());
501 return value_;
502 }
503
504 int index() {
505 ASSERT(!Done());
506 return index_;
507 }
508
509 private:
510 explicit HUseIterator(HUseListNode* head);
511
512 HUseListNode* current_;
513 HUseListNode* next_;
514 HValue* value_;
515 int index_;
516
517 friend class HValue;
518};
519
520
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000521// There must be one corresponding kDepends flag for every kChanges flag and
522// the order of the kChanges flags must be exactly the same as of the kDepends
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000523// flags. All tracked flags should appear before untracked ones.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000524enum GVNFlag {
525 // Declare global value numbering flags.
526#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000527 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
528 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000529#undef DECLARE_FLAG
530 kAfterLastFlag,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000531 kLastFlag = kAfterLastFlag - 1,
532#define COUNT_FLAG(type) + 1
533 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
534#undef COUNT_FLAG
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000535};
536
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000537
538class NumericRelation {
539 public:
540 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
541 static const char* MnemonicFromKind(Kind kind) {
542 switch (kind) {
543 case NONE: return "NONE";
544 case EQ: return "EQ";
545 case GT: return "GT";
546 case GE: return "GE";
547 case LT: return "LT";
548 case LE: return "LE";
549 case NE: return "NE";
550 }
551 UNREACHABLE();
552 return NULL;
553 }
554 const char* Mnemonic() const { return MnemonicFromKind(kind_); }
555
556 static NumericRelation None() { return NumericRelation(NONE); }
557 static NumericRelation Eq() { return NumericRelation(EQ); }
558 static NumericRelation Gt() { return NumericRelation(GT); }
559 static NumericRelation Ge() { return NumericRelation(GE); }
560 static NumericRelation Lt() { return NumericRelation(LT); }
561 static NumericRelation Le() { return NumericRelation(LE); }
562 static NumericRelation Ne() { return NumericRelation(NE); }
563
564 bool IsNone() { return kind_ == NONE; }
565
566 static NumericRelation FromToken(Token::Value token) {
567 switch (token) {
568 case Token::EQ: return Eq();
569 case Token::EQ_STRICT: return Eq();
570 case Token::LT: return Lt();
571 case Token::GT: return Gt();
572 case Token::LTE: return Le();
573 case Token::GTE: return Ge();
574 case Token::NE: return Ne();
575 case Token::NE_STRICT: return Ne();
576 default: return None();
577 }
578 }
579
580 // The semantics of "Reversed" is that if "x rel y" is true then also
581 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
582 NumericRelation Reversed() {
583 switch (kind_) {
584 case NONE: return None();
585 case EQ: return Eq();
586 case GT: return Lt();
587 case GE: return Le();
588 case LT: return Gt();
589 case LE: return Ge();
590 case NE: return Ne();
591 }
592 UNREACHABLE();
593 return None();
594 }
595
596 // The semantics of "Negated" is that if "x rel y" is true then also
597 // "!(x rel.Negated() y)" is true.
598 NumericRelation Negated() {
599 switch (kind_) {
600 case NONE: return None();
601 case EQ: return Ne();
602 case GT: return Le();
603 case GE: return Lt();
604 case LT: return Ge();
605 case LE: return Gt();
606 case NE: return Eq();
607 }
608 UNREACHABLE();
609 return None();
610 }
611
612 // The semantics of "Implies" is that if "x rel y" is true
613 // then also "x other_relation y" is true.
614 bool Implies(NumericRelation other_relation) {
615 switch (kind_) {
616 case NONE: return false;
617 case EQ: return (other_relation.kind_ == EQ)
618 || (other_relation.kind_ == GE)
619 || (other_relation.kind_ == LE);
620 case GT: return (other_relation.kind_ == GT)
621 || (other_relation.kind_ == GE)
622 || (other_relation.kind_ == NE);
623 case LT: return (other_relation.kind_ == LT)
624 || (other_relation.kind_ == LE)
625 || (other_relation.kind_ == NE);
626 case GE: return (other_relation.kind_ == GE);
627 case LE: return (other_relation.kind_ == LE);
628 case NE: return (other_relation.kind_ == NE);
629 }
630 UNREACHABLE();
631 return false;
632 }
633
634 // The semantics of "IsExtendable" is that if
635 // "rel.IsExtendable(direction)" is true then
636 // "x rel y" implies "(x + direction) rel y" .
637 bool IsExtendable(int direction) {
638 switch (kind_) {
639 case NONE: return false;
640 case EQ: return false;
641 case GT: return (direction >= 0);
642 case GE: return (direction >= 0);
643 case LT: return (direction <= 0);
644 case LE: return (direction <= 0);
645 case NE: return false;
646 }
647 UNREACHABLE();
648 return false;
649 }
650
svenpanne@chromium.org876cca82013-03-18 14:43:20 +0000651 // CompoundImplies returns true when
652 // "((x + my_offset) >> my_scale) rel y" implies
653 // "((x + other_offset) >> other_scale) other_relation y".
654 bool CompoundImplies(NumericRelation other_relation,
655 int my_offset,
656 int my_scale,
657 int other_offset = 0,
658 int other_scale = 0) {
659 return Implies(other_relation) && ComponentsImply(
660 my_offset, my_scale, other_offset, other_scale);
661 }
662
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000663 private:
svenpanne@chromium.org876cca82013-03-18 14:43:20 +0000664 // ComponentsImply returns true when
665 // "((x + my_offset) >> my_scale) rel y" implies
666 // "((x + other_offset) >> other_scale) rel y".
667 bool ComponentsImply(int my_offset,
668 int my_scale,
669 int other_offset,
670 int other_scale) {
671 switch (kind_) {
672 case NONE: break; // Fall through to UNREACHABLE().
673 case EQ:
674 case NE: return my_offset == other_offset && my_scale == other_scale;
675 case GT:
676 case GE: return my_offset <= other_offset && my_scale >= other_scale;
677 case LT:
678 case LE: return my_offset >= other_offset && my_scale <= other_scale;
679 }
680 UNREACHABLE();
681 return false;
682 }
683
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000684 explicit NumericRelation(Kind kind) : kind_(kind) {}
685
686 Kind kind_;
687};
688
689
svenpanne@chromium.org876cca82013-03-18 14:43:20 +0000690class DecompositionResult BASE_EMBEDDED {
691 public:
692 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
693
694 HValue* base() { return base_; }
695 int offset() { return offset_; }
696 int scale() { return scale_; }
697
698 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
699 if (base_ == NULL) {
700 base_ = other_base;
701 offset_ = other_offset;
702 scale_ = other_scale;
703 return true;
704 } else {
705 if (scale_ == 0) {
706 base_ = other_base;
707 offset_ += other_offset;
708 scale_ = other_scale;
709 return true;
710 } else {
711 return false;
712 }
713 }
714 }
715
716 void SwapValues(HValue** other_base, int* other_offset, int* other_scale) {
717 swap(&base_, other_base);
718 swap(&offset_, other_offset);
719 swap(&scale_, other_scale);
720 }
721
722 private:
723 template <class T> void swap(T* a, T* b) {
724 T c(*a);
725 *a = *b;
726 *b = c;
727 }
728
729 HValue* base_;
730 int offset_;
731 int scale_;
732};
733
734
735class RangeEvaluationContext BASE_EMBEDDED {
736 public:
737 RangeEvaluationContext(HValue* value, HValue* upper);
738
739 HValue* lower_bound() { return lower_bound_; }
740 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
741 HValue* candidate() { return candidate_; }
742 HValue* upper_bound() { return upper_bound_; }
743 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
744 int offset() { return offset_; }
745 int scale() { return scale_; }
746
747 bool is_range_satisfied() {
748 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
749 }
750
751 void set_lower_bound_guarantee(HValue* guarantee) {
752 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
753 }
754 void set_upper_bound_guarantee(HValue* guarantee) {
755 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
756 }
757
758 void swap_candidate(DecompositionResult* other_candicate) {
759 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
760 }
761
762 private:
763 HValue* ConvertGuarantee(HValue* guarantee);
764
765 HValue* lower_bound_;
766 HValue* lower_bound_guarantee_;
767 HValue* candidate_;
768 HValue* upper_bound_;
769 HValue* upper_bound_guarantee_;
770 int offset_;
771 int scale_;
772};
773
774
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000775typedef EnumSet<GVNFlag> GVNFlagSet;
776
777
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000778class HValue: public ZoneObject {
779 public:
780 static const int kNoNumber = -1;
781
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000782 enum Flag {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000783 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000784 // Participate in Global Value Numbering, i.e. elimination of
785 // unnecessary recomputations. If an instruction sets this flag, it must
786 // implement DataEquals(), which will be used to determine if other
787 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000788 kUseGVN,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000789 // Track instructions that are dominating side effects. If an instruction
790 // sets this flag, it must implement SetSideEffectDominator() and should
791 // indicate which side effects to track by setting GVN flags.
792 kTrackSideEffectDominators,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000793 kCanOverflow,
794 kBailoutOnMinusZero,
795 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000796 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000797 kIsArguments,
798 kTruncatingToInt32,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000799 kIsDead,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000800 // Instructions that are allowed to produce full range unsigned integer
801 // values are marked with kUint32 flag. If arithmetic shift or a load from
802 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
803 // it will deoptimize if result does not fit into signed integer range.
804 // HGraph::ComputeSafeUint32Operations is responsible for setting this
805 // flag.
806 kUint32,
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000807 // If a phi is involved in the evaluation of a numeric constraint the
808 // recursion can cause an endless cycle: we use this flag to exit the loop.
809 kNumericConstraintEvaluationInProgress,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000810 // This flag is set to true after the SetupInformativeDefinitions() pass
811 // has processed this instruction.
812 kIDefsProcessingDone,
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000813 kHasNoObservableSideEffects,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000814 kLastFlag = kIDefsProcessingDone
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000815 };
816
817 STATIC_ASSERT(kLastFlag < kBitsPerInt);
818
819 static const int kChangesToDependsFlagsLeftShift = 1;
820
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000821 static GVNFlag ChangesFlagFromInt(int x) {
822 return static_cast<GVNFlag>(x * 2);
823 }
824 static GVNFlag DependsOnFlagFromInt(int x) {
825 return static_cast<GVNFlag>(x * 2 + 1);
826 }
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000827 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
828 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000829 }
830
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000831 static HValue* cast(HValue* value) { return value; }
832
833 enum Opcode {
834 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000835 #define DECLARE_OPCODE(type) k##type,
836 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
837 kPhi
838 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000839 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000840 virtual Opcode opcode() const = 0;
841
842 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
843 #define DECLARE_PREDICATE(type) \
844 bool Is##type() const { return opcode() == k##type; }
845 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
846 #undef DECLARE_PREDICATE
847 bool IsPhi() const { return opcode() == kPhi; }
848
849 // Declare virtual predicates for abstract HInstruction or HValue
850 #define DECLARE_PREDICATE(type) \
851 virtual bool Is##type() const { return false; }
852 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
853 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000854
855 HValue() : block_(NULL),
856 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000857 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000858 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000859 range_(NULL),
860 flags_(0) {}
861 virtual ~HValue() {}
862
863 HBasicBlock* block() const { return block_; }
864 void SetBlock(HBasicBlock* block);
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000865 int LoopWeight() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000866
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000867 // Note: Never call this method for an unlinked value.
868 Isolate* isolate() const;
869
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870 int id() const { return id_; }
871 void set_id(int id) { id_ = id; }
872
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000873 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000874
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000875 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000876 Representation representation() const { return representation_; }
877 void ChangeRepresentation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000878 ASSERT(CheckFlag(kFlexibleRepresentation));
879 RepresentationChanged(r);
880 representation_ = r;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000881 if (r.IsTagged()) {
882 // Tagged is the bottom of the lattice, don't go any further.
883 ClearFlag(kFlexibleRepresentation);
884 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000885 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000886 virtual void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000887
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000888 virtual bool IsConvertibleToInteger() const { return true; }
889
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000890 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000891 void set_type(HType new_type) {
892 ASSERT(new_type.IsSubtypeOf(type_));
893 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000894 }
895
896 // An operation needs to override this function iff:
897 // 1) it can produce an int32 output.
898 // 2) the true value of its output can potentially be minus zero.
899 // The implementation must set a flag so that it bails out in the case where
900 // it would otherwise output what should be a minus zero as an int32 zero.
901 // If the operation also exists in a form that takes int32 and outputs int32
902 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000903 // back. There are three operations that need to propagate back to more than
904 // one input. They are phi and binary div and mul. They always return NULL
905 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000906 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
907 visited->Add(id());
908 return NULL;
909 }
910
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000911 // There are HInstructions that do not really change a value, they
912 // only add pieces of information to it (like bounds checks, map checks,
913 // smi checks...).
914 // We call these instructions "informative definitions", or "iDef".
915 // One of the iDef operands is special because it is the value that is
916 // "transferred" to the output, we call it the "redefined operand".
917 // If an HValue is an iDef it must override RedefinedOperandIndex() so that
918 // it does not return kNoRedefinedOperand;
919 static const int kNoRedefinedOperand = -1;
920 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
921 bool IsInformativeDefinition() {
922 return RedefinedOperandIndex() != kNoRedefinedOperand;
923 }
924 HValue* RedefinedOperand() {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000925 return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex())
926 : NULL;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000927 }
928
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000929 // A purely informative definition is an idef that will not emit code and
930 // should therefore be removed from the graph in the RestoreActualValues
931 // phase (so that live ranges will be shorter).
932 virtual bool IsPurelyInformativeDefinition() { return false; }
933
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000934 // This method must always return the original HValue SSA definition
935 // (regardless of any iDef of this value).
936 HValue* ActualValue() {
937 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue()
938 : this;
939 }
940
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000941 virtual void AddInformativeDefinitions() {}
942
943 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
944 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
945 }
946 void UpdateRedefinedUses() {
947 UpdateRedefinedUsesInner<Dominates>();
948 }
949
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000950 bool IsInteger32Constant();
951 int32_t GetInteger32Constant();
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000952 bool EqualsInteger32Constant(int32_t value);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000953
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000954 bool IsDefinedAfter(HBasicBlock* other) const;
955
956 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000957 virtual int OperandCount() = 0;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000958 virtual HValue* OperandAt(int index) const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000959 void SetOperandAt(int index, HValue* value);
960
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000961 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000962 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000963 bool HasNoUses() const { return use_list_ == NULL; }
964 bool HasMultipleUses() const {
965 return use_list_ != NULL && use_list_->tail() != NULL;
966 }
967 int UseCount() const;
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000968
969 // Mark this HValue as dead and to be removed from other HValues' use lists.
970 void Kill();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000971
972 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000973 void SetFlag(Flag f) { flags_ |= (1 << f); }
974 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
975 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
976
ulan@chromium.org812308e2012-02-29 15:58:45 +0000977 // Returns true if the flag specified is set for all uses, false otherwise.
978 bool CheckUsesForFlag(Flag f);
979
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000980 GVNFlagSet gvn_flags() const { return gvn_flags_; }
981 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
982 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
983 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
984 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
985 void ClearAllSideEffects() {
986 gvn_flags_.Remove(AllSideEffectsFlagSet());
987 }
988 bool HasSideEffects() const {
989 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
990 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000991 bool HasObservableSideEffects() const {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000992 return !CheckFlag(kHasNoObservableSideEffects) &&
993 gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000994 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000995
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000996 GVNFlagSet DependsOnFlags() const {
997 GVNFlagSet result = gvn_flags_;
998 result.Intersect(AllDependsOnFlagSet());
999 return result;
1000 }
1001
1002 GVNFlagSet SideEffectFlags() const {
1003 GVNFlagSet result = gvn_flags_;
1004 result.Intersect(AllSideEffectsFlagSet());
1005 return result;
1006 }
1007
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001008 GVNFlagSet ChangesFlags() const {
1009 GVNFlagSet result = gvn_flags_;
1010 result.Intersect(AllChangesFlagSet());
1011 return result;
1012 }
1013
1014 GVNFlagSet ObservableChangesFlags() const {
1015 GVNFlagSet result = gvn_flags_;
1016 result.Intersect(AllChangesFlagSet());
1017 result.Intersect(AllObservableSideEffectsFlagSet());
1018 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001019 }
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001020
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001021 Range* range() const { return range_; }
1022 bool HasRange() const { return range_ != NULL; }
ulan@chromium.org812308e2012-02-29 15:58:45 +00001023 void AddNewRange(Range* r, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024 void RemoveLastAddedRange();
ulan@chromium.org812308e2012-02-29 15:58:45 +00001025 void ComputeInitialRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001026
1027 // Representation helpers.
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001028 virtual Representation observed_input_representation(int index) {
1029 return Representation::None();
1030 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001031 virtual Representation RequiredInputRepresentation(int index) = 0;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001032 virtual void InferRepresentation(HInferRepresentation* h_infer);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001033
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001034 // This gives the instruction an opportunity to replace itself with an
1035 // instruction that does the same in some better way. To replace an
1036 // instruction with a new one, first add the new instruction to the graph,
1037 // then return it. Return NULL to have the instruction deleted.
1038 virtual HValue* Canonicalize() { return this; }
1039
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001040 bool Equals(HValue* other);
1041 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001042
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001043 // Compute unique ids upfront that is safe wrt GC and parallel recompilation.
1044 virtual void FinalizeUniqueValueId() { }
1045
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001046 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001047 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001048 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001049 void PrintTypeTo(StringStream* stream);
1050 void PrintRangeTo(StringStream* stream);
1051 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001052
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001053 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001054
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00001055 // Type information helpers.
1056 bool HasMonomorphicJSObjectType();
1057
1058 // TODO(mstarzinger): For now instructions can override this function to
1059 // specify statically known types, once HType can convey more information
1060 // it should be based on the HType.
1061 virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
1062
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063 // Updated the inferred type of this instruction and returns true if
1064 // it has changed.
1065 bool UpdateInferredType();
1066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001067 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001068
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001069 // This function must be overridden for instructions which have the
1070 // kTrackSideEffectDominators flag set, to track instructions that are
1071 // dominating side effects.
1072 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
1073 UNREACHABLE();
1074 }
1075
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001076 bool IsDead() const {
1077 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
1078 }
1079
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001081 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001082#endif
1083
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001084 bool IsRelationTrue(NumericRelation relation,
1085 HValue* other,
1086 int offset = 0,
1087 int scale = 0);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001088
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001089 bool TryGuaranteeRange(HValue* upper_bound);
1090 virtual bool TryDecompose(DecompositionResult* decomposition) {
1091 if (RedefinedOperand() != NULL) {
1092 return RedefinedOperand()->TryDecompose(decomposition);
1093 } else {
1094 return false;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001095 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001096 }
1097
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001098 protected:
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001099 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1100
1101 enum RangeGuaranteeDirection {
1102 DIRECTION_NONE = 0,
1103 DIRECTION_UPPER = 1,
1104 DIRECTION_LOWER = 2,
1105 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1106 };
1107 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1108 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
1109
ager@chromium.org378b34e2011-01-28 08:04:38 +00001110 // This function must be overridden for instructions with flag kUseGVN, to
1111 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001112 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00001113 UNREACHABLE();
1114 return false;
1115 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001116
1117 virtual Representation RepresentationFromInputs() {
1118 return representation();
1119 }
1120 Representation RepresentationFromUses();
1121 virtual void UpdateRepresentation(Representation new_rep,
1122 HInferRepresentation* h_infer,
1123 const char* reason);
1124 void AddDependantsToWorklist(HInferRepresentation* h_infer);
1125
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001126 virtual void RepresentationChanged(Representation to) { }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001127
ulan@chromium.org812308e2012-02-29 15:58:45 +00001128 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001129 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001130 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001131 void clear_block() {
1132 ASSERT(block_ != NULL);
1133 block_ = NULL;
1134 }
1135
1136 void set_representation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001137 ASSERT(representation_.IsNone() && !r.IsNone());
1138 representation_ = r;
1139 }
1140
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00001141 // Signature of a function testing if a HValue properly dominates another.
1142 typedef bool (*DominanceTest)(HValue*, HValue*);
1143
1144 // Simple implementation of DominanceTest implemented walking the chain
1145 // of Hinstructions (used in UpdateRedefinedUsesInner).
1146 static bool Dominates(HValue* dominator, HValue* dominated);
1147
1148 // A fast implementation of DominanceTest that works only for the
1149 // "current" instruction in the SetupInformativeDefinitions() phase.
1150 // During that phase we use a flag to mark processed instructions, and by
1151 // checking the flag we can quickly test if an instruction comes before or
1152 // after the "current" one.
1153 static bool TestDominanceUsingProcessedFlag(HValue* dominator,
1154 HValue* dominated);
1155
1156 // If we are redefining an operand, update all its dominated uses (the
1157 // function that checks if a use is dominated is the template argument).
1158 template<DominanceTest TestDominance>
1159 void UpdateRedefinedUsesInner() {
1160 HValue* input = RedefinedOperand();
1161 if (input != NULL) {
1162 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
1163 HValue* use = uses.value();
1164 if (TestDominance(this, use)) {
1165 use->SetOperandAt(uses.index(), this);
1166 }
1167 }
1168 }
1169 }
1170
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001171 // Informative definitions can override this method to state any numeric
1172 // relation they provide on the redefined value.
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001173 // Returns true if it is guaranteed that:
1174 // ((this + offset) >> scale) relation other
1175 virtual bool IsRelationTrueInternal(NumericRelation relation,
1176 HValue* other,
1177 int offset = 0,
1178 int scale = 0) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001179 return false;
1180 }
1181
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001182 static GVNFlagSet AllDependsOnFlagSet() {
1183 GVNFlagSet result;
1184 // Create changes mask.
1185#define ADD_FLAG(type) result.Add(kDependsOn##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001186 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1187 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001188#undef ADD_FLAG
1189 return result;
1190 }
1191
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001192 static GVNFlagSet AllChangesFlagSet() {
1193 GVNFlagSet result;
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001194 // Create changes mask.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001195#define ADD_FLAG(type) result.Add(kChanges##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001196 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1197 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001198#undef ADD_FLAG
1199 return result;
1200 }
1201
ager@chromium.org378b34e2011-01-28 08:04:38 +00001202 // A flag mask to mark an instruction as having arbitrary side effects.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001203 static GVNFlagSet AllSideEffectsFlagSet() {
1204 GVNFlagSet result = AllChangesFlagSet();
1205 result.Remove(kChangesOsrEntries);
1206 return result;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001207 }
1208
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001209 // A flag mask of all side effects that can make observable changes in
1210 // an executing program (i.e. are not safe to repeat, move or remove);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001211 static GVNFlagSet AllObservableSideEffectsFlagSet() {
1212 GVNFlagSet result = AllChangesFlagSet();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001213 result.Remove(kChangesNewSpacePromotion);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001214 result.Remove(kChangesElementsKind);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001215 result.Remove(kChangesElementsPointer);
1216 result.Remove(kChangesMaps);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001217 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001218 }
1219
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001220 // Remove the matching use from the use list if present. Returns the
1221 // removed list node or NULL.
1222 HUseListNode* RemoveUse(HValue* value, int index);
1223
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001224 void RegisterUse(int index, HValue* new_value);
1225
1226 HBasicBlock* block_;
1227
1228 // The id of this instruction in the hydrogen graph, assigned when first
1229 // added to the graph. Reflects creation order.
1230 int id_;
1231
1232 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001233 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001234 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001235 Range* range_;
1236 int flags_;
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001237 GVNFlagSet gvn_flags_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001238
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001239 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001240 virtual bool IsDeletable() const { return false; }
1241
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001242 DISALLOW_COPY_AND_ASSIGN(HValue);
1243};
1244
1245
1246class HInstruction: public HValue {
1247 public:
1248 HInstruction* next() const { return next_; }
1249 HInstruction* previous() const { return previous_; }
1250
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001251 virtual void PrintTo(StringStream* stream);
1252 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001253
1254 bool IsLinked() const { return block() != NULL; }
1255 void Unlink();
1256 void InsertBefore(HInstruction* next);
1257 void InsertAfter(HInstruction* previous);
1258
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001259 // The position is a write-once variable.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001260 int position() const { return position_; }
1261 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001262 void set_position(int position) {
1263 ASSERT(!has_position());
1264 ASSERT(position != RelocInfo::kNoPosition);
1265 position_ = position;
1266 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001267
ulan@chromium.org812308e2012-02-29 15:58:45 +00001268 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1269
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001270 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1271
1272#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001273 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001274#endif
1275
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001276 virtual bool IsCall() { return false; }
1277
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001278 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001279
1280 protected:
1281 HInstruction()
1282 : next_(NULL),
1283 previous_(NULL),
1284 position_(RelocInfo::kNoPosition) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001285 SetGVNFlag(kDependsOnOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001286 }
1287
1288 virtual void DeleteFromGraph() { Unlink(); }
1289
1290 private:
1291 void InitializeAsFirst(HBasicBlock* block) {
1292 ASSERT(!IsLinked());
1293 SetBlock(block);
1294 }
1295
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001296 void PrintMnemonicTo(StringStream* stream);
1297
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001298 HInstruction* next_;
1299 HInstruction* previous_;
1300 int position_;
1301
1302 friend class HBasicBlock;
1303};
1304
1305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001306template<int V>
1307class HTemplateInstruction : public HInstruction {
1308 public:
1309 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001310 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001311
1312 protected:
1313 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1314
1315 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001316 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001317};
1318
1319
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001320class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001321 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001322 virtual HBasicBlock* SuccessorAt(int i) = 0;
1323 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001324 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001325
1326 virtual void PrintDataTo(StringStream* stream);
1327
1328 HBasicBlock* FirstSuccessor() {
1329 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
1330 }
1331 HBasicBlock* SecondSuccessor() {
1332 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
1333 }
1334
1335 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
1336};
1337
1338
1339class HSuccessorIterator BASE_EMBEDDED {
1340 public:
1341 explicit HSuccessorIterator(HControlInstruction* instr)
1342 : instr_(instr), current_(0) { }
1343
1344 bool Done() { return current_ >= instr_->SuccessorCount(); }
1345 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
1346 void Advance() { current_++; }
1347
1348 private:
1349 HControlInstruction* instr_;
1350 int current_;
1351};
1352
1353
1354template<int S, int V>
1355class HTemplateControlInstruction: public HControlInstruction {
1356 public:
1357 int SuccessorCount() { return S; }
1358 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001359 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001361 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001362 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001363
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001364
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001365 protected:
1366 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1367
1368 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001369 EmbeddedContainer<HBasicBlock*, S> successors_;
1370 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001371};
1372
1373
1374class HBlockEntry: public HTemplateInstruction<0> {
1375 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001376 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001377 return Representation::None();
1378 }
1379
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001380 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001381};
1382
1383
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001384class HDummyUse: public HTemplateInstruction<1> {
1385 public:
1386 explicit HDummyUse(HValue* value) {
1387 SetOperandAt(0, value);
1388 // Pretend to be a Smi so that the HChange instructions inserted
1389 // before any use generate as little code as possible.
1390 set_representation(Representation::Tagged());
1391 set_type(HType::Smi());
1392 }
1393
1394 HValue* value() { return OperandAt(0); }
1395
1396 virtual Representation RequiredInputRepresentation(int index) {
1397 return Representation::None();
1398 }
1399
1400 virtual void PrintDataTo(StringStream* stream);
1401
1402 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1403};
1404
1405
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001406class HNumericConstraint : public HTemplateInstruction<2> {
1407 public:
1408 static HNumericConstraint* AddToGraph(HValue* constrained_value,
1409 NumericRelation relation,
1410 HValue* related_value,
1411 HInstruction* insertion_point = NULL);
1412
1413 HValue* constrained_value() { return OperandAt(0); }
1414 HValue* related_value() { return OperandAt(1); }
1415 NumericRelation relation() { return relation_; }
1416
1417 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00001418 virtual bool IsPurelyInformativeDefinition() { return true; }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001419
1420 virtual Representation RequiredInputRepresentation(int index) {
1421 return representation();
1422 }
1423
1424 virtual void PrintDataTo(StringStream* stream);
1425
1426 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001427 HValue* other_related_value,
1428 int offset = 0,
1429 int scale = 0) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001430 if (related_value() == other_related_value) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00001431 return relation().CompoundImplies(other_relation, offset, scale);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001432 } else {
1433 return false;
1434 }
1435 }
1436
1437 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1438
1439 private:
1440 HNumericConstraint(HValue* constrained_value,
1441 NumericRelation relation,
1442 HValue* related_value)
1443 : relation_(relation) {
1444 SetOperandAt(0, constrained_value);
1445 SetOperandAt(1, related_value);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001446 }
1447
1448 NumericRelation relation_;
1449};
1450
1451
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001452// We insert soft-deoptimize when we hit code with unknown typefeedback,
1453// so that we get a chance of re-optimizing with useful typefeedback.
1454// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1455class HSoftDeoptimize: public HTemplateInstruction<0> {
1456 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001457 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001458 return Representation::None();
1459 }
1460
1461 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
1462};
1463
1464
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001465class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001466 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001467 HDeoptimize(int environment_length, Zone* zone)
1468 : values_(environment_length, zone) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001469
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001470 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001471 return Representation::None();
1472 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001473
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001474 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001475 virtual HValue* OperandAt(int index) const { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001476 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001477
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001478 virtual int SuccessorCount() { return 0; }
1479 virtual HBasicBlock* SuccessorAt(int i) {
1480 UNREACHABLE();
1481 return NULL;
1482 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001483 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1484 UNREACHABLE();
1485 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001486
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001487 void AddEnvironmentValue(HValue* value, Zone* zone) {
1488 values_.Add(NULL, zone);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001489 SetOperandAt(values_.length() - 1, value);
1490 }
1491
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001492 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001493
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001494 enum UseEnvironment {
1495 kNoUses,
1496 kUseAll
1497 };
1498
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001499 protected:
1500 virtual void InternalSetOperandAt(int index, HValue* value) {
1501 values_[index] = value;
1502 }
1503
1504 private:
1505 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001506};
1507
1508
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001509class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001510 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001511 explicit HGoto(HBasicBlock* target) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001512 SetSuccessorAt(0, target);
1513 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001515 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001516 return Representation::None();
1517 }
1518
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001519 virtual void PrintDataTo(StringStream* stream);
1520
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001521 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522};
1523
1524
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001525class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001526 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001527 HUnaryControlInstruction(HValue* value,
1528 HBasicBlock* true_target,
1529 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001530 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001531 SetSuccessorAt(0, true_target);
1532 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001533 }
1534
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001535 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001536
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001537 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001538};
1539
1540
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001541class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001542 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001543 HBranch(HValue* value,
1544 HBasicBlock* true_target,
1545 HBasicBlock* false_target,
1546 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
1547 : HUnaryControlInstruction(value, true_target, false_target),
1548 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001549 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001550 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001551 explicit HBranch(HValue* value)
1552 : HUnaryControlInstruction(value, NULL, NULL) { }
1553
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001554
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001555 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001556 return Representation::None();
1557 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001558 virtual Representation observed_input_representation(int index);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001560 ToBooleanStub::Types expected_input_types() const {
1561 return expected_input_types_;
1562 }
1563
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001564 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001565
1566 private:
1567 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001568};
1569
1570
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001571class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001572 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001573 HCompareMap(HValue* value,
1574 Handle<Map> map,
1575 HBasicBlock* true_target,
1576 HBasicBlock* false_target)
1577 : HUnaryControlInstruction(value, true_target, false_target),
1578 map_(map) {
1579 ASSERT(true_target != NULL);
1580 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001581 ASSERT(!map.is_null());
1582 }
1583
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001584 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +00001585
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 Handle<Map> map() const { return map_; }
1587
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001588 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001589 return Representation::Tagged();
1590 }
1591
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001592 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001593
1594 private:
1595 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001596};
1597
1598
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001599class HReturn: public HTemplateControlInstruction<0, 3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001600 public:
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001601 HReturn(HValue* value, HValue* context, HValue* parameter_count) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001602 SetOperandAt(0, value);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001603 SetOperandAt(1, context);
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001604 SetOperandAt(2, parameter_count);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001605 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001606
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001607 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001608 return Representation::Tagged();
1609 }
1610
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001611 virtual void PrintDataTo(StringStream* stream);
1612
1613 HValue* value() { return OperandAt(0); }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001614 HValue* context() { return OperandAt(1); }
ulan@chromium.org6e196bf2013-03-13 09:38:22 +00001615 HValue* parameter_count() { return OperandAt(2); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001616
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001617 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001618};
1619
1620
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001621class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001622 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001623 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001624 return Representation::None();
1625 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001626
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001627 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001628};
1629
1630
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001631class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001632 public:
1633 explicit HUnaryOperation(HValue* value) {
1634 SetOperandAt(0, value);
1635 }
1636
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001637 static HUnaryOperation* cast(HValue* value) {
1638 return reinterpret_cast<HUnaryOperation*>(value);
1639 }
1640
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001641 HValue* value() const { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001642 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001643};
1644
1645
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001646class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001647 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001648 HThrow(HValue* context, HValue* value) {
1649 SetOperandAt(0, context);
1650 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001651 SetAllSideEffects();
1652 }
1653
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001654 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001655 return Representation::Tagged();
1656 }
1657
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001658 HValue* context() { return OperandAt(0); }
1659 HValue* value() { return OperandAt(1); }
1660
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001661 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001662};
1663
1664
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001665class HUseConst: public HUnaryOperation {
1666 public:
1667 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1668
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001669 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001670 return Representation::None();
1671 }
1672
1673 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1674};
1675
1676
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001677class HForceRepresentation: public HTemplateInstruction<1> {
1678 public:
1679 HForceRepresentation(HValue* value, Representation required_representation) {
1680 SetOperandAt(0, value);
1681 set_representation(required_representation);
1682 }
1683
1684 HValue* value() { return OperandAt(0); }
1685
1686 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1687
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001688 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001689 return representation(); // Same as the output representation.
1690 }
1691
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001692 virtual void PrintDataTo(StringStream* stream);
1693
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001694 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1695};
1696
1697
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001698class HChange: public HUnaryOperation {
1699 public:
1700 HChange(HValue* value,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001701 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001702 bool is_truncating,
1703 bool deoptimize_on_undefined)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001704 : HUnaryOperation(value) {
1705 ASSERT(!value->representation().IsNone() && !to.IsNone());
1706 ASSERT(!value->representation().Equals(to));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001707 set_representation(to);
1708 SetFlag(kUseGVN);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001709 if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001710 if (is_truncating) SetFlag(kTruncatingToInt32);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00001711 if (value->type().IsSmi()) {
1712 set_type(HType::Smi());
1713 } else {
1714 set_type(HType::TaggedNumber());
1715 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
1716 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717 }
1718
1719 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001720 virtual HType CalculateInferredType();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001721 virtual HValue* Canonicalize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001722
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001723 Representation from() const { return value()->representation(); }
1724 Representation to() const { return representation(); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001725 bool deoptimize_on_undefined() const {
1726 return CheckFlag(kDeoptimizeOnUndefined);
1727 }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001728 bool deoptimize_on_minus_zero() const {
1729 return CheckFlag(kBailoutOnMinusZero);
1730 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001731 virtual Representation RequiredInputRepresentation(int index) {
1732 return from();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001733 }
1734
ulan@chromium.org812308e2012-02-29 15:58:45 +00001735 virtual Range* InferRange(Zone* zone);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001736
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001737 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001738
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001739 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001740
1741 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001742 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001743
1744 private:
1745 virtual bool IsDeletable() const {
1746 return !from().IsTagged() || value()->type().IsSmi();
1747 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001748};
1749
1750
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001751class HClampToUint8: public HUnaryOperation {
1752 public:
1753 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001754 : HUnaryOperation(value) {
1755 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001756 SetFlag(kUseGVN);
1757 }
1758
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001759 virtual Representation RequiredInputRepresentation(int index) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001760 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001761 }
1762
1763 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1764
1765 protected:
1766 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001767
1768 private:
1769 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001770};
1771
1772
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001773enum RemovableSimulate {
1774 REMOVABLE_SIMULATE,
1775 FIXED_SIMULATE
1776};
1777
1778
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001779class HSimulate: public HInstruction {
1780 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001781 HSimulate(BailoutId ast_id,
1782 int pop_count,
1783 Zone* zone,
1784 RemovableSimulate removable)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001785 : ast_id_(ast_id),
1786 pop_count_(pop_count),
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001787 values_(2, zone),
1788 assigned_indexes_(2, zone),
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001789 zone_(zone),
1790 removable_(removable) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791 virtual ~HSimulate() {}
1792
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001793 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001795 bool HasAstId() const { return !ast_id_.IsNone(); }
1796 BailoutId ast_id() const { return ast_id_; }
1797 void set_ast_id(BailoutId id) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001798 ASSERT(!HasAstId());
1799 ast_id_ = id;
1800 }
1801
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001802 int pop_count() const { return pop_count_; }
1803 const ZoneList<HValue*>* values() const { return &values_; }
1804 int GetAssignedIndexAt(int index) const {
1805 ASSERT(HasAssignedIndexAt(index));
1806 return assigned_indexes_[index];
1807 }
1808 bool HasAssignedIndexAt(int index) const {
1809 return assigned_indexes_[index] != kNoIndex;
1810 }
1811 void AddAssignedValue(int index, HValue* value) {
1812 AddValue(index, value);
1813 }
1814 void AddPushedValue(HValue* value) {
1815 AddValue(kNoIndex, value);
1816 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001817 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001818 virtual HValue* OperandAt(int index) const { return values_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001819
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001820 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001821 return Representation::None();
1822 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001823
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00001824 void MergeWith(ZoneList<HSimulate*>* list);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001825 bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
1826
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001827 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001828
1829#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001830 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001831#endif
1832
1833 protected:
1834 virtual void InternalSetOperandAt(int index, HValue* value) {
1835 values_[index] = value;
1836 }
1837
1838 private:
1839 static const int kNoIndex = -1;
1840 void AddValue(int index, HValue* value) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001841 assigned_indexes_.Add(index, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001842 // Resize the list of pushed values.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001843 values_.Add(NULL, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001844 // Set the operand through the base method in HValue to make sure that the
1845 // use lists are correctly updated.
1846 SetOperandAt(values_.length() - 1, value);
1847 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001848 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001849 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850 ZoneList<HValue*> values_;
1851 ZoneList<int> assigned_indexes_;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001852 Zone* zone_;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001853 RemovableSimulate removable_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001854};
1855
1856
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001857class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001858 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001859 enum Type {
1860 kFunctionEntry,
1861 kBackwardsBranch
1862 };
1863
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001864 HStackCheck(HValue* context, Type type) : type_(type) {
1865 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001866 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001867 }
1868
1869 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001870
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001871 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001872 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001873 }
1874
ager@chromium.org04921a82011-06-27 13:21:41 +00001875 void Eliminate() {
1876 // The stack check eliminator might try to eliminate the same stack
1877 // check instruction multiple times.
1878 if (IsLinked()) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001879 DeleteAndReplaceWith(NULL);
ager@chromium.org04921a82011-06-27 13:21:41 +00001880 }
1881 }
1882
1883 bool is_function_entry() { return type_ == kFunctionEntry; }
1884 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1885
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001886 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001887
1888 private:
1889 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001890};
1891
1892
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001893enum InliningKind {
1894 NORMAL_RETURN, // Normal function/method call and return.
1895 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
1896 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001897 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001898 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
1899};
1900
1901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001902class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001903 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001904 HEnterInlined(Handle<JSFunction> closure,
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001905 int arguments_count,
danno@chromium.org40cb8782011-05-25 07:58:50 +00001906 FunctionLiteral* function,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001907 InliningKind inlining_kind,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001908 Variable* arguments_var,
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001909 ZoneList<HValue*>* arguments_values,
1910 bool undefined_receiver)
danno@chromium.org40cb8782011-05-25 07:58:50 +00001911 : closure_(closure),
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001912 arguments_count_(arguments_count),
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001913 arguments_pushed_(false),
danno@chromium.org40cb8782011-05-25 07:58:50 +00001914 function_(function),
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001915 inlining_kind_(inlining_kind),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001916 arguments_var_(arguments_var),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001917 arguments_values_(arguments_values),
1918 undefined_receiver_(undefined_receiver) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 }
1920
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001921 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001922
1923 Handle<JSFunction> closure() const { return closure_; }
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001924 int arguments_count() const { return arguments_count_; }
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001925 bool arguments_pushed() const { return arguments_pushed_; }
1926 void set_arguments_pushed() { arguments_pushed_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001927 FunctionLiteral* function() const { return function_; }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001928 InliningKind inlining_kind() const { return inlining_kind_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001929 bool undefined_receiver() const { return undefined_receiver_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001930
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001931 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001932 return Representation::None();
1933 }
1934
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001935 Variable* arguments_var() { return arguments_var_; }
1936 ZoneList<HValue*>* arguments_values() { return arguments_values_; }
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001937
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001938 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001939
1940 private:
1941 Handle<JSFunction> closure_;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001942 int arguments_count_;
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001943 bool arguments_pushed_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001944 FunctionLiteral* function_;
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001945 InliningKind inlining_kind_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001946 Variable* arguments_var_;
1947 ZoneList<HValue*>* arguments_values_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001948 bool undefined_receiver_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001949};
1950
1951
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001952class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001953 public:
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00001954 HLeaveInlined() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001955
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001956 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001957 return Representation::None();
1958 }
1959
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001960 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001961};
1962
1963
1964class HPushArgument: public HUnaryOperation {
1965 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001966 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1967 set_representation(Representation::Tagged());
1968 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001969
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001970 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001971 return Representation::Tagged();
1972 }
1973
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001974 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001975
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001976 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001977};
1978
1979
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001980class HThisFunction: public HTemplateInstruction<0> {
1981 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001982 HThisFunction() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001983 set_representation(Representation::Tagged());
1984 SetFlag(kUseGVN);
1985 }
1986
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001987 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001988 return Representation::None();
1989 }
1990
1991 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1992
1993 protected:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001994 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001995
1996 private:
1997 virtual bool IsDeletable() const { return true; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001998};
1999
2000
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002001class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002002 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002003 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002004 set_representation(Representation::Tagged());
2005 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002006 }
2007
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002008 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002009 return Representation::None();
2010 }
2011
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002012 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002013
2014 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002015 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002016
2017 private:
2018 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002019};
2020
2021
2022class HOuterContext: public HUnaryOperation {
2023 public:
2024 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
2025 set_representation(Representation::Tagged());
2026 SetFlag(kUseGVN);
2027 }
2028
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002029 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002030
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002031 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002032 return Representation::Tagged();
2033 }
2034
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002035 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002036 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002037
2038 private:
2039 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002040};
2041
2042
yangguo@chromium.org56454712012-02-16 15:33:53 +00002043class HDeclareGlobals: public HUnaryOperation {
2044 public:
2045 HDeclareGlobals(HValue* context,
2046 Handle<FixedArray> pairs,
2047 int flags)
2048 : HUnaryOperation(context),
2049 pairs_(pairs),
2050 flags_(flags) {
2051 set_representation(Representation::Tagged());
2052 SetAllSideEffects();
2053 }
2054
2055 HValue* context() { return OperandAt(0); }
2056 Handle<FixedArray> pairs() const { return pairs_; }
2057 int flags() const { return flags_; }
2058
2059 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
2060
2061 virtual Representation RequiredInputRepresentation(int index) {
2062 return Representation::Tagged();
2063 }
2064 private:
2065 Handle<FixedArray> pairs_;
2066 int flags_;
2067};
2068
2069
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002070class HGlobalObject: public HUnaryOperation {
2071 public:
2072 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
2073 set_representation(Representation::Tagged());
2074 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002075 }
2076
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002077 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002078
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002079 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002080 return Representation::Tagged();
2081 }
2082
ager@chromium.org378b34e2011-01-28 08:04:38 +00002083 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002084 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002085
2086 private:
2087 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002088};
2089
2090
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002091class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002093 explicit HGlobalReceiver(HValue* global_object)
2094 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095 set_representation(Representation::Tagged());
2096 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002097 }
2098
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002099 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002100
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002101 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002102 return Representation::Tagged();
2103 }
2104
ager@chromium.org378b34e2011-01-28 08:04:38 +00002105 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002106 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002107
2108 private:
2109 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002110};
2111
2112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113template <int V>
2114class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002116 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002117 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
2118 this->set_representation(Representation::Tagged());
2119 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002120 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002121
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002122 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002123
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002124 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002125
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002126 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002128 private:
2129 int argument_count_;
2130};
2131
2132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002133class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002134 public:
2135 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002136 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002137 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002138 }
2139
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002140 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002141 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002142 }
2143
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002144 virtual void PrintDataTo(StringStream* stream);
2145
2146 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002147};
2148
2149
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002150class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002151 public:
2152 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002153 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002154 SetOperandAt(0, first);
2155 SetOperandAt(1, second);
2156 }
2157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002158 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002159
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002160 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002161 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002162 }
2163
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002164 HValue* first() { return OperandAt(0); }
2165 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002166};
2167
2168
danno@chromium.org160a7b02011-04-18 15:51:38 +00002169class HInvokeFunction: public HBinaryCall {
2170 public:
2171 HInvokeFunction(HValue* context, HValue* function, int argument_count)
2172 : HBinaryCall(context, function, argument_count) {
2173 }
2174
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002175 HInvokeFunction(HValue* context,
2176 HValue* function,
2177 Handle<JSFunction> known_function,
2178 int argument_count)
2179 : HBinaryCall(context, function, argument_count),
2180 known_function_(known_function) {
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002181 formal_parameter_count_ = known_function.is_null()
2182 ? 0 : known_function->shared()->formal_parameter_count();
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002183 }
2184
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002185 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00002186 return Representation::Tagged();
2187 }
2188
2189 HValue* context() { return first(); }
2190 HValue* function() { return second(); }
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002191 Handle<JSFunction> known_function() { return known_function_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002192 int formal_parameter_count() const { return formal_parameter_count_; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00002193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002194 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002195
2196 private:
2197 Handle<JSFunction> known_function_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002198 int formal_parameter_count_;
danno@chromium.org160a7b02011-04-18 15:51:38 +00002199};
2200
2201
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002202class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002203 public:
2204 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002205 : HCall<0>(argument_count),
2206 function_(function),
2207 formal_parameter_count_(function->shared()->formal_parameter_count()) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002208
2209 Handle<JSFunction> function() const { return function_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002210 int formal_parameter_count() const { return formal_parameter_count_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002211
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002212 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002213 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002214 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002215 }
2216
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002217 virtual void PrintDataTo(StringStream* stream);
2218
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002219 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002220 return Representation::None();
2221 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002222
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002223 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002224
2225 private:
2226 Handle<JSFunction> function_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002227 int formal_parameter_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002228};
2229
2230
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002231class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002232 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002233 HCallKeyed(HValue* context, HValue* key, int argument_count)
2234 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002235 }
2236
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002237 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002238 return Representation::Tagged();
2239 }
2240
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002241 HValue* context() { return first(); }
2242 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002244 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002245};
2246
2247
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002248class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002249 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002250 HCallNamed(HValue* context, Handle<String> name, int argument_count)
2251 : HUnaryCall(context, argument_count), name_(name) {
2252 }
2253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002254 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002256 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002257 Handle<String> name() const { return name_; }
2258
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002259 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002260
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002261 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002262 return Representation::Tagged();
2263 }
2264
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265 private:
2266 Handle<String> name_;
2267};
2268
2269
danno@chromium.orgc612e022011-11-10 11:38:15 +00002270class HCallFunction: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002271 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +00002272 HCallFunction(HValue* context, HValue* function, int argument_count)
2273 : HBinaryCall(context, function, argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002274 }
2275
danno@chromium.orgc612e022011-11-10 11:38:15 +00002276 HValue* context() { return first(); }
2277 HValue* function() { return second(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002278
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002279 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002280 return Representation::Tagged();
2281 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002282
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002283 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002284};
2285
2286
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002287class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002288 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002289 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2290 : HUnaryCall(context, argument_count), name_(name) {
2291 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002293 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002295 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002296 Handle<String> name() const { return name_; }
2297
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002298 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002299 return Representation::Tagged();
2300 }
2301
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002302 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002303
2304 private:
2305 Handle<String> name_;
2306};
2307
2308
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002309class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002311 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002312 : HCall<0>(argument_count),
2313 target_(target),
2314 formal_parameter_count_(target->shared()->formal_parameter_count()) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002315
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002316 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002317
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002318 Handle<JSFunction> target() const { return target_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002319 int formal_parameter_count() const { return formal_parameter_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002320
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002321 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002322 return Representation::None();
2323 }
2324
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002325 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326
2327 private:
2328 Handle<JSFunction> target_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00002329 int formal_parameter_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002330};
2331
2332
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002333class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002335 HCallNew(HValue* context, HValue* constructor, int argument_count)
2336 : HBinaryCall(context, constructor, argument_count) {
2337 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002338
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002339 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002340 return Representation::Tagged();
2341 }
2342
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002343 HValue* context() { return first(); }
2344 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002345
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002346 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002347};
2348
2349
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002350class HCallNewArray: public HCallNew {
2351 public:
2352 HCallNewArray(HValue* context, HValue* constructor, int argument_count,
2353 Handle<JSGlobalPropertyCell> type_cell)
2354 : HCallNew(context, constructor, argument_count),
2355 type_cell_(type_cell) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002356 elements_kind_ = static_cast<ElementsKind>(
2357 Smi::cast(type_cell->value())->value());
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002358 }
2359
2360 Handle<JSGlobalPropertyCell> property_cell() const {
2361 return type_cell_;
2362 }
2363
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002364 ElementsKind elements_kind() const { return elements_kind_; }
2365
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002366 DECLARE_CONCRETE_INSTRUCTION(CallNewArray)
2367
2368 private:
ulan@chromium.org57ff8812013-05-10 08:16:55 +00002369 ElementsKind elements_kind_;
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002370 Handle<JSGlobalPropertyCell> type_cell_;
2371};
2372
2373
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002374class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002375 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002376 HCallRuntime(HValue* context,
2377 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002378 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002379 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002380 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
2381 SetOperandAt(0, context);
2382 }
2383
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002384 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002385
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002386 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002387 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002388 Handle<String> name() const { return name_; }
2389
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002390 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002391 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002392 }
2393
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002394 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395
2396 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002397 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002398 Handle<String> name_;
2399};
2400
2401
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002402class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002403 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002404 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002405 set_type(HType::Smi());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002406 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002407 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002408 SetGVNFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002409 }
2410
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002411 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002412 return Representation::Tagged();
2413 }
2414
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002415 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002416
2417 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002418 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002419
2420 private:
2421 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002422};
2423
2424
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002425class HMapEnumLength: public HUnaryOperation {
2426 public:
2427 explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
2428 set_type(HType::Smi());
2429 set_representation(Representation::Tagged());
2430 SetFlag(kUseGVN);
2431 SetGVNFlag(kDependsOnMaps);
2432 }
2433
2434 virtual Representation RequiredInputRepresentation(int index) {
2435 return Representation::Tagged();
2436 }
2437
2438 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2439
2440 protected:
2441 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002442
2443 private:
2444 virtual bool IsDeletable() const { return true; }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002445};
2446
2447
whesse@chromium.org7b260152011-06-20 15:33:18 +00002448class HElementsKind: public HUnaryOperation {
2449 public:
2450 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
2451 set_representation(Representation::Integer32());
2452 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002453 SetGVNFlag(kDependsOnElementsKind);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002454 }
2455
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002456 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002457 return Representation::Tagged();
2458 }
2459
2460 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
2461
2462 protected:
2463 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002464
2465 private:
2466 virtual bool IsDeletable() const { return true; }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002467};
2468
2469
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470class HBitNot: public HUnaryOperation {
2471 public:
2472 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
2473 set_representation(Representation::Integer32());
2474 SetFlag(kUseGVN);
2475 SetFlag(kTruncatingToInt32);
2476 }
2477
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002478 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002479 return Representation::Integer32();
2480 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002481 virtual Representation observed_input_representation(int index) {
2482 return Representation::Integer32();
2483 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002484 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002485
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00002486 virtual HValue* Canonicalize();
2487
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002488 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002489
2490 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002491 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002492
2493 private:
2494 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002495};
2496
2497
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002498class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002499 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002500 static HInstruction* New(Zone* zone,
2501 HValue* context,
2502 HValue* value,
2503 BuiltinFunctionId op);
2504
2505 HValue* context() { return OperandAt(0); }
2506 HValue* value() { return OperandAt(1); }
2507
2508 virtual void PrintDataTo(StringStream* stream);
2509
2510 virtual HType CalculateInferredType();
2511
2512 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2513
2514 virtual Representation RequiredInputRepresentation(int index) {
2515 if (index == 0) {
2516 return Representation::Tagged();
2517 } else {
2518 switch (op_) {
2519 case kMathFloor:
2520 case kMathRound:
2521 case kMathSqrt:
2522 case kMathPowHalf:
2523 case kMathLog:
2524 case kMathExp:
2525 case kMathSin:
2526 case kMathCos:
2527 case kMathTan:
2528 return Representation::Double();
2529 case kMathAbs:
2530 return representation();
2531 default:
2532 UNREACHABLE();
2533 return Representation::None();
2534 }
2535 }
2536 }
2537
2538 virtual HValue* Canonicalize();
2539
2540 BuiltinFunctionId op() const { return op_; }
2541 const char* OpName() const;
2542
2543 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
2544
2545 protected:
2546 virtual bool DataEquals(HValue* other) {
2547 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2548 return op_ == b->op();
2549 }
2550
2551 private:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002552 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2553 : op_(op) {
2554 SetOperandAt(0, context);
2555 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002556 switch (op) {
2557 case kMathFloor:
2558 case kMathRound:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002559 set_representation(Representation::Integer32());
2560 break;
2561 case kMathAbs:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002562 // Not setting representation here: it is None intentionally.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002563 SetFlag(kFlexibleRepresentation);
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002564 // TODO(svenpanne) This flag is actually only needed if representation()
2565 // is tagged, and not when it is an unboxed double or unboxed integer.
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002566 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002567 break;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002568 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00002569 case kMathSin:
2570 case kMathCos:
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00002571 case kMathTan:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002572 set_representation(Representation::Double());
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002573 // These operations use the TranscendentalCache, so they may allocate.
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002574 SetGVNFlag(kChangesNewSpacePromotion);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002575 break;
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002576 case kMathExp:
danno@chromium.orgca29dd82013-04-26 11:59:48 +00002577 case kMathSqrt:
2578 case kMathPowHalf:
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002579 set_representation(Representation::Double());
2580 break;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002581 default:
2582 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 }
2584 SetFlag(kUseGVN);
2585 }
2586
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002587 virtual bool IsDeletable() const { return true; }
2588
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002589 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002590};
2591
2592
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002593class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002594 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002595 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002596 : HUnaryOperation(value) {
2597 set_representation(Representation::External());
2598 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002599 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002600 // change once set, so it's no necessary to introduce any additional
2601 // dependencies on top of the inputs.
2602 SetFlag(kUseGVN);
2603 }
2604
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002605 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002606 return Representation::Tagged();
2607 }
2608
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002609 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002610
2611 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002612 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002613
2614 private:
2615 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002616};
2617
2618
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002619class HCheckMaps: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620 public:
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002621 static HCheckMaps* New(HValue* value, Handle<Map> map, Zone* zone,
2622 HValue *typecheck = NULL) {
2623 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2624 check_map->map_set_.Add(map, zone);
2625 return check_map;
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002626 }
2627
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002628 static HCheckMaps* New(HValue* value, SmallMapList* maps, Zone* zone,
2629 HValue *typecheck = NULL) {
2630 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
2631 for (int i = 0; i < maps->length(); i++) {
2632 check_map->map_set_.Add(maps->at(i), zone);
2633 }
2634 check_map->map_set_.Sort();
2635 return check_map;
2636 }
2637
2638 static HCheckMaps* NewWithTransitions(HValue* value, Handle<Map> map,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002639 Zone* zone) {
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002640 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, value);
2641 check_map->map_set_.Add(map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002642
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002643 // Since transitioned elements maps of the initial map don't fail the map
2644 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2645 check_map->ClearGVNFlag(kDependsOnElementsKind);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002646
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002647 ElementsKind kind = map->elements_kind();
2648 bool packed = IsFastPackedElementsKind(kind);
2649 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2650 kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2651 Map* transitioned_map =
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002652 map->LookupElementsTransitionMap(kind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002653 if (transitioned_map) {
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002654 check_map->map_set_.Add(Handle<Map>(transitioned_map), zone);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002655 }
2656 };
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002657 check_map->map_set_.Sort();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002658 return check_map;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659 }
2660
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002661 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002662 return Representation::Tagged();
2663 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002664 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002665 virtual void PrintDataTo(StringStream* stream);
2666 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002667
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002668 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002669 SmallMapList* map_set() { return &map_set_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002670
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002671 virtual void FinalizeUniqueValueId();
2672
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002673 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002674
2675 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002676 virtual bool DataEquals(HValue* other) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002677 ASSERT_EQ(map_set_.length(), map_unique_ids_.length());
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002678 HCheckMaps* b = HCheckMaps::cast(other);
2679 // Relies on the fact that map_set has been sorted before.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002680 if (map_unique_ids_.length() != b->map_unique_ids_.length()) {
2681 return false;
2682 }
2683 for (int i = 0; i < map_unique_ids_.length(); i++) {
2684 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) {
2685 return false;
2686 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002687 }
2688 return true;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689 }
2690
2691 private:
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00002692 // Clients should use one of the static New* methods above.
2693 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck)
2694 : map_unique_ids_(0, zone) {
2695 SetOperandAt(0, value);
2696 // Use the object value for the dependency if NULL is passed.
2697 // TODO(titzer): do GVN flags already express this dependency?
2698 SetOperandAt(1, typecheck != NULL ? typecheck : value);
2699 set_representation(Representation::Tagged());
2700 SetFlag(kUseGVN);
2701 SetFlag(kTrackSideEffectDominators);
2702 SetGVNFlag(kDependsOnMaps);
2703 SetGVNFlag(kDependsOnElementsKind);
2704 }
2705
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002706 SmallMapList map_set_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002707 ZoneList<UniqueValueId> map_unique_ids_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708};
2709
2710
2711class HCheckFunction: public HUnaryOperation {
2712 public:
2713 HCheckFunction(HValue* value, Handle<JSFunction> function)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002714 : HUnaryOperation(value), target_(function), target_unique_id_() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715 set_representation(Representation::Tagged());
2716 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002717 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718 }
2719
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002720 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002721 return Representation::Tagged();
2722 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723 virtual void PrintDataTo(StringStream* stream);
2724 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725
2726#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002727 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728#endif
2729
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002730 virtual void FinalizeUniqueValueId() {
2731 target_unique_id_ = UniqueValueId(target_);
2732 }
2733
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002734 Handle<JSFunction> target() const { return target_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002735 bool target_in_new_space() const { return target_in_new_space_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002737 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002738
2739 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002740 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002741 HCheckFunction* b = HCheckFunction::cast(other);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002742 return target_unique_id_ == b->target_unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743 }
2744
2745 private:
2746 Handle<JSFunction> target_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002747 UniqueValueId target_unique_id_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002748 bool target_in_new_space_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002749};
2750
2751
2752class HCheckInstanceType: public HUnaryOperation {
2753 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002754 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2755 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002756 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002757 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2758 return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002759 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002760 static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2761 return new(zone) HCheckInstanceType(value, IS_STRING);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002762 }
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002763 static HCheckInstanceType* NewIsInternalizedString(
2764 HValue* value, Zone* zone) {
2765 return new(zone) HCheckInstanceType(value, IS_INTERNALIZED_STRING);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766 }
2767
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002768 virtual void PrintDataTo(StringStream* stream);
2769
2770 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002771 return Representation::Tagged();
2772 }
2773
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002774 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002775
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002776 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2777 void GetCheckInterval(InstanceType* first, InstanceType* last);
2778 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002779
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002780 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002781
2782 protected:
2783 // TODO(ager): It could be nice to allow the ommision of instance
2784 // type checks if we have already performed an instance type check
2785 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002786 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002788 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789 }
2790
2791 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002792 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002793 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002794 IS_JS_ARRAY,
2795 IS_STRING,
yangguo@chromium.org4a9f6552013-03-04 14:46:33 +00002796 IS_INTERNALIZED_STRING,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002797 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2798 };
2799
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002800 const char* GetCheckName();
2801
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002802 HCheckInstanceType(HValue* value, Check check)
2803 : HUnaryOperation(value), check_(check) {
2804 set_representation(Representation::Tagged());
2805 SetFlag(kUseGVN);
2806 }
2807
2808 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809};
2810
2811
2812class HCheckNonSmi: public HUnaryOperation {
2813 public:
2814 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2815 set_representation(Representation::Tagged());
2816 SetFlag(kUseGVN);
2817 }
2818
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002819 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820 return Representation::Tagged();
2821 }
2822
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002823 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824
2825#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002826 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002827#endif
2828
danno@chromium.org160a7b02011-04-18 15:51:38 +00002829 virtual HValue* Canonicalize() {
2830 HType value_type = value()->type();
2831 if (!value_type.IsUninitialized() &&
2832 (value_type.IsHeapNumber() ||
2833 value_type.IsString() ||
2834 value_type.IsBoolean() ||
2835 value_type.IsNonPrimitive())) {
2836 return NULL;
2837 }
2838 return this;
2839 }
2840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002841 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002842
2843 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002844 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002845};
2846
2847
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002848class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002849 public:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002850 HCheckPrototypeMaps(Handle<JSObject> prototype,
2851 Handle<JSObject> holder,
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002852 Zone* zone)
2853 : prototypes_(2, zone),
2854 maps_(2, zone),
2855 first_prototype_unique_id_(),
2856 last_prototype_unique_id_() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002857 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002858 SetGVNFlag(kDependsOnMaps);
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002859 // Keep a list of all objects on the prototype chain up to the holder
2860 // and the expected maps.
2861 while (true) {
2862 prototypes_.Add(prototype, zone);
2863 maps_.Add(Handle<Map>(prototype->map()), zone);
2864 if (prototype.is_identical_to(holder)) break;
2865 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
2866 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002867 }
2868
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002869 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
2870
2871 ZoneList<Handle<Map> >* maps() { return &maps_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002872
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002873 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002874
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002875 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002876 return Representation::None();
2877 }
2878
danno@chromium.org81cac2b2012-07-10 11:28:27 +00002879 virtual void PrintDataTo(StringStream* stream);
2880
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002881 virtual intptr_t Hashcode() {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002882 return first_prototype_unique_id_.Hashcode() * 17 +
2883 last_prototype_unique_id_.Hashcode();
2884 }
2885
2886 virtual void FinalizeUniqueValueId() {
2887 first_prototype_unique_id_ = UniqueValueId(prototypes_.first());
2888 last_prototype_unique_id_ = UniqueValueId(prototypes_.last());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002889 }
2890
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002891 bool CanOmitPrototypeChecks() {
2892 for (int i = 0; i < maps()->length(); i++) {
2893 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false;
2894 }
2895 return true;
2896 }
2897
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002898 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002899 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002900 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002901 return first_prototype_unique_id_ == b->first_prototype_unique_id_ &&
2902 last_prototype_unique_id_ == b->last_prototype_unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903 }
2904
2905 private:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002906 ZoneList<Handle<JSObject> > prototypes_;
2907 ZoneList<Handle<Map> > maps_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00002908 UniqueValueId first_prototype_unique_id_;
2909 UniqueValueId last_prototype_unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002910};
2911
2912
2913class HCheckSmi: public HUnaryOperation {
2914 public:
2915 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2916 set_representation(Representation::Tagged());
2917 SetFlag(kUseGVN);
2918 }
2919
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002920 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002921 return Representation::Tagged();
2922 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002923 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924
2925#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002926 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002927#endif
2928
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002929 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002930
2931 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002932 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933};
2934
2935
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002936class HCheckSmiOrInt32: public HUnaryOperation {
2937 public:
2938 explicit HCheckSmiOrInt32(HValue* value) : HUnaryOperation(value) {
2939 SetFlag(kFlexibleRepresentation);
2940 SetFlag(kUseGVN);
2941 }
2942
2943 virtual int RedefinedOperandIndex() { return 0; }
2944 virtual Representation RequiredInputRepresentation(int index) {
2945 return representation();
2946 }
2947 virtual void InferRepresentation(HInferRepresentation* h_infer);
2948
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002949 virtual Representation observed_input_representation(int index) {
2950 return Representation::Integer32();
2951 }
2952
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002953 virtual HValue* Canonicalize() {
ulan@chromium.org750145a2013-03-07 15:14:13 +00002954 if (representation().IsTagged() && !value()->type().IsSmi()) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002955 return this;
2956 } else {
2957 return value();
2958 }
2959 }
2960
2961 DECLARE_CONCRETE_INSTRUCTION(CheckSmiOrInt32)
2962
2963 protected:
2964 virtual bool DataEquals(HValue* other) { return true; }
2965};
2966
2967
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002968class HPhi: public HValue {
2969 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002970 HPhi(int merged_index, Zone* zone)
2971 : inputs_(2, zone),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002972 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002973 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002974 is_live_(false),
2975 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002976 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2977 non_phi_uses_[i] = 0;
2978 indirect_uses_[i] = 0;
2979 }
2980 ASSERT(merged_index >= 0);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002981 SetFlag(kFlexibleRepresentation);
2982 }
2983
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002984 virtual Representation RepresentationFromInputs();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002985
ulan@chromium.org812308e2012-02-29 15:58:45 +00002986 virtual Range* InferRange(Zone* zone);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002987 virtual void InferRepresentation(HInferRepresentation* h_infer);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002988 Representation RepresentationFromUseRequirements();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002989 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002990 return representation();
2991 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002992 virtual HType CalculateInferredType();
2993 virtual int OperandCount() { return inputs_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002994 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002995 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002996 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002997 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002998
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002999 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003000
3001 int merged_index() const { return merged_index_; }
3002
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003003 virtual void AddInformativeDefinitions();
3004
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003005 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003006
3007#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00003008 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003009#endif
3010
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 void InitRealUses(int id);
3012 void AddNonPhiUsesFrom(HPhi* other);
3013 void AddIndirectUsesTo(int* use_count);
3014
3015 int tagged_non_phi_uses() const {
3016 return non_phi_uses_[Representation::kTagged];
3017 }
3018 int int32_non_phi_uses() const {
3019 return non_phi_uses_[Representation::kInteger32];
3020 }
3021 int double_non_phi_uses() const {
3022 return non_phi_uses_[Representation::kDouble];
3023 }
3024 int tagged_indirect_uses() const {
3025 return indirect_uses_[Representation::kTagged];
3026 }
3027 int int32_indirect_uses() const {
3028 return indirect_uses_[Representation::kInteger32];
3029 }
3030 int double_indirect_uses() const {
3031 return indirect_uses_[Representation::kDouble];
3032 }
3033 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003034 bool is_live() { return is_live_; }
3035 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003036
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003037 static HPhi* cast(HValue* value) {
3038 ASSERT(value->IsPhi());
3039 return reinterpret_cast<HPhi*>(value);
3040 }
3041 virtual Opcode opcode() const { return HValue::kPhi; }
3042
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003043 virtual bool IsConvertibleToInteger() const {
3044 return is_convertible_to_integer_;
3045 }
3046
3047 void set_is_convertible_to_integer(bool b) {
3048 is_convertible_to_integer_ = b;
3049 }
3050
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003051 bool AllOperandsConvertibleToInteger() {
3052 for (int i = 0; i < OperandCount(); ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003053 if (!OperandAt(i)->IsConvertibleToInteger()) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003054 if (FLAG_trace_representation) {
3055 HValue* input = OperandAt(i);
3056 PrintF("#%d %s: Input #%d %s at %d is NCTI\n",
3057 id(), Mnemonic(), input->id(), input->Mnemonic(), i);
3058 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003059 return false;
3060 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003061 }
3062 return true;
3063 }
3064
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003065 void SimplifyConstantInputs();
3066
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067 protected:
3068 virtual void DeleteFromGraph();
3069 virtual void InternalSetOperandAt(int index, HValue* value) {
3070 inputs_[index] = value;
3071 }
3072
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003073 virtual bool IsRelationTrueInternal(NumericRelation relation,
3074 HValue* other,
3075 int offset = 0,
3076 int scale = 0);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003077
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 private:
3079 ZoneList<HValue*> inputs_;
3080 int merged_index_;
3081
3082 int non_phi_uses_[Representation::kNumRepresentations];
3083 int indirect_uses_[Representation::kNumRepresentations];
3084 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003085 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003086 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087};
3088
3089
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003090class HInductionVariableAnnotation : public HUnaryOperation {
3091 public:
3092 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3093 NumericRelation relation,
3094 int operand_index);
3095
3096 NumericRelation relation() { return relation_; }
3097 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
3098
3099 virtual int RedefinedOperandIndex() { return 0; }
3100 virtual bool IsPurelyInformativeDefinition() { return true; }
3101 virtual Representation RequiredInputRepresentation(int index) {
3102 return representation();
3103 }
3104
3105 virtual void PrintDataTo(StringStream* stream);
3106
3107 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003108 HValue* other_related_value,
3109 int offset = 0,
3110 int scale = 0) {
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003111 if (induction_base() == other_related_value) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003112 return relation().CompoundImplies(other_relation, offset, scale);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003113 } else {
3114 return false;
3115 }
3116 }
3117
3118 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3119
3120 private:
3121 HInductionVariableAnnotation(HPhi* phi,
3122 NumericRelation relation,
3123 int operand_index)
3124 : HUnaryOperation(phi),
3125 phi_(phi), relation_(relation), operand_index_(operand_index) {
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003126 }
3127
3128 // We need to store the phi both here and in the instruction operand because
3129 // the operand can change if a new idef of the phi is added between the phi
3130 // and this instruction (inserting an idef updates every use).
3131 HPhi* phi_;
3132 NumericRelation relation_;
3133 int operand_index_;
3134};
3135
3136
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003137class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003138 public:
3139 HArgumentsObject() {
3140 set_representation(Representation::Tagged());
3141 SetFlag(kIsArguments);
3142 }
3143
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003144 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003145 return Representation::None();
3146 }
3147
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003148 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003149
3150 private:
3151 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003152};
3153
3154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003155class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003156 public:
3157 HConstant(Handle<Object> handle, Representation r);
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003158 HConstant(int32_t value,
3159 Representation r,
danno@chromium.orgf005df62013-04-30 16:36:45 +00003160 bool is_not_in_new_space = true,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003161 Handle<Object> optional_handle = Handle<Object>::null());
3162 HConstant(double value,
3163 Representation r,
danno@chromium.orgf005df62013-04-30 16:36:45 +00003164 bool is_not_in_new_space = true,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003165 Handle<Object> optional_handle = Handle<Object>::null());
3166 HConstant(Handle<Object> handle,
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003167 UniqueValueId unique_id,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003168 Representation r,
3169 HType type,
3170 bool is_internalized_string,
danno@chromium.orgf005df62013-04-30 16:36:45 +00003171 bool is_not_in_new_space,
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003172 bool boolean_value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003173
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003174 Handle<Object> handle() {
3175 if (handle_.is_null()) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00003176 // Default arguments to is_not_in_new_space depend on this heap number
3177 // to be tenured so that it's guaranteed not be be located in new space.
yangguo@chromium.org4db26402013-04-25 11:02:09 +00003178 handle_ = FACTORY->NewNumber(double_value_, TENURED);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003179 }
yangguo@chromium.org4db26402013-04-25 11:02:09 +00003180 ALLOW_HANDLE_DEREF(Isolate::Current(), "smi check");
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003181 ASSERT(has_int32_value_ || !handle_->IsSmi());
3182 return handle_;
3183 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003184
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003185 bool IsSpecialDouble() const {
3186 return has_double_value_ &&
3187 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3188 FixedDoubleArray::is_the_hole_nan(double_value_) ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +00003189 std::isnan(double_value_));
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003190 }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003191
danno@chromium.orgf005df62013-04-30 16:36:45 +00003192 bool NotInNewSpace() const {
3193 return is_not_in_new_space_;
3194 }
3195
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003196 bool ImmortalImmovable() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003197 if (has_int32_value_) {
3198 return false;
3199 }
3200 if (has_double_value_) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003201 if (IsSpecialDouble()) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003202 return true;
3203 }
3204 return false;
3205 }
3206
3207 ASSERT(!handle_.is_null());
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003208 Heap* heap = isolate()->heap();
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003209 ASSERT(unique_id_ != UniqueValueId(heap->minus_zero_value()));
3210 ASSERT(unique_id_ != UniqueValueId(heap->nan_value()));
3211 return unique_id_ == UniqueValueId(heap->undefined_value()) ||
3212 unique_id_ == UniqueValueId(heap->null_value()) ||
3213 unique_id_ == UniqueValueId(heap->true_value()) ||
3214 unique_id_ == UniqueValueId(heap->false_value()) ||
3215 unique_id_ == UniqueValueId(heap->the_hole_value()) ||
3216 unique_id_ == UniqueValueId(heap->empty_string());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003217 }
3218
3219 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003220 return Representation::None();
3221 }
3222
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003223 virtual bool IsConvertibleToInteger() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003224 return has_int32_value_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003225 }
3226
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00003227 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003228 virtual void PrintDataTo(StringStream* stream);
3229 virtual HType CalculateInferredType();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003230 bool IsInteger() { return handle()->IsSmi(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003231 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3232 HConstant* CopyToTruncatedInt32(Zone* zone) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003233 bool HasInteger32Value() const { return has_int32_value_; }
3234 int32_t Integer32Value() const {
3235 ASSERT(HasInteger32Value());
3236 return int32_value_;
3237 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003238 bool HasSmiValue() const {
3239 return HasInteger32Value() && Smi::IsValid(Integer32Value());
3240 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003241 bool HasDoubleValue() const { return has_double_value_; }
3242 double DoubleValue() const {
3243 ASSERT(HasDoubleValue());
3244 return double_value_;
3245 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003246 bool IsTheHole() const {
3247 if (HasDoubleValue() && FixedDoubleArray::is_the_hole_nan(double_value_)) {
3248 return true;
3249 }
3250 Heap* heap = isolate()->heap();
3251 if (!handle_.is_null() && *handle_ == heap->the_hole_value()) {
3252 return true;
3253 }
3254 return false;
3255 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003256 bool HasNumberValue() const { return has_double_value_; }
erikcorry0ad885c2011-11-21 13:51:57 +00003257 int32_t NumberValueAsInteger32() const {
3258 ASSERT(HasNumberValue());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003259 // Irrespective of whether a numeric HConstant can be safely
3260 // represented as an int32, we store the (in some cases lossy)
3261 // representation of the number in int32_value_.
3262 return int32_value_;
erikcorry0ad885c2011-11-21 13:51:57 +00003263 }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003264 bool HasStringValue() const {
3265 if (has_double_value_ || has_int32_value_) return false;
3266 ASSERT(!handle_.is_null());
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003267 return type_from_value_.IsString();
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003268 }
3269 Handle<String> StringValue() const {
3270 ASSERT(HasStringValue());
3271 return Handle<String>::cast(handle_);
3272 }
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003273 bool HasInternalizedStringValue() const {
3274 return HasStringValue() && is_internalized_string_;
3275 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003276
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003277 bool BooleanValue() const { return boolean_value_; }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003278
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003279 virtual intptr_t Hashcode() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003280 if (has_int32_value_) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003281 return static_cast<intptr_t>(int32_value_);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003282 } else if (has_double_value_) {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003283 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003284 } else {
3285 ASSERT(!handle_.is_null());
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003286 return unique_id_.Hashcode();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003287 }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003288 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003289
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003290 virtual void FinalizeUniqueValueId() {
3291 if (!has_double_value_) {
3292 ASSERT(!handle_.is_null());
3293 unique_id_ = UniqueValueId(handle_);
3294 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003295 }
3296
3297#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00003298 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003299#endif
3300
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003301 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003302
3303 protected:
ulan@chromium.org812308e2012-02-29 15:58:45 +00003304 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003305
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003306 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003307 HConstant* other_constant = HConstant::cast(other);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003308 if (has_int32_value_) {
3309 return other_constant->has_int32_value_ &&
3310 int32_value_ == other_constant->int32_value_;
3311 } else if (has_double_value_) {
3312 return other_constant->has_double_value_ &&
3313 BitCast<int64_t>(double_value_) ==
3314 BitCast<int64_t>(other_constant->double_value_);
3315 } else {
3316 ASSERT(!handle_.is_null());
3317 return !other_constant->handle_.is_null() &&
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003318 unique_id_ == other_constant->unique_id_;
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003319 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003320 }
3321
3322 private:
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003323 void Initialize(Representation r);
3324
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003325 virtual bool IsDeletable() const { return true; }
3326
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003327 // If this is a numerical constant, handle_ either points to to the
3328 // HeapObject the constant originated from or is null. If the
3329 // constant is non-numeric, handle_ always points to a valid
3330 // constant HeapObject.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003331 Handle<Object> handle_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00003332 UniqueValueId unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003333
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003334 // We store the HConstant in the most specific form safely possible.
3335 // The two flags, has_int32_value_ and has_double_value_ tell us if
3336 // int32_value_ and double_value_ hold valid, safe representations
3337 // of the constant. has_int32_value_ implies has_double_value_ but
3338 // not the converse.
danno@chromium.org160a7b02011-04-18 15:51:38 +00003339 bool has_int32_value_ : 1;
3340 bool has_double_value_ : 1;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003341 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType.
danno@chromium.orgf005df62013-04-30 16:36:45 +00003342 bool is_not_in_new_space_ : 1;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003343 bool boolean_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003344 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003345 double double_value_;
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00003346 HType type_from_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003347};
3348
3349
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003350class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003351 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003352 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3353 : observed_output_representation_(Representation::None()) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003355 SetOperandAt(0, context);
3356 SetOperandAt(1, left);
3357 SetOperandAt(2, right);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003358 observed_input_representation_[0] = Representation::None();
3359 observed_input_representation_[1] = Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003360 }
3361
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003362 HValue* context() { return OperandAt(0); }
3363 HValue* left() { return OperandAt(1); }
3364 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003365
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003366 // True if switching left and right operands likely generates better code.
3367 bool AreOperandsBetterSwitched() {
3368 if (!IsCommutative()) return false;
3369
3370 // Constant operands are better off on the right, they can be inlined in
3371 // many situations on most platforms.
3372 if (left()->IsConstant()) return true;
3373 if (right()->IsConstant()) return false;
3374
3375 // Otherwise, if there is only one use of the right operand, it would be
3376 // better off on the left for platforms that only have 2-arg arithmetic
3377 // ops (e.g ia32, x64) that clobber the left operand.
3378 return (right()->UseCount() == 1);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003380
ulan@chromium.org57ff8812013-05-10 08:16:55 +00003381 HValue* BetterLeftOperand() {
3382 return AreOperandsBetterSwitched() ? right() : left();
3383 }
3384
3385 HValue* BetterRightOperand() {
3386 return AreOperandsBetterSwitched() ? left() : right();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003387 }
3388
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003389 void set_observed_input_representation(int index, Representation rep) {
3390 ASSERT(index >= 1 && index <= 2);
3391 observed_input_representation_[index - 1] = rep;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003392 }
3393
3394 virtual void initialize_output_representation(Representation observed) {
3395 observed_output_representation_ = observed;
3396 }
3397
3398 virtual Representation observed_input_representation(int index) {
3399 if (index == 0) return Representation::Tagged();
3400 return observed_input_representation_[index - 1];
3401 }
3402
3403 virtual void InferRepresentation(HInferRepresentation* h_infer);
3404 virtual Representation RepresentationFromInputs();
3405 virtual void AssumeRepresentation(Representation r);
3406
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003407 virtual bool IsCommutative() const { return false; }
3408
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003409 virtual void PrintDataTo(StringStream* stream);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003410
3411 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003412
3413 private:
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00003414 bool IgnoreObservedOutputRepresentation(Representation current_rep);
3415
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003416 Representation observed_input_representation_[2];
3417 Representation observed_output_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003418};
3419
3420
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003421class HWrapReceiver: public HTemplateInstruction<2> {
3422 public:
3423 HWrapReceiver(HValue* receiver, HValue* function) {
3424 set_representation(Representation::Tagged());
3425 SetOperandAt(0, receiver);
3426 SetOperandAt(1, function);
3427 }
3428
3429 virtual Representation RequiredInputRepresentation(int index) {
3430 return Representation::Tagged();
3431 }
3432
3433 HValue* receiver() { return OperandAt(0); }
3434 HValue* function() { return OperandAt(1); }
3435
3436 virtual HValue* Canonicalize();
3437
yangguo@chromium.org39110192013-01-16 09:55:08 +00003438 virtual void PrintDataTo(StringStream* stream);
3439
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003440 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3441};
3442
3443
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003444class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445 public:
3446 HApplyArguments(HValue* function,
3447 HValue* receiver,
3448 HValue* length,
3449 HValue* elements) {
3450 set_representation(Representation::Tagged());
3451 SetOperandAt(0, function);
3452 SetOperandAt(1, receiver);
3453 SetOperandAt(2, length);
3454 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003455 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456 }
3457
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003458 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003459 // The length is untagged, all other inputs are tagged.
3460 return (index == 2)
3461 ? Representation::Integer32()
3462 : Representation::Tagged();
3463 }
3464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003465 HValue* function() { return OperandAt(0); }
3466 HValue* receiver() { return OperandAt(1); }
3467 HValue* length() { return OperandAt(2); }
3468 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003469
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003470 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003471};
3472
3473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003474class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003475 public:
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003476 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003477 // The value produced by this instruction is a pointer into the stack
3478 // that looks as if it was a smi because of alignment.
3479 set_representation(Representation::Tagged());
3480 SetFlag(kUseGVN);
3481 }
3482
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003483 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003484
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003485 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003486 return Representation::None();
3487 }
3488
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003489 bool from_inlined() const { return from_inlined_; }
3490
ager@chromium.org378b34e2011-01-28 08:04:38 +00003491 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003492 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003493
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003494 private:
3495 virtual bool IsDeletable() const { return true; }
3496
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003497 bool from_inlined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003498};
3499
3500
3501class HArgumentsLength: public HUnaryOperation {
3502 public:
3503 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
3504 set_representation(Representation::Integer32());
3505 SetFlag(kUseGVN);
3506 }
3507
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003508 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003509 return Representation::Tagged();
3510 }
3511
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003512 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003513
3514 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003515 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003516
3517 private:
3518 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003519};
3520
3521
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003522class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523 public:
3524 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3525 set_representation(Representation::Tagged());
3526 SetFlag(kUseGVN);
3527 SetOperandAt(0, arguments);
3528 SetOperandAt(1, length);
3529 SetOperandAt(2, index);
3530 }
3531
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003532 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003533
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003534 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003535 // The arguments elements is considered tagged.
3536 return index == 0
3537 ? Representation::Tagged()
3538 : Representation::Integer32();
3539 }
3540
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003541 HValue* arguments() { return OperandAt(0); }
3542 HValue* length() { return OperandAt(1); }
3543 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003544
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003545 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003546
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003547 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003548};
3549
3550
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003551enum BoundsCheckKeyMode {
3552 DONT_ALLOW_SMI_KEY,
3553 ALLOW_SMI_KEY
3554};
3555
3556
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003557class HBoundsCheckBaseIndexInformation;
3558
3559
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003560class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003561 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003562 // Normally HBoundsCheck should be created using the
3563 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3564 // a HCheckSmiOrInt32 check.
3565 // However when building stubs, where we know that the arguments are Int32,
3566 // it makes sense to invoke this constructor directly.
3567 HBoundsCheck(HValue* index,
3568 HValue* length,
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003569 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3570 Representation r = Representation::None())
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003571 : key_mode_(key_mode), skip_check_(false),
3572 base_(NULL), offset_(0), scale_(0),
3573 responsibility_direction_(DIRECTION_NONE) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003574 SetOperandAt(0, index);
3575 SetOperandAt(1, length);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003576 if (r.IsNone()) {
3577 // In the normal compilation pipeline the representation is flexible
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003578 // (see InferRepresentation).
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003579 SetFlag(kFlexibleRepresentation);
3580 } else {
3581 // When compiling stubs we want to set the representation explicitly
3582 // so the compilation pipeline can skip the HInferRepresentation phase.
3583 set_representation(r);
3584 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003585 SetFlag(kUseGVN);
3586 }
3587
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003588 bool skip_check() { return skip_check_; }
3589 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003590 HValue* base() { return base_; }
3591 int offset() { return offset_; }
3592 int scale() { return scale_; }
3593 bool index_can_increase() {
3594 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3595 }
3596 bool index_can_decrease() {
3597 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3598 }
3599
3600 void ApplyIndexChange();
3601 bool DetectCompoundIndex() {
3602 ASSERT(base() == NULL);
3603
3604 DecompositionResult decomposition;
3605 if (index()->TryDecompose(&decomposition)) {
3606 base_ = decomposition.base();
3607 offset_ = decomposition.offset();
3608 scale_ = decomposition.scale();
3609 return true;
3610 } else {
3611 base_ = index();
3612 offset_ = 0;
3613 scale_ = 0;
3614 return false;
3615 }
3616 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003617
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003618 virtual Representation RequiredInputRepresentation(int arg_index) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003619 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003620 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003621 virtual Representation observed_input_representation(int index) {
3622 return Representation::Integer32();
3623 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003624
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003625 virtual bool IsRelationTrueInternal(NumericRelation relation,
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003626 HValue* related_value,
3627 int offset = 0,
3628 int scale = 0);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003629
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003630 virtual void PrintDataTo(StringStream* stream);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003631 virtual void InferRepresentation(HInferRepresentation* h_infer);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003632
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003633 HValue* index() { return OperandAt(0); }
3634 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003636 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003637 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003638 virtual void AddInformativeDefinitions();
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003639
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003640 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003641
3642 protected:
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003643 friend class HBoundsCheckBaseIndexInformation;
3644
3645 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3646 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3647 responsibility_direction_ | direction);
3648 }
3649
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003650 virtual bool DataEquals(HValue* other) { return true; }
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003651 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003652 BoundsCheckKeyMode key_mode_;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003653 bool skip_check_;
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00003654 HValue* base_;
3655 int offset_;
3656 int scale_;
3657 RangeGuaranteeDirection responsibility_direction_;
3658};
3659
3660
3661class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3662 public:
3663 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3664 DecompositionResult decomposition;
3665 if (check->index()->TryDecompose(&decomposition)) {
3666 SetOperandAt(0, decomposition.base());
3667 SetOperandAt(1, check);
3668 } else {
3669 UNREACHABLE();
3670 }
3671 }
3672
3673 HValue* base_index() { return OperandAt(0); }
3674 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
3675
3676 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3677
3678 virtual Representation RequiredInputRepresentation(int arg_index) {
3679 return representation();
3680 }
3681
3682 virtual bool IsRelationTrueInternal(NumericRelation relation,
3683 HValue* related_value,
3684 int offset = 0,
3685 int scale = 0);
3686 virtual void PrintDataTo(StringStream* stream);
3687
3688 virtual int RedefinedOperandIndex() { return 0; }
3689 virtual bool IsPurelyInformativeDefinition() { return true; }
3690
3691 protected:
3692 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3693 bounds_check()->SetResponsibilityForRange(direction);
3694 }
3695 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
3696 bounds_check()->TryGuaranteeRangeChanging(context);
3697 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003698};
3699
3700
3701class HBitwiseBinaryOperation: public HBinaryOperation {
3702 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003703 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3704 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003705 SetFlag(kFlexibleRepresentation);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003706 SetFlag(kTruncatingToInt32);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003707 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003708 }
3709
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003710 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003711 return index == 0
3712 ? Representation::Tagged()
3713 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003714 }
3715
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003716 virtual void RepresentationChanged(Representation to) {
3717 if (!to.IsTagged()) {
3718 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003719 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003720 SetFlag(kUseGVN);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003721 } else {
3722 SetAllSideEffects();
3723 ClearFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003724 }
3725 }
3726
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003727 virtual void UpdateRepresentation(Representation new_rep,
3728 HInferRepresentation* h_infer,
3729 const char* reason) {
3730 // We only generate either int32 or generic tagged bitwise operations.
3731 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
3732 HValue::UpdateRepresentation(new_rep, h_infer, reason);
3733 }
3734
3735 virtual void initialize_output_representation(Representation observed) {
3736 if (observed.IsDouble()) observed = Representation::Integer32();
3737 HBinaryOperation::initialize_output_representation(observed);
3738 }
3739
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003740 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003741
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003742 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003743
3744 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003745 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003746};
3747
3748
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003749class HMathFloorOfDiv: public HBinaryOperation {
3750 public:
3751 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
3752 : HBinaryOperation(context, left, right) {
3753 set_representation(Representation::Integer32());
3754 SetFlag(kUseGVN);
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003755 SetFlag(kCanOverflow);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003756 if (!right->IsConstant()) {
3757 SetFlag(kCanBeDivByZero);
3758 }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003759 }
3760
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003761 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3762
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003763 virtual Representation RequiredInputRepresentation(int index) {
3764 return Representation::Integer32();
3765 }
3766
3767 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
3768
3769 protected:
3770 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003771
3772 private:
3773 virtual bool IsDeletable() const { return true; }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003774};
3775
3776
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003777class HArithmeticBinaryOperation: public HBinaryOperation {
3778 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003779 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
3780 : HBinaryOperation(context, left, right) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003781 SetAllSideEffects();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003782 SetFlag(kFlexibleRepresentation);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003783 }
3784
3785 virtual void RepresentationChanged(Representation to) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003786 if (to.IsTagged()) {
3787 SetAllSideEffects();
3788 ClearFlag(kUseGVN);
3789 } else {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003790 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003791 SetFlag(kUseGVN);
3792 }
3793 }
3794
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003795 virtual HType CalculateInferredType();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003796 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003797 return index == 0
3798 ? Representation::Tagged()
3799 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003801
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00003802 virtual HValue* Canonicalize();
3803
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003804 private:
3805 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003806};
3807
3808
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003809class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003810 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003811 HCompareGeneric(HValue* context,
3812 HValue* left,
3813 HValue* right,
3814 Token::Value token)
3815 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003816 ASSERT(Token::IsCompareOp(token));
3817 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003818 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003819 }
3820
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003821 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003822 return index == 0
3823 ? Representation::Tagged()
3824 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003825 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003826
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003827 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003828 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003829
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003830 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003832 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
3833
3834 private:
3835 Token::Value token_;
3836};
3837
3838
3839class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
3840 public:
3841 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
3842 : token_(token) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003843 SetFlag(kFlexibleRepresentation);
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003844 ASSERT(Token::IsCompareOp(token));
3845 SetOperandAt(0, left);
3846 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003847 }
3848
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003849 HValue* left() { return OperandAt(0); }
3850 HValue* right() { return OperandAt(1); }
3851 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003852
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003853 void set_observed_input_representation(Representation left,
3854 Representation right) {
3855 observed_input_representation_[0] = left;
3856 observed_input_representation_[1] = right;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003857 }
3858
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003859 virtual void InferRepresentation(HInferRepresentation* h_infer);
3860
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003861 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003862 return representation();
3863 }
3864 virtual Representation observed_input_representation(int index) {
3865 return observed_input_representation_[index];
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003866 }
3867 virtual void PrintDataTo(StringStream* stream);
3868
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003869 virtual void AddInformativeDefinitions();
3870
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003871 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
3872
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003873 private:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003874 Representation observed_input_representation_[2];
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003875 Token::Value token_;
3876};
3877
3878
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003879class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003880 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003881 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
3882 SetOperandAt(0, left);
3883 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003884 }
3885
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003886 HValue* left() { return OperandAt(0); }
3887 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003888
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003889 virtual void PrintDataTo(StringStream* stream);
3890
3891 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003892 return Representation::Tagged();
3893 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003894
danno@chromium.orgca29dd82013-04-26 11:59:48 +00003895 virtual Representation observed_input_representation(int index) {
3896 return Representation::Tagged();
3897 }
3898
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003899 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003900};
3901
3902
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003903class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003904 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003905 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
3906 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003907 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003908 }
3909
3910 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003911 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00003912 int right() const { return right_; }
3913
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003914 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003915 return Representation::Integer32();
3916 }
3917
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003918 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003919
3920 private:
3921 const Token::Value op_;
3922 const int right_;
3923};
3924
3925
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003926class HIsNilAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003927 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003928 HIsNilAndBranch(HValue* value, EqualityKind kind, NilValue nil)
3929 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003930
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003931 EqualityKind kind() const { return kind_; }
3932 NilValue nil() const { return nil_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003934 virtual void PrintDataTo(StringStream* stream);
3935
3936 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003937 return Representation::Tagged();
3938 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003939 virtual Representation observed_input_representation(int index) {
3940 return Representation::Tagged();
3941 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003942
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003943 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003944
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003945 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003946 EqualityKind kind_;
3947 NilValue nil_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003948};
3949
3950
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003951class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003952 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003953 explicit HIsObjectAndBranch(HValue* value)
3954 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003955
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003956 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003957 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003958 }
3959
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003960 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
3961};
3962
erikcorry0ad885c2011-11-21 13:51:57 +00003963class HIsStringAndBranch: public HUnaryControlInstruction {
3964 public:
3965 explicit HIsStringAndBranch(HValue* value)
3966 : HUnaryControlInstruction(value, NULL, NULL) { }
3967
3968 virtual Representation RequiredInputRepresentation(int index) {
3969 return Representation::Tagged();
3970 }
3971
3972 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
3973};
3974
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003975
3976class HIsSmiAndBranch: public HUnaryControlInstruction {
3977 public:
3978 explicit HIsSmiAndBranch(HValue* value)
3979 : HUnaryControlInstruction(value, NULL, NULL) { }
3980
3981 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
3982
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003983 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003984 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003985 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003986
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003987 protected:
3988 virtual bool DataEquals(HValue* other) { return true; }
3989};
3990
3991
3992class HIsUndetectableAndBranch: public HUnaryControlInstruction {
3993 public:
3994 explicit HIsUndetectableAndBranch(HValue* value)
3995 : HUnaryControlInstruction(value, NULL, NULL) { }
3996
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003997 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003998 return Representation::Tagged();
3999 }
4000
4001 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
4002};
4003
4004
erikcorry0ad885c2011-11-21 13:51:57 +00004005class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
4006 public:
4007 HStringCompareAndBranch(HValue* context,
4008 HValue* left,
4009 HValue* right,
4010 Token::Value token)
4011 : token_(token) {
4012 ASSERT(Token::IsCompareOp(token));
4013 SetOperandAt(0, context);
4014 SetOperandAt(1, left);
4015 SetOperandAt(2, right);
4016 set_representation(Representation::Tagged());
4017 }
4018
4019 HValue* context() { return OperandAt(0); }
4020 HValue* left() { return OperandAt(1); }
4021 HValue* right() { return OperandAt(2); }
4022 Token::Value token() const { return token_; }
4023
4024 virtual void PrintDataTo(StringStream* stream);
4025
4026 virtual Representation RequiredInputRepresentation(int index) {
4027 return Representation::Tagged();
4028 }
4029
4030 Representation GetInputRepresentation() const {
4031 return Representation::Tagged();
4032 }
4033
4034 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
4035
4036 private:
4037 Token::Value token_;
4038};
4039
4040
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004041class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
4042 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004043 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004044 return Representation::None();
4045 }
4046
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004047 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00004048};
4049
4050
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004051class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004052 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004053 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
4054 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
4055 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
4056 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004057 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
4058 }
4059
4060 InstanceType from() { return from_; }
4061 InstanceType to() { return to_; }
4062
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004063 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004064
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004065 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004066 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004067 }
4068
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004069 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
4070
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004071 private:
4072 InstanceType from_;
4073 InstanceType to_; // Inclusive range, not all combinations work.
4074};
4075
4076
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004077class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004078 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004079 explicit HHasCachedArrayIndexAndBranch(HValue* value)
4080 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004081
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004082 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004083 return Representation::Tagged();
4084 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004085
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004086 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004087};
4088
4089
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00004090class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00004091 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00004092 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
4093 set_representation(Representation::Tagged());
4094 SetFlag(kUseGVN);
4095 }
4096
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004097 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00004098 return Representation::Tagged();
4099 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00004100
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004101 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00004102
4103 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004104 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004105
4106 private:
4107 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00004108};
4109
4110
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004111class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004112 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004113 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
4114 : HUnaryControlInstruction(value, NULL, NULL),
4115 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004116
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004117 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
4118
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004119 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004120 return Representation::Tagged();
4121 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004123 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004124
4125 Handle<String> class_name() const { return class_name_; }
4126
4127 private:
4128 Handle<String> class_name_;
4129};
4130
4131
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004132class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004133 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004134 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
4135 : HUnaryControlInstruction(value, NULL, NULL),
4136 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004137
4138 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004139 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004140
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004141 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004142
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004143 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00004144 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004145 }
4146
4147 private:
4148 Handle<String> type_literal_;
4149};
4150
4151
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004152class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004153 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004154 HInstanceOf(HValue* context, HValue* left, HValue* right)
4155 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004156 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004157 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004158 }
4159
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004160 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004161 return Representation::Tagged();
4162 }
4163
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004164 virtual HType CalculateInferredType();
4165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004166 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004167
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004168 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004169};
4170
4171
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004172class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004173 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004174 HInstanceOfKnownGlobal(HValue* context,
4175 HValue* left,
4176 Handle<JSFunction> right)
4177 : function_(right) {
4178 SetOperandAt(0, context);
4179 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004180 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004181 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004182 }
4183
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004184 HValue* context() { return OperandAt(0); }
4185 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004186 Handle<JSFunction> function() { return function_; }
4187
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004188 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004189 return Representation::Tagged();
4190 }
4191
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004192 virtual HType CalculateInferredType();
4193
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004194 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00004195
4196 private:
4197 Handle<JSFunction> function_;
4198};
4199
4200
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +00004201// TODO(mstarzinger): This instruction should be modeled as a load of the map
4202// field followed by a load of the instance size field once HLoadNamedField is
4203// flexible enough to accommodate byte-field loads.
4204class HInstanceSize: public HTemplateInstruction<1> {
4205 public:
4206 explicit HInstanceSize(HValue* object) {
4207 SetOperandAt(0, object);
4208 set_representation(Representation::Integer32());
4209 }
4210
4211 HValue* object() { return OperandAt(0); }
4212
4213 virtual Representation RequiredInputRepresentation(int index) {
4214 return Representation::Tagged();
4215 }
4216
4217 DECLARE_CONCRETE_INSTRUCTION(InstanceSize)
4218};
4219
4220
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004221class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004222 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004223 static HInstruction* New(Zone* zone, HValue* left, HValue* right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004224
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004225 HValue* left() { return OperandAt(0); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004226 HValue* right() const { return OperandAt(1); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004227
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004228 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004229 return index == 0
4230 ? Representation::Double()
4231 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004232 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004233 virtual Representation observed_input_representation(int index) {
4234 return RequiredInputRepresentation(index);
4235 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004236
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004237 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004238
4239 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004240 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004241
4242 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004243 HPower(HValue* left, HValue* right) {
4244 SetOperandAt(0, left);
4245 SetOperandAt(1, right);
4246 set_representation(Representation::Double());
4247 SetFlag(kUseGVN);
4248 SetGVNFlag(kChangesNewSpacePromotion);
4249 }
4250
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004251 virtual bool IsDeletable() const {
4252 return !right()->representation().IsTagged();
4253 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004254};
4255
4256
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004257class HRandom: public HTemplateInstruction<1> {
4258 public:
4259 explicit HRandom(HValue* global_object) {
4260 SetOperandAt(0, global_object);
4261 set_representation(Representation::Double());
4262 }
4263
4264 HValue* global_object() { return OperandAt(0); }
4265
4266 virtual Representation RequiredInputRepresentation(int index) {
4267 return Representation::Tagged();
4268 }
4269
4270 DECLARE_CONCRETE_INSTRUCTION(Random)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004271
4272 private:
4273 virtual bool IsDeletable() const { return true; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004274};
4275
4276
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004277class HAdd: public HArithmeticBinaryOperation {
4278 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004279 static HInstruction* New(Zone* zone,
4280 HValue* context,
4281 HValue* left,
4282 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004283
4284 // Add is only commutative if two integer values are added and not if two
4285 // tagged values are added (because it might be a String concatenation).
4286 virtual bool IsCommutative() const {
4287 return !representation().IsTagged();
4288 }
4289
4290 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4291
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004292 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004293
ulan@chromium.org812308e2012-02-29 15:58:45 +00004294 virtual HValue* Canonicalize();
4295
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004296 virtual bool TryDecompose(DecompositionResult* decomposition) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004297 if (left()->IsInteger32Constant()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004298 decomposition->Apply(right(), left()->GetInteger32Constant());
4299 return true;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004300 } else if (right()->IsInteger32Constant()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004301 decomposition->Apply(left(), right()->GetInteger32Constant());
4302 return true;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004303 } else {
4304 return false;
4305 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004306 }
4307
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004308 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004309
4310 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004311 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004312
ulan@chromium.org812308e2012-02-29 15:58:45 +00004313 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004314
4315 private:
4316 HAdd(HValue* context, HValue* left, HValue* right)
4317 : HArithmeticBinaryOperation(context, left, right) {
4318 SetFlag(kCanOverflow);
4319 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004320};
4321
4322
4323class HSub: public HArithmeticBinaryOperation {
4324 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004325 static HInstruction* New(Zone* zone,
4326 HValue* context,
4327 HValue* left,
4328 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004329
4330 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4331
ulan@chromium.org812308e2012-02-29 15:58:45 +00004332 virtual HValue* Canonicalize();
4333
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004334 virtual bool TryDecompose(DecompositionResult* decomposition) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004335 if (right()->IsInteger32Constant()) {
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004336 decomposition->Apply(left(), -right()->GetInteger32Constant());
4337 return true;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004338 } else {
4339 return false;
4340 }
4341 }
4342
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004343 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004344
4345 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004346 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004347
ulan@chromium.org812308e2012-02-29 15:58:45 +00004348 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004349
4350 private:
4351 HSub(HValue* context, HValue* left, HValue* right)
4352 : HArithmeticBinaryOperation(context, left, right) {
4353 SetFlag(kCanOverflow);
4354 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004355};
4356
4357
4358class HMul: public HArithmeticBinaryOperation {
4359 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004360 static HInstruction* New(Zone* zone,
4361 HValue* context,
4362 HValue* left,
4363 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004364
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004365 static HInstruction* NewImul(Zone* zone,
4366 HValue* context,
4367 HValue* left,
4368 HValue* right) {
4369 HMul* mul = new(zone) HMul(context, left, right);
4370 // TODO(mstarzinger): Prevent bailout on minus zero for imul.
4371 mul->AssumeRepresentation(Representation::Integer32());
4372 mul->ClearFlag(HValue::kCanOverflow);
4373 return mul;
4374 }
4375
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004376 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4377
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +00004378 virtual HValue* Canonicalize();
4379
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004380 // Only commutative if it is certain that not two objects are multiplicated.
4381 virtual bool IsCommutative() const {
4382 return !representation().IsTagged();
4383 }
4384
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004385 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004386
4387 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004388 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004389
ulan@chromium.org812308e2012-02-29 15:58:45 +00004390 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004391
4392 private:
4393 HMul(HValue* context, HValue* left, HValue* right)
4394 : HArithmeticBinaryOperation(context, left, right) {
4395 SetFlag(kCanOverflow);
4396 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004397};
4398
4399
4400class HMod: public HArithmeticBinaryOperation {
4401 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004402 static HInstruction* New(Zone* zone,
4403 HValue* context,
4404 HValue* left,
4405 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004406
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004407 bool HasPowerOf2Divisor() {
4408 if (right()->IsConstant() &&
4409 HConstant::cast(right())->HasInteger32Value()) {
4410 int32_t value = HConstant::cast(right())->Integer32Value();
4411 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4412 }
4413
4414 return false;
4415 }
4416
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004417 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4418
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004419 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004420
4421 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004422 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004423
ulan@chromium.org812308e2012-02-29 15:58:45 +00004424 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004425
4426 private:
4427 HMod(HValue* context, HValue* left, HValue* right)
4428 : HArithmeticBinaryOperation(context, left, right) {
4429 SetFlag(kCanBeDivByZero);
4430 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004431};
4432
4433
4434class HDiv: public HArithmeticBinaryOperation {
4435 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004436 static HInstruction* New(Zone* zone,
4437 HValue* context,
4438 HValue* left,
4439 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004440
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004441 bool HasPowerOf2Divisor() {
4442 if (right()->IsConstant() &&
4443 HConstant::cast(right())->HasInteger32Value()) {
4444 int32_t value = HConstant::cast(right())->Integer32Value();
4445 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4446 }
4447
4448 return false;
4449 }
4450
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004451 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4452
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004453 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004454
4455 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004456 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004457
ulan@chromium.org812308e2012-02-29 15:58:45 +00004458 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004459
4460 private:
4461 HDiv(HValue* context, HValue* left, HValue* right)
4462 : HArithmeticBinaryOperation(context, left, right) {
4463 SetFlag(kCanBeDivByZero);
4464 SetFlag(kCanOverflow);
4465 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004466};
4467
4468
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004469class HMathMinMax: public HArithmeticBinaryOperation {
4470 public:
4471 enum Operation { kMathMin, kMathMax };
4472
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004473 static HInstruction* New(Zone* zone,
4474 HValue* context,
4475 HValue* left,
4476 HValue* right,
4477 Operation op);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004478
4479 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004480 return index == 0 ? Representation::Tagged()
4481 : representation();
4482 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004483
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004484 virtual Representation observed_input_representation(int index) {
4485 return RequiredInputRepresentation(index);
4486 }
4487
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004488 virtual void InferRepresentation(HInferRepresentation* h_infer);
4489
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004490 virtual Representation RepresentationFromInputs() {
4491 Representation left_rep = left()->representation();
4492 Representation right_rep = right()->representation();
4493 if ((left_rep.IsNone() || left_rep.IsInteger32()) &&
4494 (right_rep.IsNone() || right_rep.IsInteger32())) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004495 return Representation::Integer32();
4496 }
4497 return Representation::Double();
4498 }
4499
4500 virtual bool IsCommutative() const { return true; }
4501
4502 Operation operation() { return operation_; }
4503
4504 DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
4505
4506 protected:
4507 virtual bool DataEquals(HValue* other) {
4508 return other->IsMathMinMax() &&
4509 HMathMinMax::cast(other)->operation_ == operation_;
4510 }
4511
4512 virtual Range* InferRange(Zone* zone);
4513
4514 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004515 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
4516 : HArithmeticBinaryOperation(context, left, right),
4517 operation_(op) { }
4518
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004519 Operation operation_;
4520};
4521
4522
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004523class HBitwise: public HBitwiseBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004524 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004525 static HInstruction* New(Zone* zone,
4526 Token::Value op,
4527 HValue* context,
4528 HValue* left,
4529 HValue* right);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004530
4531 Token::Value op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004532
4533 virtual bool IsCommutative() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004534
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004535 virtual HValue* Canonicalize();
4536
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004537 virtual void PrintDataTo(StringStream* stream);
4538
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004539 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004540
4541 protected:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004542 virtual bool DataEquals(HValue* other) {
4543 return op() == HBitwise::cast(other)->op();
4544 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004545
ulan@chromium.org812308e2012-02-29 15:58:45 +00004546 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004547
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004548 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004549 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
4550 : HBitwiseBinaryOperation(context, left, right), op_(op) {
4551 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4552 }
4553
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004554 Token::Value op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004555};
4556
4557
4558class HShl: public HBitwiseBinaryOperation {
4559 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004560 static HInstruction* New(Zone* zone,
4561 HValue* context,
4562 HValue* left,
4563 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004564
ulan@chromium.org812308e2012-02-29 15:58:45 +00004565 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004566
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004567 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004568
4569 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004570 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004571
4572 private:
4573 HShl(HValue* context, HValue* left, HValue* right)
4574 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004575};
4576
4577
4578class HShr: public HBitwiseBinaryOperation {
4579 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004580 static HInstruction* New(Zone* zone,
4581 HValue* context,
4582 HValue* left,
4583 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004584
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004585 virtual bool TryDecompose(DecompositionResult* decomposition) {
4586 if (right()->IsInteger32Constant()) {
4587 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4588 // This is intended to look for HAdd and HSub, to handle compounds
4589 // like ((base + offset) >> scale) with one single decomposition.
4590 left()->TryDecompose(decomposition);
4591 return true;
4592 }
4593 }
4594 return false;
4595 }
4596
ulan@chromium.org812308e2012-02-29 15:58:45 +00004597 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004598
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004599 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004600
4601 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004602 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004603
4604 private:
4605 HShr(HValue* context, HValue* left, HValue* right)
4606 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004607};
4608
4609
4610class HSar: public HBitwiseBinaryOperation {
4611 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004612 static HInstruction* New(Zone* zone,
4613 HValue* context,
4614 HValue* left,
4615 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004616
svenpanne@chromium.org876cca82013-03-18 14:43:20 +00004617 virtual bool TryDecompose(DecompositionResult* decomposition) {
4618 if (right()->IsInteger32Constant()) {
4619 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4620 // This is intended to look for HAdd and HSub, to handle compounds
4621 // like ((base + offset) >> scale) with one single decomposition.
4622 left()->TryDecompose(decomposition);
4623 return true;
4624 }
4625 }
4626 return false;
4627 }
4628
ulan@chromium.org812308e2012-02-29 15:58:45 +00004629 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004630
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004631 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004632
4633 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004634 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004635
4636 private:
4637 HSar(HValue* context, HValue* left, HValue* right)
4638 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004639};
4640
4641
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004642class HRor: public HBitwiseBinaryOperation {
4643 public:
4644 HRor(HValue* context, HValue* left, HValue* right)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004645 : HBitwiseBinaryOperation(context, left, right) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004646 ChangeRepresentation(Representation::Integer32());
4647 }
4648
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004649 DECLARE_CONCRETE_INSTRUCTION(Ror)
4650
4651 protected:
4652 virtual bool DataEquals(HValue* other) { return true; }
4653};
4654
4655
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004656class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004657 public:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004658 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004659 SetGVNFlag(kChangesOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004660 }
4661
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004662 BailoutId ast_id() const { return ast_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004663
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004664 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004665 return Representation::None();
4666 }
4667
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004668 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004669
4670 private:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004671 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004672};
4673
4674
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004675class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004676 public:
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004677 enum ParameterKind {
4678 STACK_PARAMETER,
4679 REGISTER_PARAMETER
4680 };
4681
4682 explicit HParameter(unsigned index,
4683 ParameterKind kind = STACK_PARAMETER)
4684 : index_(index),
4685 kind_(kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004686 set_representation(Representation::Tagged());
4687 }
4688
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00004689 explicit HParameter(unsigned index,
4690 ParameterKind kind,
4691 Representation r)
4692 : index_(index),
4693 kind_(kind) {
4694 set_representation(r);
4695 }
4696
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004697 unsigned index() const { return index_; }
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004698 ParameterKind kind() const { return kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004699
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004700 virtual void PrintDataTo(StringStream* stream);
4701
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004702 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004703 return Representation::None();
4704 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004705
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004706 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004707
4708 private:
4709 unsigned index_;
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004710 ParameterKind kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004711};
4712
4713
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004714class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004715 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004716 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
4717 : HUnaryCall(context, argument_count),
4718 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004719 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004720 }
4721
4722 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004723
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004724 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004725
4726 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
4727 transcendental_type_ = transcendental_type;
4728 }
4729 TranscendentalCache::Type transcendental_type() {
4730 return transcendental_type_;
4731 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004732
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004733 virtual void PrintDataTo(StringStream* stream);
4734
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004735 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004736 return Representation::Tagged();
4737 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004738
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004739 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004740
4741 private:
4742 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004743 TranscendentalCache::Type transcendental_type_;
4744};
4745
4746
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004747class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004748 public:
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004749 HUnknownOSRValue()
4750 : incoming_value_(NULL) {
4751 set_representation(Representation::Tagged());
4752 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004753
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004754 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004755 return Representation::None();
4756 }
4757
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004758 void set_incoming_value(HPhi* value) {
4759 incoming_value_ = value;
4760 }
4761
4762 HPhi* incoming_value() {
4763 return incoming_value_;
4764 }
4765
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004766 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004767
4768 private:
4769 HPhi* incoming_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004770};
4771
4772
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004773class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004774 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004775 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004776 : cell_(cell), details_(details), unique_id_() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004777 set_representation(Representation::Tagged());
4778 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004779 SetGVNFlag(kDependsOnGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004780 }
4781
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004782 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004783 bool RequiresHoleCheck() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004784
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004785 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004786
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004787 virtual intptr_t Hashcode() {
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004788 return unique_id_.Hashcode();
4789 }
4790
4791 virtual void FinalizeUniqueValueId() {
4792 unique_id_ = UniqueValueId(cell_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004793 }
4794
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004795 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004796 return Representation::None();
4797 }
4798
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004799 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004800
4801 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004802 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004803 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004804 return unique_id_ == b->unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004805 }
4806
4807 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004808 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4809
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004810 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004811 PropertyDetails details_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00004812 UniqueValueId unique_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004813};
4814
4815
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004816class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004817 public:
4818 HLoadGlobalGeneric(HValue* context,
4819 HValue* global_object,
4820 Handle<Object> name,
4821 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004822 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004823 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004824 SetOperandAt(0, context);
4825 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004826 set_representation(Representation::Tagged());
4827 SetAllSideEffects();
4828 }
4829
4830 HValue* context() { return OperandAt(0); }
4831 HValue* global_object() { return OperandAt(1); }
4832 Handle<Object> name() const { return name_; }
4833 bool for_typeof() const { return for_typeof_; }
4834
4835 virtual void PrintDataTo(StringStream* stream);
4836
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004837 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004838 return Representation::Tagged();
4839 }
4840
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004841 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004842
4843 private:
4844 Handle<Object> name_;
4845 bool for_typeof_;
4846};
4847
4848
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004849class HAllocateObject: public HTemplateInstruction<1> {
4850 public:
4851 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4852 : constructor_(constructor) {
4853 SetOperandAt(0, context);
4854 set_representation(Representation::Tagged());
4855 SetGVNFlag(kChangesNewSpacePromotion);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00004856 constructor_initial_map_ = constructor->has_initial_map()
4857 ? Handle<Map>(constructor->initial_map())
4858 : Handle<Map>::null();
4859 // If slack tracking finished, the instance size and property counts
4860 // remain unchanged so that we can allocate memory for the object.
4861 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004862 }
4863
4864 // Maximum instance size for which allocations will be inlined.
4865 static const int kMaxSize = 64 * kPointerSize;
4866
4867 HValue* context() { return OperandAt(0); }
4868 Handle<JSFunction> constructor() { return constructor_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00004869 Handle<Map> constructor_initial_map() { return constructor_initial_map_; }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004870
4871 virtual Representation RequiredInputRepresentation(int index) {
4872 return Representation::Tagged();
4873 }
4874 virtual Handle<Map> GetMonomorphicJSObjectMap() {
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00004875 ASSERT(!constructor_initial_map_.is_null());
4876 return constructor_initial_map_;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004877 }
4878 virtual HType CalculateInferredType();
4879
4880 DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
4881
4882 private:
4883 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
4884 // virtual bool IsDeletable() const { return true; }
4885
4886 Handle<JSFunction> constructor_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00004887 Handle<Map> constructor_initial_map_;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004888};
4889
4890
4891class HAllocate: public HTemplateInstruction<2> {
4892 public:
4893 enum Flags {
4894 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0,
4895 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
4896 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
4897 ALLOCATE_DOUBLE_ALIGNED = 1 << 3
4898 };
4899
4900 HAllocate(HValue* context, HValue* size, HType type, Flags flags)
4901 : type_(type),
4902 flags_(flags) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004903 SetOperandAt(0, context);
4904 SetOperandAt(1, size);
4905 set_representation(Representation::Tagged());
4906 SetGVNFlag(kChangesNewSpacePromotion);
4907 }
4908
danno@chromium.orgca29dd82013-04-26 11:59:48 +00004909 static Flags DefaultFlags() {
4910 return CAN_ALLOCATE_IN_NEW_SPACE;
4911 }
4912
4913 static Flags DefaultFlags(ElementsKind kind) {
4914 Flags flags = CAN_ALLOCATE_IN_NEW_SPACE;
4915 if (IsFastDoubleElementsKind(kind)) {
4916 flags = static_cast<HAllocate::Flags>(
4917 flags | HAllocate::ALLOCATE_DOUBLE_ALIGNED);
4918 }
4919 return flags;
4920 }
4921
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004922 HValue* context() { return OperandAt(0); }
4923 HValue* size() { return OperandAt(1); }
4924
4925 virtual Representation RequiredInputRepresentation(int index) {
4926 if (index == 0) {
4927 return Representation::Tagged();
4928 } else {
4929 return Representation::Integer32();
4930 }
4931 }
4932
4933 virtual HType CalculateInferredType();
4934
4935 bool CanAllocateInNewSpace() const {
4936 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0;
4937 }
4938
4939 bool CanAllocateInOldDataSpace() const {
4940 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0;
4941 }
4942
4943 bool CanAllocateInOldPointerSpace() const {
4944 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
4945 }
4946
4947 bool CanAllocateInOldSpace() const {
4948 return CanAllocateInOldDataSpace() ||
4949 CanAllocateInOldPointerSpace();
4950 }
4951
4952 bool GuaranteedInNewSpace() const {
4953 return CanAllocateInNewSpace() && !CanAllocateInOldSpace();
4954 }
4955
4956 bool MustAllocateDoubleAligned() const {
4957 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
4958 }
4959
ulan@chromium.org750145a2013-03-07 15:14:13 +00004960 virtual void PrintDataTo(StringStream* stream);
4961
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004962 DECLARE_CONCRETE_INSTRUCTION(Allocate)
4963
4964 private:
4965 HType type_;
4966 Flags flags_;
4967};
4968
4969
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00004970class HInnerAllocatedObject: public HTemplateInstruction<1> {
4971 public:
4972 HInnerAllocatedObject(HValue* value, int offset)
4973 : offset_(offset) {
4974 ASSERT(value->IsAllocate());
4975 SetOperandAt(0, value);
4976 set_representation(Representation::Tagged());
4977 }
4978
4979 HValue* base_object() { return OperandAt(0); }
4980 int offset() { return offset_; }
4981
4982 virtual Representation RequiredInputRepresentation(int index) {
4983 return Representation::Tagged();
4984 }
4985
4986 virtual void PrintDataTo(StringStream* stream);
4987
4988 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
4989
4990 private:
4991 int offset_;
4992};
4993
4994
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004995inline bool StoringValueNeedsWriteBarrier(HValue* value) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004996 return !value->type().IsBoolean()
4997 && !value->type().IsSmi()
4998 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
4999}
5000
5001
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005002inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
5003 HValue* new_space_dominator) {
svenpanne@chromium.org2bda5432013-03-15 12:39:50 +00005004 if (object->IsInnerAllocatedObject()) {
5005 return ReceiverObjectNeedsWriteBarrier(
5006 HInnerAllocatedObject::cast(object)->base_object(),
5007 new_space_dominator);
5008 }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005009 if (object != new_space_dominator) return true;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005010 if (object->IsAllocateObject()) return false;
5011 if (object->IsAllocate()) {
5012 return !HAllocate::cast(object)->GuaranteedInNewSpace();
5013 }
5014 return true;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005015}
5016
5017
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005018class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005019 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005020 HStoreGlobalCell(HValue* value,
5021 Handle<JSGlobalPropertyCell> cell,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005022 PropertyDetails details)
ager@chromium.org378b34e2011-01-28 08:04:38 +00005023 : HUnaryOperation(value),
5024 cell_(cell),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005025 details_(details) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005026 SetGVNFlag(kChangesGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005027 }
5028
5029 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005030 bool RequiresHoleCheck() {
5031 return !details_.IsDontDelete() || details_.IsReadOnly();
5032 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005033 bool NeedsWriteBarrier() {
5034 return StoringValueNeedsWriteBarrier(value());
5035 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005036
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005037 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005038 return Representation::Tagged();
5039 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005040 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005041
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005042 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005043
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005044 private:
5045 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005046 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005047};
5048
5049
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005050class HStoreGlobalGeneric: public HTemplateInstruction<3> {
5051 public:
5052 HStoreGlobalGeneric(HValue* context,
5053 HValue* global_object,
5054 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005055 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005056 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005057 : name_(name),
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005058 strict_mode_flag_(strict_mode_flag) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005059 SetOperandAt(0, context);
5060 SetOperandAt(1, global_object);
5061 SetOperandAt(2, value);
5062 set_representation(Representation::Tagged());
5063 SetAllSideEffects();
5064 }
5065
5066 HValue* context() { return OperandAt(0); }
5067 HValue* global_object() { return OperandAt(1); }
5068 Handle<Object> name() const { return name_; }
5069 HValue* value() { return OperandAt(2); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005070 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005071
5072 virtual void PrintDataTo(StringStream* stream);
5073
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005074 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005075 return Representation::Tagged();
5076 }
5077
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005078 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005079
5080 private:
5081 Handle<Object> name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005082 StrictModeFlag strict_mode_flag_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00005083};
5084
5085
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005086class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005087 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005088 enum Mode {
5089 // Perform a normal load of the context slot without checking its value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005090 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005091 // Load and check the value of the context slot. Deoptimize if it's the
5092 // hole value. This is used for checking for loading of uninitialized
5093 // harmony bindings where we deoptimize into full-codegen generated code
5094 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005095 kCheckDeoptimize,
5096 // Load and check the value of the context slot. Return undefined if it's
5097 // the hole value. This is used for non-harmony const assignments
5098 kCheckReturnUndefined
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005099 };
5100
5101 HLoadContextSlot(HValue* context, Variable* var)
5102 : HUnaryOperation(context), slot_index_(var->index()) {
5103 ASSERT(var->IsContextSlot());
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005104 switch (var->mode()) {
5105 case LET:
5106 case CONST_HARMONY:
5107 mode_ = kCheckDeoptimize;
5108 break;
5109 case CONST:
5110 mode_ = kCheckReturnUndefined;
5111 break;
5112 default:
5113 mode_ = kNoCheck;
5114 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005115 set_representation(Representation::Tagged());
5116 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005117 SetGVNFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005118 }
5119
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005120 int slot_index() const { return slot_index_; }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005121 Mode mode() const { return mode_; }
5122
5123 bool DeoptimizesOnHole() {
5124 return mode_ == kCheckDeoptimize;
5125 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005126
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005127 bool RequiresHoleCheck() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005128 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005129 }
5130
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005131 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005132 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005133 }
5134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005135 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005136
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005137 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005138
5139 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005140 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005141 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005142 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005143 }
5144
5145 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005146 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
5147
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005148 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005149 Mode mode_;
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005150};
5151
5152
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005153class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005154 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005155 enum Mode {
5156 // Perform a normal store to the context slot without checking its previous
5157 // value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005158 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005159 // Check the previous value of the context slot and deoptimize if it's the
5160 // hole value. This is used for checking for assignments to uninitialized
5161 // harmony bindings where we deoptimize into full-codegen generated code
5162 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005163 kCheckDeoptimize,
5164 // Check the previous value and ignore assignment if it isn't a hole value
5165 kCheckIgnoreAssignment
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005166 };
5167
5168 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
5169 : slot_index_(slot_index), mode_(mode) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005170 SetOperandAt(0, context);
5171 SetOperandAt(1, value);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005172 SetGVNFlag(kChangesContextSlots);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005173 }
5174
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005175 HValue* context() { return OperandAt(0); }
5176 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005177 int slot_index() const { return slot_index_; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005178 Mode mode() const { return mode_; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005180 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005181 return StoringValueNeedsWriteBarrier(value());
5182 }
5183
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005184 bool DeoptimizesOnHole() {
5185 return mode_ == kCheckDeoptimize;
5186 }
5187
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005188 bool RequiresHoleCheck() {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005189 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005190 }
5191
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005192 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005193 return Representation::Tagged();
5194 }
5195
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005196 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005197
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005198 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005199
5200 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005201 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005202 Mode mode_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00005203};
5204
5205
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005206class HLoadNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005207 public:
danno@chromium.orgf005df62013-04-30 16:36:45 +00005208 HLoadNamedField(HValue* object, bool is_in_object,
5209 Representation field_representation,
5210 int offset, HValue* typecheck = NULL)
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005211 : is_in_object_(is_in_object),
danno@chromium.orgf005df62013-04-30 16:36:45 +00005212 field_representation_(field_representation),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005213 offset_(offset) {
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005214 ASSERT(object != NULL);
5215 SetOperandAt(0, object);
5216 SetOperandAt(1, typecheck != NULL ? typecheck : object);
5217
danno@chromium.orgf005df62013-04-30 16:36:45 +00005218 if (FLAG_track_fields && field_representation.IsSmi()) {
5219 set_type(HType::Smi());
5220 set_representation(Representation::Tagged());
5221 } else if (FLAG_track_double_fields && field_representation.IsDouble()) {
5222 set_representation(field_representation);
5223 } else {
5224 set_representation(Representation::Tagged());
5225 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005226 SetFlag(kUseGVN);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005227 if (FLAG_track_double_fields && representation().IsDouble()) {
5228 ASSERT(is_in_object);
5229 ASSERT(offset == HeapNumber::kValueOffset);
5230 SetGVNFlag(kDependsOnDoubleFields);
5231 } else if (is_in_object) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005232 SetGVNFlag(kDependsOnInobjectFields);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005233 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005234 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005235 SetGVNFlag(kDependsOnBackingStoreFields);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005236 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005237 }
5238 }
5239
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005240 static HLoadNamedField* NewArrayLength(Zone* zone, HValue* object,
5241 HValue* typecheck,
5242 HType type = HType::Tagged()) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00005243 Representation representation =
5244 type.IsSmi() ? Representation::Smi() : Representation::Tagged();
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005245 HLoadNamedField* result = new(zone) HLoadNamedField(
danno@chromium.orgf005df62013-04-30 16:36:45 +00005246 object, true, representation, JSArray::kLengthOffset, typecheck);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005247 result->set_type(type);
5248 result->SetGVNFlag(kDependsOnArrayLengths);
5249 result->ClearGVNFlag(kDependsOnInobjectFields);
5250 return result;
5251 }
5252
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005253 HValue* object() { return OperandAt(0); }
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +00005254 HValue* typecheck() {
5255 ASSERT(HasTypeCheck());
5256 return OperandAt(1);
5257 }
5258
5259 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005260 bool is_in_object() const { return is_in_object_; }
danno@chromium.orgf005df62013-04-30 16:36:45 +00005261 Representation field_representation() const { return representation_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005262 int offset() const { return offset_; }
5263
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005264 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005265 return Representation::Tagged();
5266 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005267 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005268
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005269 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005270
5271 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005272 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005273 HLoadNamedField* b = HLoadNamedField::cast(other);
5274 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
5275 }
5276
5277 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005278 virtual bool IsDeletable() const { return true; }
5279
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005280 bool is_in_object_;
danno@chromium.orgf005df62013-04-30 16:36:45 +00005281 Representation field_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005282 int offset_;
5283};
5284
5285
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005286class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005287 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005288 HLoadNamedFieldPolymorphic(HValue* context,
5289 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00005290 SmallMapList* types,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005291 Handle<String> name,
5292 Zone* zone);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005293
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005294 HValue* context() { return OperandAt(0); }
5295 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00005296 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005297 Handle<String> name() { return name_; }
5298 bool need_generic() { return need_generic_; }
5299
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005300 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005301 return Representation::Tagged();
5302 }
5303
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00005304 virtual void PrintDataTo(StringStream* stream);
5305
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005306 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005307
5308 static const int kMaxLoadPolymorphism = 4;
5309
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005310 virtual void FinalizeUniqueValueId();
5311
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005312 protected:
5313 virtual bool DataEquals(HValue* value);
5314
5315 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00005316 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005317 Handle<String> name_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005318 ZoneList<UniqueValueId> types_unique_ids_;
5319 UniqueValueId name_unique_id_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005320 bool need_generic_;
5321};
5322
5323
5324
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005325class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005326 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005327 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005328 : name_(name) {
5329 SetOperandAt(0, context);
5330 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005331 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00005332 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005333 }
5334
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005335 HValue* context() { return OperandAt(0); }
5336 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005337 Handle<Object> name() const { return name_; }
5338
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005339 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005340 return Representation::Tagged();
5341 }
5342
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00005343 virtual void PrintDataTo(StringStream* stream);
5344
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005345 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005346
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005347 private:
5348 Handle<Object> name_;
5349};
5350
5351
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005352class HLoadFunctionPrototype: public HUnaryOperation {
5353 public:
5354 explicit HLoadFunctionPrototype(HValue* function)
5355 : HUnaryOperation(function) {
5356 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00005357 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005358 SetGVNFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005359 }
5360
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005361 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005362
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005363 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005364 return Representation::Tagged();
5365 }
5366
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005367 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005368
5369 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005370 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005371};
5372
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005373class ArrayInstructionInterface {
5374 public:
5375 virtual HValue* GetKey() = 0;
5376 virtual void SetKey(HValue* key) = 0;
5377 virtual void SetIndexOffset(uint32_t index_offset) = 0;
5378 virtual bool IsDehoisted() = 0;
5379 virtual void SetDehoisted(bool is_dehoisted) = 0;
5380 virtual ~ArrayInstructionInterface() { };
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005381
5382 static Representation KeyedAccessIndexRequirement(Representation r) {
5383 return r.IsInteger32() ? Representation::Integer32()
5384 : Representation::Tagged();
5385 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005386};
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005387
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005388
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005389enum LoadKeyedHoleMode {
5390 NEVER_RETURN_HOLE,
5391 ALLOW_RETURN_HOLE
5392};
5393
5394
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005395class HLoadKeyed
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005396 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005397 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005398 HLoadKeyed(HValue* obj,
5399 HValue* key,
5400 HValue* dependency,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005401 ElementsKind elements_kind,
5402 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005403 : bit_field_(0) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005404 bit_field_ = ElementsKindField::encode(elements_kind) |
5405 HoleModeField::encode(mode);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005406
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005407 SetOperandAt(0, obj);
5408 SetOperandAt(1, key);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005409 SetOperandAt(2, dependency != NULL ? dependency : obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005410
5411 if (!is_external()) {
5412 // I can detect the case between storing double (holey and fast) and
5413 // smi/object by looking at elements_kind_.
5414 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5415 IsFastDoubleElementsKind(elements_kind));
5416
5417 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005418 if (IsFastSmiElementsKind(elements_kind)) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005419 set_type(HType::Smi());
5420 }
5421
5422 set_representation(Representation::Tagged());
5423 SetGVNFlag(kDependsOnArrayElements);
5424 } else {
5425 set_representation(Representation::Double());
5426 SetGVNFlag(kDependsOnDoubleArrayElements);
5427 }
5428 } else {
5429 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5430 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5431 set_representation(Representation::Double());
5432 } else {
5433 set_representation(Representation::Integer32());
5434 }
5435
5436 SetGVNFlag(kDependsOnSpecializedArrayElements);
5437 // Native code could change the specialized array.
5438 SetGVNFlag(kDependsOnCalls);
5439 }
5440
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005441 SetFlag(kUseGVN);
5442 }
5443
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005444 bool is_external() const {
5445 return IsExternalArrayElementsKind(elements_kind());
5446 }
5447 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005448 HValue* key() { return OperandAt(1); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005449 HValue* dependency() {
5450 ASSERT(HasDependency());
5451 return OperandAt(2);
5452 }
5453 bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005454 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
5455 void SetIndexOffset(uint32_t index_offset) {
5456 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
5457 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005458 HValue* GetKey() { return key(); }
5459 void SetKey(HValue* key) { SetOperandAt(1, key); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005460 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
5461 void SetDehoisted(bool is_dehoisted) {
5462 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
5463 }
5464 ElementsKind elements_kind() const {
5465 return ElementsKindField::decode(bit_field_);
5466 }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005467 LoadKeyedHoleMode hole_mode() const {
5468 return HoleModeField::decode(bit_field_);
5469 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005470
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005471 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005472 // kind_fast: tagged[int32] (none)
5473 // kind_double: tagged[int32] (none)
5474 // kind_external: external[int32] (none)
5475 if (index == 0) {
5476 return is_external() ? Representation::External()
5477 : Representation::Tagged();
5478 }
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005479 if (index == 1) {
5480 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5481 OperandAt(1)->representation());
5482 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005483 return Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005484 }
5485
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005486 virtual Representation observed_input_representation(int index) {
5487 return RequiredInputRepresentation(index);
5488 }
5489
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005490 virtual void PrintDataTo(StringStream* stream);
5491
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005492 bool UsesMustHandleHole() const;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005493 bool RequiresHoleCheck() const;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005494
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005495 virtual Range* InferRange(Zone* zone);
5496
5497 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
ager@chromium.org378b34e2011-01-28 08:04:38 +00005498
5499 protected:
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005500 virtual bool DataEquals(HValue* other) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005501 if (!other->IsLoadKeyed()) return false;
5502 HLoadKeyed* other_load = HLoadKeyed::cast(other);
5503
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005504 if (IsDehoisted() && index_offset() != other_load->index_offset())
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005505 return false;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005506 return elements_kind() == other_load->elements_kind();
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005507 }
5508
5509 private:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005510 virtual bool IsDeletable() const {
5511 return !RequiresHoleCheck();
5512 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005513
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005514 // Establish some checks around our packed fields
5515 enum LoadKeyedBits {
5516 kBitsForElementsKind = 5,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005517 kBitsForHoleMode = 1,
5518 kBitsForIndexOffset = 25,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005519 kBitsForIsDehoisted = 1,
5520
5521 kStartElementsKind = 0,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005522 kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
5523 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005524 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset
5525 };
5526
5527 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset +
5528 kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
5529 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
5530 class ElementsKindField:
5531 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
5532 {}; // NOLINT
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005533 class HoleModeField:
5534 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
5535 {}; // NOLINT
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005536 class IndexOffsetField:
5537 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset>
5538 {}; // NOLINT
5539 class IsDehoistedField:
5540 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
5541 {}; // NOLINT
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005542 uint32_t bit_field_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005543};
5544
5545
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005546class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005547 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005548 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005549 set_representation(Representation::Tagged());
5550 SetOperandAt(0, obj);
5551 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005552 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005553 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005554 }
5555
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005556 HValue* object() { return OperandAt(0); }
5557 HValue* key() { return OperandAt(1); }
5558 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005559
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005560 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005561
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005562 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005563 // tagged[tagged]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005564 return Representation::Tagged();
5565 }
5566
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005567 virtual HValue* Canonicalize();
5568
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005569 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005570};
5571
5572
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005573class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005574 public:
5575 HStoreNamedField(HValue* obj,
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005576 Handle<Name> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005577 HValue* val,
5578 bool in_object,
danno@chromium.orgf005df62013-04-30 16:36:45 +00005579 Representation field_representation,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005580 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005581 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005582 is_in_object_(in_object),
danno@chromium.orgf005df62013-04-30 16:36:45 +00005583 field_representation_(field_representation),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005584 offset_(offset),
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005585 transition_unique_id_(),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005586 new_space_dominator_(NULL) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005587 SetOperandAt(0, obj);
5588 SetOperandAt(1, val);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005589 SetFlag(kTrackSideEffectDominators);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005590 if (FLAG_track_double_fields && field_representation.IsDouble()) {
5591 SetGVNFlag(kChangesDoubleFields);
5592 } else if (is_in_object_) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005593 SetGVNFlag(kChangesInobjectFields);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005594 SetGVNFlag(kDependsOnNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005595 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005596 SetGVNFlag(kChangesBackingStoreFields);
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005597 SetGVNFlag(kDependsOnNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005598 }
5599 }
5600
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005601 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005602
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005603 virtual Representation RequiredInputRepresentation(int index) {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005604 if (FLAG_track_double_fields &&
5605 index == 1 && field_representation_.IsDouble()) {
5606 return field_representation_;
5607 } else if (FLAG_track_fields &&
5608 index == 1 && field_representation_.IsSmi()) {
danno@chromium.orgf005df62013-04-30 16:36:45 +00005609 return Representation::Integer32();
5610 }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005611 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005612 }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005613 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5614 ASSERT(side_effect == kChangesNewSpacePromotion);
5615 new_space_dominator_ = dominator;
5616 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005617 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005618
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005619 HValue* object() { return OperandAt(0); }
5620 HValue* value() { return OperandAt(1); }
5621
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005622 Handle<Name> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005623 bool is_in_object() const { return is_in_object_; }
5624 int offset() const { return offset_; }
5625 Handle<Map> transition() const { return transition_; }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005626 UniqueValueId transition_unique_id() const { return transition_unique_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005627 void set_transition(Handle<Map> map) { transition_ = map; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005628 HValue* new_space_dominator() const { return new_space_dominator_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005629
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005630 bool NeedsWriteBarrier() {
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005631 ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) ||
5632 transition_.is_null());
danno@chromium.orgf005df62013-04-30 16:36:45 +00005633 return (!FLAG_track_fields || !field_representation_.IsSmi()) &&
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005634 // If there is a transition, a new storage object needs to be allocated.
5635 !(FLAG_track_double_fields && field_representation_.IsDouble()) &&
danno@chromium.orgf005df62013-04-30 16:36:45 +00005636 StoringValueNeedsWriteBarrier(value()) &&
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005637 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005638 }
5639
verwaest@chromium.org37141392012-05-31 13:27:02 +00005640 bool NeedsWriteBarrierForMap() {
5641 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5642 }
5643
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005644 virtual void FinalizeUniqueValueId() {
5645 transition_unique_id_ = UniqueValueId(transition_);
5646 }
5647
danno@chromium.orgf005df62013-04-30 16:36:45 +00005648 Representation field_representation() const {
5649 return field_representation_;
5650 }
5651
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005652 private:
ulan@chromium.org57ff8812013-05-10 08:16:55 +00005653 Handle<Name> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005654 bool is_in_object_;
danno@chromium.orgf005df62013-04-30 16:36:45 +00005655 Representation field_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005656 int offset_;
5657 Handle<Map> transition_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005658 UniqueValueId transition_unique_id_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005659 HValue* new_space_dominator_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005660};
5661
5662
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005663class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005664 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005665 HStoreNamedGeneric(HValue* context,
5666 HValue* object,
5667 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005668 HValue* value,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005669 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005670 : name_(name),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005671 strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005672 SetOperandAt(0, object);
5673 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005674 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005675 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005676 }
5677
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005678 HValue* object() { return OperandAt(0); }
5679 HValue* value() { return OperandAt(1); }
5680 HValue* context() { return OperandAt(2); }
5681 Handle<String> name() { return name_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005682 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005683
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005684 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005685
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005686 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005687 return Representation::Tagged();
5688 }
5689
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005690 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005691
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005692 private:
5693 Handle<String> name_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005694 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005695};
5696
5697
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005698class HStoreKeyed
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005699 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005700 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005701 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
5702 ElementsKind elements_kind)
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005703 : elements_kind_(elements_kind),
5704 index_offset_(0),
5705 is_dehoisted_(false),
5706 new_space_dominator_(NULL) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005707 SetOperandAt(0, obj);
5708 SetOperandAt(1, key);
5709 SetOperandAt(2, val);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005710
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005711 if (IsFastObjectElementsKind(elements_kind)) {
5712 SetFlag(kTrackSideEffectDominators);
5713 SetGVNFlag(kDependsOnNewSpacePromotion);
5714 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005715 if (is_external()) {
5716 SetGVNFlag(kChangesSpecializedArrayElements);
5717 } else if (IsFastDoubleElementsKind(elements_kind)) {
5718 SetGVNFlag(kChangesDoubleArrayElements);
5719 SetFlag(kDeoptimizeOnUndefined);
5720 } else {
5721 SetGVNFlag(kChangesArrayElements);
5722 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005723
5724 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
5725 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
5726 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
5727 SetFlag(kTruncatingToInt32);
5728 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005729 }
5730
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005731 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005732 // kind_fast: tagged[int32] = tagged
5733 // kind_double: tagged[int32] = double
5734 // kind_external: external[int32] = (double | int32)
5735 if (index == 0) {
5736 return is_external() ? Representation::External()
5737 : Representation::Tagged();
5738 } else if (index == 1) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005739 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5740 OperandAt(1)->representation());
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005741 }
5742
5743 ASSERT_EQ(index, 2);
5744 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5745 return Representation::Double();
5746 }
5747
5748 return is_external() ? Representation::Integer32()
5749 : Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005750 }
5751
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005752 bool is_external() const {
5753 return IsExternalArrayElementsKind(elements_kind());
5754 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005755
5756 virtual Representation observed_input_representation(int index) {
5757 if (index < 2) return RequiredInputRepresentation(index);
5758 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5759 return Representation::Double();
5760 }
5761 if (is_external()) {
5762 return Representation::Integer32();
5763 }
5764 // For fast object elements kinds, don't assume anything.
5765 return Representation::None();
5766 }
5767
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005768 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005769 HValue* key() { return OperandAt(1); }
5770 HValue* value() { return OperandAt(2); }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005771 bool value_is_smi() const {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005772 return IsFastSmiElementsKind(elements_kind_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005773 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005774 ElementsKind elements_kind() const { return elements_kind_; }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005775 uint32_t index_offset() { return index_offset_; }
5776 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
5777 HValue* GetKey() { return key(); }
5778 void SetKey(HValue* key) { SetOperandAt(1, key); }
5779 bool IsDehoisted() { return is_dehoisted_; }
5780 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005781
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005782 bool IsConstantHoleStore() {
5783 return value()->IsConstant() && HConstant::cast(value())->IsTheHole();
5784 }
5785
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005786 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5787 ASSERT(side_effect == kChangesNewSpacePromotion);
5788 new_space_dominator_ = dominator;
5789 }
5790
5791 HValue* new_space_dominator() const { return new_space_dominator_; }
5792
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005793 bool NeedsWriteBarrier() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005794 if (value_is_smi()) {
5795 return false;
5796 } else {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005797 return StoringValueNeedsWriteBarrier(value()) &&
5798 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005799 }
5800 }
5801
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005802 bool NeedsCanonicalization();
5803
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005804 virtual void PrintDataTo(StringStream* stream);
5805
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005806 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005807
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005808 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005809 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005810 uint32_t index_offset_;
5811 bool is_dehoisted_;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005812 HValue* new_space_dominator_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005813};
5814
5815
5816class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005817 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005818 HStoreKeyedGeneric(HValue* context,
5819 HValue* object,
5820 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005821 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005822 StrictModeFlag strict_mode_flag)
5823 : strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005824 SetOperandAt(0, object);
5825 SetOperandAt(1, key);
5826 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005827 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005828 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005829 }
5830
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005831 HValue* object() { return OperandAt(0); }
5832 HValue* key() { return OperandAt(1); }
5833 HValue* value() { return OperandAt(2); }
5834 HValue* context() { return OperandAt(3); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005835 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005836
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005837 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005838 // tagged[tagged] = tagged
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005839 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005840 }
5841
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005842 virtual void PrintDataTo(StringStream* stream);
5843
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005844 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005845
5846 private:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005847 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005848};
5849
5850
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005851class HTransitionElementsKind: public HTemplateInstruction<2> {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005852 public:
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005853 HTransitionElementsKind(HValue* context,
5854 HValue* object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005855 Handle<Map> original_map,
5856 Handle<Map> transitioned_map)
5857 : original_map_(original_map),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005858 transitioned_map_(transitioned_map),
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005859 original_map_unique_id_(),
5860 transitioned_map_unique_id_(),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005861 from_kind_(original_map->elements_kind()),
5862 to_kind_(transitioned_map->elements_kind()) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005863 SetOperandAt(0, object);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005864 SetOperandAt(1, context);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005865 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005866 SetGVNFlag(kChangesElementsKind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005867 if (original_map->has_fast_double_elements()) {
5868 SetGVNFlag(kChangesElementsPointer);
5869 SetGVNFlag(kChangesNewSpacePromotion);
5870 }
5871 if (transitioned_map->has_fast_double_elements()) {
5872 SetGVNFlag(kChangesElementsPointer);
5873 SetGVNFlag(kChangesNewSpacePromotion);
5874 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005875 set_representation(Representation::Tagged());
5876 }
5877
5878 virtual Representation RequiredInputRepresentation(int index) {
5879 return Representation::Tagged();
5880 }
5881
5882 HValue* object() { return OperandAt(0); }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005883 HValue* context() { return OperandAt(1); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005884 Handle<Map> original_map() { return original_map_; }
5885 Handle<Map> transitioned_map() { return transitioned_map_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005886 ElementsKind from_kind() { return from_kind_; }
5887 ElementsKind to_kind() { return to_kind_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005888
5889 virtual void PrintDataTo(StringStream* stream);
5890
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005891 virtual void FinalizeUniqueValueId() {
5892 original_map_unique_id_ = UniqueValueId(original_map_);
5893 transitioned_map_unique_id_ = UniqueValueId(transitioned_map_);
5894 }
5895
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005896 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
5897
5898 protected:
5899 virtual bool DataEquals(HValue* other) {
5900 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005901 return original_map_unique_id_ == instr->original_map_unique_id_ &&
5902 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005903 }
5904
5905 private:
5906 Handle<Map> original_map_;
5907 Handle<Map> transitioned_map_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00005908 UniqueValueId original_map_unique_id_;
5909 UniqueValueId transitioned_map_unique_id_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005910 ElementsKind from_kind_;
5911 ElementsKind to_kind_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005912};
5913
5914
danno@chromium.org160a7b02011-04-18 15:51:38 +00005915class HStringAdd: public HBinaryOperation {
5916 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005917 static HInstruction* New(Zone* zone,
5918 HValue* context,
5919 HValue* left,
5920 HValue* right);
danno@chromium.org160a7b02011-04-18 15:51:38 +00005921
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005922 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00005923 return Representation::Tagged();
5924 }
5925
5926 virtual HType CalculateInferredType() {
5927 return HType::String();
5928 }
5929
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005930 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00005931
5932 protected:
5933 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005934
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005935
5936 private:
5937 HStringAdd(HValue* context, HValue* left, HValue* right)
5938 : HBinaryOperation(context, left, right) {
5939 set_representation(Representation::Tagged());
5940 SetFlag(kUseGVN);
5941 SetGVNFlag(kDependsOnMaps);
5942 SetGVNFlag(kChangesNewSpacePromotion);
5943 }
5944
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005945 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005946 // virtual bool IsDeletable() const { return true; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00005947};
5948
5949
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005950class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005951 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005952 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
5953 SetOperandAt(0, context);
5954 SetOperandAt(1, string);
5955 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005956 set_representation(Representation::Integer32());
5957 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005958 SetGVNFlag(kDependsOnMaps);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005959 SetGVNFlag(kChangesNewSpacePromotion);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005960 }
5961
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005962 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005963 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005964 return index == 2
5965 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005966 : Representation::Tagged();
5967 }
5968
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005969 HValue* context() { return OperandAt(0); }
5970 HValue* string() { return OperandAt(1); }
5971 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005972
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005973 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005974
5975 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005976 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00005977
ulan@chromium.org812308e2012-02-29 15:58:45 +00005978 virtual Range* InferRange(Zone* zone) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005979 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005980 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005981
5982 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
5983 // private:
5984 // virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005985};
5986
5987
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005988class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005989 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005990 static HInstruction* New(Zone* zone,
5991 HValue* context,
5992 HValue* char_code);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005993
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005994 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005995 return index == 0
5996 ? Representation::Tagged()
5997 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005998 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005999 virtual HType CalculateInferredType();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006000
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006001 HValue* context() { return OperandAt(0); }
6002 HValue* value() { return OperandAt(1); }
6003
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006004 virtual bool DataEquals(HValue* other) { return true; }
6005
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006006 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006007
ulan@chromium.org2e04b582013-02-21 14:06:02 +00006008 private:
6009 HStringCharFromCode(HValue* context, HValue* char_code) {
6010 SetOperandAt(0, context);
6011 SetOperandAt(1, char_code);
6012 set_representation(Representation::Tagged());
6013 SetFlag(kUseGVN);
6014 SetGVNFlag(kChangesNewSpacePromotion);
6015 }
6016
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006017 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
ulan@chromium.org2e04b582013-02-21 14:06:02 +00006018 // virtual bool IsDeletable() const { return true; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00006019};
6020
6021
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006022class HStringLength: public HUnaryOperation {
6023 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00006024 static HInstruction* New(Zone* zone, HValue* string);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006025
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006026 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006027 return Representation::Tagged();
6028 }
6029
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006030 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006031 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
6032 return HType::Smi();
6033 }
6034
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006035 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006036
6037 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006038 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00006039
ulan@chromium.org812308e2012-02-29 15:58:45 +00006040 virtual Range* InferRange(Zone* zone) {
6041 return new(zone) Range(0, String::kMaxLength);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006042 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006043
6044 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00006045 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
6046 set_representation(Representation::Tagged());
6047 SetFlag(kUseGVN);
6048 SetGVNFlag(kDependsOnMaps);
6049 }
6050
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006051 virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00006052};
6053
6054
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006055template <int V>
6056class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006057 public:
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00006058 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
6059 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
6060 this->set_representation(Representation::Tagged());
6061 }
6062
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006063 HMaterializedLiteral<V>(int index, int depth)
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00006064 : literal_index_(index), depth_(depth),
6065 allocation_site_mode_(DONT_TRACK_ALLOCATION_SITE) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006066 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006067 }
6068
6069 int literal_index() const { return literal_index_; }
6070 int depth() const { return depth_; }
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00006071 AllocationSiteMode allocation_site_mode() const {
6072 return allocation_site_mode_;
6073 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006074
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006075 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006076 virtual bool IsDeletable() const { return true; }
6077
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006078 int literal_index_;
6079 int depth_;
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00006080 AllocationSiteMode allocation_site_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006081};
6082
6083
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006084class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006085 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006086 HArrayLiteral(HValue* context,
ricow@chromium.org7ad65222011-12-19 12:13:11 +00006087 Handle<HeapObject> boilerplate_object,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006088 Handle<FixedArray> literals,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006089 int length,
6090 int literal_index,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00006091 int depth,
6092 AllocationSiteMode mode)
6093 : HMaterializedLiteral<1>(literal_index, depth, mode),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006094 length_(length),
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006095 boilerplate_object_(boilerplate_object),
6096 literals_(literals) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006097 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00006098 SetGVNFlag(kChangesNewSpacePromotion);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006099
6100 boilerplate_elements_kind_ = boilerplate_object_->IsJSObject()
6101 ? Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind()
6102 : TERMINAL_FAST_ELEMENTS_KIND;
6103
6104 is_copy_on_write_ = boilerplate_object_->IsJSObject() &&
6105 (Handle<JSObject>::cast(boilerplate_object_)->elements()->map() ==
6106 HEAP->fixed_cow_array_map());
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006107 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006108
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006109 HValue* context() { return OperandAt(0); }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00006110 ElementsKind boilerplate_elements_kind() const {
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006111 return boilerplate_elements_kind_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00006112 }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00006113 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006114 Handle<FixedArray> literals() const { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006115 int length() const { return length_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006116 bool IsCopyOnWrite() const { return is_copy_on_write_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006117
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006118 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006119 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006120 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00006121 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006122
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006123 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006124
6125 private:
6126 int length_;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00006127 Handle<HeapObject> boilerplate_object_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006128 Handle<FixedArray> literals_;
6129 ElementsKind boilerplate_elements_kind_;
6130 bool is_copy_on_write_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006131};
6132
6133
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006134class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006135 public:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006136 HObjectLiteral(HValue* context,
6137 Handle<FixedArray> constant_properties,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006138 Handle<FixedArray> literals,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006139 bool fast_elements,
6140 int literal_index,
6141 int depth,
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006142 bool may_store_doubles,
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006143 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006144 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006145 constant_properties_(constant_properties),
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006146 constant_properties_length_(constant_properties->length()),
6147 literals_(literals),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006148 fast_elements_(fast_elements),
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006149 may_store_doubles_(may_store_doubles),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006150 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00006151 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00006152 SetGVNFlag(kChangesNewSpacePromotion);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00006153 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006154
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006155 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006156 Handle<FixedArray> constant_properties() const {
6157 return constant_properties_;
6158 }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006159 int constant_properties_length() const {
6160 return constant_properties_length_;
6161 }
6162 Handle<FixedArray> literals() const { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006163 bool fast_elements() const { return fast_elements_; }
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006164 bool may_store_doubles() const { return may_store_doubles_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006165 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006166
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006167 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006168 return Representation::Tagged();
6169 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00006170 virtual HType CalculateInferredType();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00006171
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00006172 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006173
6174 private:
6175 Handle<FixedArray> constant_properties_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006176 int constant_properties_length_;
6177 Handle<FixedArray> literals_;
6178 bool fast_elements_ : 1;
ulan@chromium.org57ff8812013-05-10 08:16:55 +00006179 bool may_store_doubles_ : 1;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006180 bool has_function_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006181};
6182
6183
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006184class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006185 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006186 HRegExpLiteral(HValue* context,
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00006187 Handle<FixedArray> literals,
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006188 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006189 Handle<String> flags,
6190 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006191 : HMaterializedLiteral<1>(literal_index, 0),
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00006192 literals_(literals),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006193 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006194 flags_(flags) {
6195 SetOperandAt(0, context);
ricow@chromium.org27bf2882011-11-17 08:34:43 +00006196 SetAllSideEffects();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006197 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006198
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006199 HValue* context() { return OperandAt(0); }
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00006200 Handle<FixedArray> literals() { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006201 Handle<String> pattern() { return pattern_; }
6202 Handle<String> flags() { return flags_; }
6203
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006204 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006205 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006206 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00006207 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006209 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006210
6211 private:
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00006212 Handle<FixedArray> literals_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006213 Handle<String> pattern_;
6214 Handle<String> flags_;
6215};
6216
6217
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006218class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006219 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006220 HFunctionLiteral(HValue* context,
6221 Handle<SharedFunctionInfo> shared,
6222 bool pretenure)
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006223 : shared_info_(shared),
6224 pretenure_(pretenure),
6225 has_no_literals_(shared->num_literals() == 0),
6226 is_generator_(shared->is_generator()),
6227 language_mode_(shared->language_mode()) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006228 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006229 set_representation(Representation::Tagged());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00006230 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006231 }
6232
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006233 HValue* context() { return OperandAt(0); }
6234
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006235 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006236 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006237 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00006238 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006239
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006240 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006241
6242 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
6243 bool pretenure() const { return pretenure_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006244 bool has_no_literals() const { return has_no_literals_; }
6245 bool is_generator() const { return is_generator_; }
6246 LanguageMode language_mode() const { return language_mode_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006247
6248 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006249 virtual bool IsDeletable() const { return true; }
6250
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006251 Handle<SharedFunctionInfo> shared_info_;
ulan@chromium.org32d7dba2013-04-24 10:59:06 +00006252 bool pretenure_ : 1;
6253 bool has_no_literals_ : 1;
6254 bool is_generator_ : 1;
6255 LanguageMode language_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006256};
6257
6258
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006259class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006260 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006261 explicit HTypeof(HValue* context, HValue* value) {
6262 SetOperandAt(0, context);
6263 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006264 set_representation(Representation::Tagged());
6265 }
6266
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006267 HValue* context() { return OperandAt(0); }
6268 HValue* value() { return OperandAt(1); }
6269
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006270 virtual void PrintDataTo(StringStream* stream);
6271
6272 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00006273 return Representation::Tagged();
6274 }
6275
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006276 DECLARE_CONCRETE_INSTRUCTION(Typeof)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006277
6278 private:
6279 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006280};
6281
6282
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00006283class HTrapAllocationMemento : public HTemplateInstruction<1> {
6284 public:
6285 explicit HTrapAllocationMemento(HValue* obj) {
6286 SetOperandAt(0, obj);
6287 }
6288
6289 virtual Representation RequiredInputRepresentation(int index) {
6290 return Representation::Tagged();
6291 }
6292
6293 HValue* object() { return OperandAt(0); }
6294
6295 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
6296};
6297
6298
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006299class HToFastProperties: public HUnaryOperation {
6300 public:
6301 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
6302 // This instruction is not marked as having side effects, but
6303 // changes the map of the input operand. Use it only when creating
6304 // object literals.
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +00006305 ASSERT(value->IsObjectLiteral());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006306 set_representation(Representation::Tagged());
6307 }
6308
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006309 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006310 return Representation::Tagged();
6311 }
6312
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006313 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006314
6315 private:
6316 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00006317};
6318
6319
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006320class HValueOf: public HUnaryOperation {
6321 public:
6322 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
6323 set_representation(Representation::Tagged());
6324 }
6325
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006326 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006327 return Representation::Tagged();
6328 }
6329
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006330 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006331
6332 private:
6333 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006334};
6335
6336
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00006337class HDateField: public HUnaryOperation {
6338 public:
6339 HDateField(HValue* date, Smi* index)
6340 : HUnaryOperation(date), index_(index) {
6341 set_representation(Representation::Tagged());
6342 }
6343
6344 Smi* index() const { return index_; }
6345
6346 virtual Representation RequiredInputRepresentation(int index) {
6347 return Representation::Tagged();
6348 }
6349
6350 DECLARE_CONCRETE_INSTRUCTION(DateField)
6351
6352 private:
6353 Smi* index_;
6354};
6355
6356
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00006357class HSeqStringSetChar: public HTemplateInstruction<3> {
6358 public:
6359 HSeqStringSetChar(String::Encoding encoding,
6360 HValue* string,
6361 HValue* index,
6362 HValue* value) : encoding_(encoding) {
6363 SetOperandAt(0, string);
6364 SetOperandAt(1, index);
6365 SetOperandAt(2, value);
6366 }
6367
6368 String::Encoding encoding() { return encoding_; }
6369 HValue* string() { return OperandAt(0); }
6370 HValue* index() { return OperandAt(1); }
6371 HValue* value() { return OperandAt(2); }
6372
6373 virtual Representation RequiredInputRepresentation(int index) {
6374 return Representation::Tagged();
6375 }
6376
6377 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
6378
6379 private:
6380 String::Encoding encoding_;
6381};
6382
6383
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006384class HDeleteProperty: public HBinaryOperation {
6385 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006386 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
6387 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006388 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00006389 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006390 }
6391
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006392 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006393 return Representation::Tagged();
6394 }
6395
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00006396 virtual HType CalculateInferredType();
6397
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00006398 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006399
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00006400 HValue* object() { return left(); }
6401 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006402};
6403
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006404
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006405class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006406 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006407 HIn(HValue* context, HValue* key, HValue* object) {
6408 SetOperandAt(0, context);
6409 SetOperandAt(1, key);
6410 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006411 set_representation(Representation::Tagged());
6412 SetAllSideEffects();
6413 }
6414
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00006415 HValue* context() { return OperandAt(0); }
6416 HValue* key() { return OperandAt(1); }
6417 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006418
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006419 virtual Representation RequiredInputRepresentation(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006420 return Representation::Tagged();
6421 }
6422
6423 virtual HType CalculateInferredType() {
6424 return HType::Boolean();
6425 }
6426
6427 virtual void PrintDataTo(StringStream* stream);
6428
6429 DECLARE_CONCRETE_INSTRUCTION(In)
6430};
6431
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006432
6433class HCheckMapValue: public HTemplateInstruction<2> {
6434 public:
6435 HCheckMapValue(HValue* value,
6436 HValue* map) {
6437 SetOperandAt(0, value);
6438 SetOperandAt(1, map);
6439 set_representation(Representation::Tagged());
6440 SetFlag(kUseGVN);
6441 SetGVNFlag(kDependsOnMaps);
6442 SetGVNFlag(kDependsOnElementsKind);
6443 }
6444
6445 virtual Representation RequiredInputRepresentation(int index) {
6446 return Representation::Tagged();
6447 }
6448
6449 virtual void PrintDataTo(StringStream* stream);
6450
6451 virtual HType CalculateInferredType() {
6452 return HType::Tagged();
6453 }
6454
6455 HValue* value() { return OperandAt(0); }
6456 HValue* map() { return OperandAt(1); }
6457
6458 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
6459
6460 protected:
6461 virtual bool DataEquals(HValue* other) {
6462 return true;
6463 }
6464};
6465
6466
6467class HForInPrepareMap : public HTemplateInstruction<2> {
6468 public:
6469 HForInPrepareMap(HValue* context,
6470 HValue* object) {
6471 SetOperandAt(0, context);
6472 SetOperandAt(1, object);
6473 set_representation(Representation::Tagged());
6474 SetAllSideEffects();
6475 }
6476
6477 virtual Representation RequiredInputRepresentation(int index) {
6478 return Representation::Tagged();
6479 }
6480
6481 HValue* context() { return OperandAt(0); }
6482 HValue* enumerable() { return OperandAt(1); }
6483
6484 virtual void PrintDataTo(StringStream* stream);
6485
6486 virtual HType CalculateInferredType() {
6487 return HType::Tagged();
6488 }
6489
6490 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
6491};
6492
6493
6494class HForInCacheArray : public HTemplateInstruction<2> {
6495 public:
6496 HForInCacheArray(HValue* enumerable,
6497 HValue* keys,
6498 int idx) : idx_(idx) {
6499 SetOperandAt(0, enumerable);
6500 SetOperandAt(1, keys);
6501 set_representation(Representation::Tagged());
6502 }
6503
6504 virtual Representation RequiredInputRepresentation(int index) {
6505 return Representation::Tagged();
6506 }
6507
6508 HValue* enumerable() { return OperandAt(0); }
6509 HValue* map() { return OperandAt(1); }
6510 int idx() { return idx_; }
6511
6512 HForInCacheArray* index_cache() {
6513 return index_cache_;
6514 }
6515
6516 void set_index_cache(HForInCacheArray* index_cache) {
6517 index_cache_ = index_cache;
6518 }
6519
6520 virtual void PrintDataTo(StringStream* stream);
6521
6522 virtual HType CalculateInferredType() {
6523 return HType::Tagged();
6524 }
6525
6526 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
6527
6528 private:
6529 int idx_;
6530 HForInCacheArray* index_cache_;
6531};
6532
6533
6534class HLoadFieldByIndex : public HTemplateInstruction<2> {
6535 public:
6536 HLoadFieldByIndex(HValue* object,
6537 HValue* index) {
6538 SetOperandAt(0, object);
6539 SetOperandAt(1, index);
6540 set_representation(Representation::Tagged());
6541 }
6542
6543 virtual Representation RequiredInputRepresentation(int index) {
6544 return Representation::Tagged();
6545 }
6546
6547 HValue* object() { return OperandAt(0); }
6548 HValue* index() { return OperandAt(1); }
6549
6550 virtual void PrintDataTo(StringStream* stream);
6551
6552 virtual HType CalculateInferredType() {
6553 return HType::Tagged();
6554 }
6555
6556 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006557
6558 private:
6559 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006560};
6561
6562
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006563#undef DECLARE_INSTRUCTION
6564#undef DECLARE_CONCRETE_INSTRUCTION
6565
6566} } // namespace v8::internal
6567
6568#endif // V8_HYDROGEN_INSTRUCTIONS_H_