blob: d2b3fc5d8c9de497316e5e8580acbffb3eca42ca [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) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000078 V(Branch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000079 V(CallConstantFunction) \
80 V(CallFunction) \
81 V(CallGlobal) \
82 V(CallKeyed) \
83 V(CallKnownGlobal) \
84 V(CallNamed) \
85 V(CallNew) \
86 V(CallRuntime) \
87 V(CallStub) \
88 V(Change) \
89 V(CheckFunction) \
90 V(CheckInstanceType) \
jkummerow@chromium.org1456e702012-03-30 08:38:13 +000091 V(CheckMaps) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000092 V(CheckNonSmi) \
93 V(CheckPrototypeMaps) \
94 V(CheckSmi) \
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +000095 V(CheckSmiOrInt32) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +000096 V(ClampToUint8) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +000097 V(ClassOfTestAndBranch) \
98 V(CompareIDAndBranch) \
99 V(CompareGeneric) \
100 V(CompareObjectEqAndBranch) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000101 V(CompareMap) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000102 V(CompareConstantEqAndBranch) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000103 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000104 V(Context) \
yangguo@chromium.org56454712012-02-16 15:33:53 +0000105 V(DeclareGlobals) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(DeleteProperty) \
107 V(Deoptimize) \
108 V(Div) \
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000109 V(DummyUse) \
whesse@chromium.org7b260152011-06-20 15:33:18 +0000110 V(ElementsKind) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000111 V(EnterInlined) \
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000112 V(FastLiteral) \
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000113 V(FixedArrayBaseLength) \
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000114 V(ForceRepresentation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000116 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(GlobalObject) \
118 V(GlobalReceiver) \
119 V(Goto) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000120 V(HasCachedArrayIndexAndBranch) \
121 V(HasInstanceTypeAndBranch) \
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000122 V(InductionVariableAnnotation) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000123 V(In) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000124 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000125 V(InstanceOfKnownGlobal) \
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +0000126 V(InstanceSize) \
danno@chromium.org160a7b02011-04-18 15:51:38 +0000127 V(InvokeFunction) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000128 V(IsConstructCallAndBranch) \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000129 V(IsNilAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000130 V(IsObjectAndBranch) \
erikcorry0ad885c2011-11-21 13:51:57 +0000131 V(IsStringAndBranch) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000132 V(IsSmiAndBranch) \
133 V(IsUndetectableAndBranch) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000134 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000135 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000136 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000137 V(LoadElements) \
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) \
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000209 V(ElementsKind) \
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000210 V(ElementsPointer) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000211 V(ArrayElements) \
ricow@chromium.org2c99e282011-07-28 09:15:17 +0000212 V(DoubleArrayElements) \
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000213 V(SpecializedArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214 V(GlobalVars) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000215 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000216 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217 V(OsrEntries)
218
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000219#define DECLARE_ABSTRACT_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000220 virtual bool Is##type() const { return true; } \
221 static H##type* cast(HValue* value) { \
222 ASSERT(value->Is##type()); \
223 return reinterpret_cast<H##type*>(value); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000224 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000225
226
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000227#define DECLARE_CONCRETE_INSTRUCTION(type) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000228 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000229 static H##type* cast(HValue* value) { \
230 ASSERT(value->Is##type()); \
231 return reinterpret_cast<H##type*>(value); \
232 } \
233 virtual Opcode opcode() const { return HValue::k##type; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000234
235
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000236#ifdef DEBUG
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000237#define ASSERT_ALLOCATION_DISABLED \
238 ASSERT(isolate()->optimizing_compiler_thread()->IsOptimizerThread() || \
239 !isolate()->heap()->IsAllocationAllowed())
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000240#else
241#define ASSERT_ALLOCATION_DISABLED do {} while (0)
242#endif
243
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000244class Range: public ZoneObject {
245 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000246 Range()
247 : lower_(kMinInt),
248 upper_(kMaxInt),
249 next_(NULL),
250 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000251
252 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000253 : lower_(lower),
254 upper_(upper),
255 next_(NULL),
256 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000257
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000258 int32_t upper() const { return upper_; }
259 int32_t lower() const { return lower_; }
260 Range* next() const { return next_; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000261 Range* CopyClearLower(Zone* zone) const {
262 return new(zone) Range(kMinInt, upper_);
263 }
264 Range* CopyClearUpper(Zone* zone) const {
265 return new(zone) Range(lower_, kMaxInt);
266 }
267 Range* Copy(Zone* zone) const {
268 Range* result = new(zone) Range(lower_, upper_);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000269 result->set_can_be_minus_zero(CanBeMinusZero());
270 return result;
271 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 int32_t Mask() const;
273 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
274 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
275 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
276 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000277 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000278 bool IsMostGeneric() const {
279 return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
280 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000281 bool IsInSmiRange() const {
282 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000283 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000284 void KeepOrder();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000285#ifdef DEBUG
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000286 void Verify() const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000287#endif
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000288
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 void StackUpon(Range* other) {
290 Intersect(other);
291 next_ = other;
292 }
293
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000294 void Intersect(Range* other);
295 void Union(Range* other);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000296 void CombinedMax(Range* other);
297 void CombinedMin(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000298
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000299 void AddConstant(int32_t value);
300 void Sar(int32_t value);
301 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302 bool AddAndCheckOverflow(Range* other);
303 bool SubAndCheckOverflow(Range* other);
304 bool MulAndCheckOverflow(Range* other);
305
306 private:
307 int32_t lower_;
308 int32_t upper_;
309 Range* next_;
310 bool can_be_minus_zero_;
311};
312
313
314class Representation {
315 public:
316 enum Kind {
317 kNone,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000318 kInteger32,
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000319 kDouble,
320 kTagged,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000321 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000322 kNumRepresentations
323 };
324
325 Representation() : kind_(kNone) { }
326
327 static Representation None() { return Representation(kNone); }
328 static Representation Tagged() { return Representation(kTagged); }
329 static Representation Integer32() { return Representation(kInteger32); }
330 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000331 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000332
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000333 static Representation FromKind(Kind kind) { return Representation(kind); }
334
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000335 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000336 return kind_ == other.kind_;
337 }
338
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000339 bool is_more_general_than(const Representation& other) {
340 ASSERT(kind_ != kExternal);
341 ASSERT(other.kind_ != kExternal);
342 return kind_ > other.kind_;
343 }
344
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000345 Kind kind() const { return static_cast<Kind>(kind_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000346 bool IsNone() const { return kind_ == kNone; }
347 bool IsTagged() const { return kind_ == kTagged; }
348 bool IsInteger32() const { return kind_ == kInteger32; }
349 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000350 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000351 bool IsSpecialization() const {
352 return kind_ == kInteger32 || kind_ == kDouble;
353 }
354 const char* Mnemonic() const;
355
356 private:
357 explicit Representation(Kind k) : kind_(k) { }
358
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000359 // Make sure kind fits in int8.
360 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
361
362 int8_t kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000363};
364
365
366class HType {
367 public:
368 HType() : type_(kUninitialized) { }
369
370 static HType Tagged() { return HType(kTagged); }
371 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
372 static HType TaggedNumber() { return HType(kTaggedNumber); }
373 static HType Smi() { return HType(kSmi); }
374 static HType HeapNumber() { return HType(kHeapNumber); }
375 static HType String() { return HType(kString); }
376 static HType Boolean() { return HType(kBoolean); }
377 static HType NonPrimitive() { return HType(kNonPrimitive); }
378 static HType JSArray() { return HType(kJSArray); }
379 static HType JSObject() { return HType(kJSObject); }
380 static HType Uninitialized() { return HType(kUninitialized); }
381
382 // Return the weakest (least precise) common type.
383 HType Combine(HType other) {
384 return HType(static_cast<Type>(type_ & other.type_));
385 }
386
387 bool Equals(const HType& other) {
388 return type_ == other.type_;
389 }
390
391 bool IsSubtypeOf(const HType& other) {
392 return Combine(other).Equals(other);
393 }
394
395 bool IsTagged() {
396 ASSERT(type_ != kUninitialized);
397 return ((type_ & kTagged) == kTagged);
398 }
399
400 bool IsTaggedPrimitive() {
401 ASSERT(type_ != kUninitialized);
402 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
403 }
404
405 bool IsTaggedNumber() {
406 ASSERT(type_ != kUninitialized);
407 return ((type_ & kTaggedNumber) == kTaggedNumber);
408 }
409
410 bool IsSmi() {
411 ASSERT(type_ != kUninitialized);
412 return ((type_ & kSmi) == kSmi);
413 }
414
415 bool IsHeapNumber() {
416 ASSERT(type_ != kUninitialized);
417 return ((type_ & kHeapNumber) == kHeapNumber);
418 }
419
420 bool IsString() {
421 ASSERT(type_ != kUninitialized);
422 return ((type_ & kString) == kString);
423 }
424
425 bool IsBoolean() {
426 ASSERT(type_ != kUninitialized);
427 return ((type_ & kBoolean) == kBoolean);
428 }
429
430 bool IsNonPrimitive() {
431 ASSERT(type_ != kUninitialized);
432 return ((type_ & kNonPrimitive) == kNonPrimitive);
433 }
434
435 bool IsJSArray() {
436 ASSERT(type_ != kUninitialized);
437 return ((type_ & kJSArray) == kJSArray);
438 }
439
440 bool IsJSObject() {
441 ASSERT(type_ != kUninitialized);
442 return ((type_ & kJSObject) == kJSObject);
443 }
444
445 bool IsUninitialized() {
446 return type_ == kUninitialized;
447 }
448
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000449 bool IsHeapObject() {
450 ASSERT(type_ != kUninitialized);
451 return IsHeapNumber() || IsString() || IsNonPrimitive();
452 }
453
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000454 static HType TypeFromValue(Isolate* isolate, Handle<Object> value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000455
456 const char* ToString();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000457
458 private:
459 enum Type {
460 kTagged = 0x1, // 0000 0000 0000 0001
461 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
462 kTaggedNumber = 0xd, // 0000 0000 0000 1101
463 kSmi = 0x1d, // 0000 0000 0001 1101
464 kHeapNumber = 0x2d, // 0000 0000 0010 1101
465 kString = 0x45, // 0000 0000 0100 0101
466 kBoolean = 0x85, // 0000 0000 1000 0101
467 kNonPrimitive = 0x101, // 0000 0001 0000 0001
468 kJSObject = 0x301, // 0000 0011 0000 0001
whesse@chromium.org7b260152011-06-20 15:33:18 +0000469 kJSArray = 0x701, // 0000 0111 0000 0001
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000470 kUninitialized = 0x1fff // 0001 1111 1111 1111
471 };
472
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000473 // Make sure type fits in int16.
474 STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
475
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000476 explicit HType(Type t) : type_(t) { }
477
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000478 int16_t type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479};
480
481
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000482class HUseListNode: public ZoneObject {
483 public:
484 HUseListNode(HValue* value, int index, HUseListNode* tail)
485 : tail_(tail), value_(value), index_(index) {
486 }
487
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000488 HUseListNode* tail();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000489 HValue* value() const { return value_; }
490 int index() const { return index_; }
491
492 void set_tail(HUseListNode* list) { tail_ = list; }
493
494#ifdef DEBUG
495 void Zap() {
496 tail_ = reinterpret_cast<HUseListNode*>(1);
497 value_ = NULL;
498 index_ = -1;
499 }
500#endif
501
502 private:
503 HUseListNode* tail_;
504 HValue* value_;
505 int index_;
506};
507
508
509// We reuse use list nodes behind the scenes as uses are added and deleted.
510// This class is the safe way to iterate uses while deleting them.
511class HUseIterator BASE_EMBEDDED {
512 public:
513 bool Done() { return current_ == NULL; }
514 void Advance();
515
516 HValue* value() {
517 ASSERT(!Done());
518 return value_;
519 }
520
521 int index() {
522 ASSERT(!Done());
523 return index_;
524 }
525
526 private:
527 explicit HUseIterator(HUseListNode* head);
528
529 HUseListNode* current_;
530 HUseListNode* next_;
531 HValue* value_;
532 int index_;
533
534 friend class HValue;
535};
536
537
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000538// There must be one corresponding kDepends flag for every kChanges flag and
539// the order of the kChanges flags must be exactly the same as of the kDepends
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000540// flags. All tracked flags should appear before untracked ones.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000541enum GVNFlag {
542 // Declare global value numbering flags.
543#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000544 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
545 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000546#undef DECLARE_FLAG
547 kAfterLastFlag,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000548 kLastFlag = kAfterLastFlag - 1,
549#define COUNT_FLAG(type) + 1
550 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
551#undef COUNT_FLAG
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000552};
553
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000554
555class NumericRelation {
556 public:
557 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
558 static const char* MnemonicFromKind(Kind kind) {
559 switch (kind) {
560 case NONE: return "NONE";
561 case EQ: return "EQ";
562 case GT: return "GT";
563 case GE: return "GE";
564 case LT: return "LT";
565 case LE: return "LE";
566 case NE: return "NE";
567 }
568 UNREACHABLE();
569 return NULL;
570 }
571 const char* Mnemonic() const { return MnemonicFromKind(kind_); }
572
573 static NumericRelation None() { return NumericRelation(NONE); }
574 static NumericRelation Eq() { return NumericRelation(EQ); }
575 static NumericRelation Gt() { return NumericRelation(GT); }
576 static NumericRelation Ge() { return NumericRelation(GE); }
577 static NumericRelation Lt() { return NumericRelation(LT); }
578 static NumericRelation Le() { return NumericRelation(LE); }
579 static NumericRelation Ne() { return NumericRelation(NE); }
580
581 bool IsNone() { return kind_ == NONE; }
582
583 static NumericRelation FromToken(Token::Value token) {
584 switch (token) {
585 case Token::EQ: return Eq();
586 case Token::EQ_STRICT: return Eq();
587 case Token::LT: return Lt();
588 case Token::GT: return Gt();
589 case Token::LTE: return Le();
590 case Token::GTE: return Ge();
591 case Token::NE: return Ne();
592 case Token::NE_STRICT: return Ne();
593 default: return None();
594 }
595 }
596
597 // The semantics of "Reversed" is that if "x rel y" is true then also
598 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
599 NumericRelation Reversed() {
600 switch (kind_) {
601 case NONE: return None();
602 case EQ: return Eq();
603 case GT: return Lt();
604 case GE: return Le();
605 case LT: return Gt();
606 case LE: return Ge();
607 case NE: return Ne();
608 }
609 UNREACHABLE();
610 return None();
611 }
612
613 // The semantics of "Negated" is that if "x rel y" is true then also
614 // "!(x rel.Negated() y)" is true.
615 NumericRelation Negated() {
616 switch (kind_) {
617 case NONE: return None();
618 case EQ: return Ne();
619 case GT: return Le();
620 case GE: return Lt();
621 case LT: return Ge();
622 case LE: return Gt();
623 case NE: return Eq();
624 }
625 UNREACHABLE();
626 return None();
627 }
628
629 // The semantics of "Implies" is that if "x rel y" is true
630 // then also "x other_relation y" is true.
631 bool Implies(NumericRelation other_relation) {
632 switch (kind_) {
633 case NONE: return false;
634 case EQ: return (other_relation.kind_ == EQ)
635 || (other_relation.kind_ == GE)
636 || (other_relation.kind_ == LE);
637 case GT: return (other_relation.kind_ == GT)
638 || (other_relation.kind_ == GE)
639 || (other_relation.kind_ == NE);
640 case LT: return (other_relation.kind_ == LT)
641 || (other_relation.kind_ == LE)
642 || (other_relation.kind_ == NE);
643 case GE: return (other_relation.kind_ == GE);
644 case LE: return (other_relation.kind_ == LE);
645 case NE: return (other_relation.kind_ == NE);
646 }
647 UNREACHABLE();
648 return false;
649 }
650
651 // The semantics of "IsExtendable" is that if
652 // "rel.IsExtendable(direction)" is true then
653 // "x rel y" implies "(x + direction) rel y" .
654 bool IsExtendable(int direction) {
655 switch (kind_) {
656 case NONE: return false;
657 case EQ: return false;
658 case GT: return (direction >= 0);
659 case GE: return (direction >= 0);
660 case LT: return (direction <= 0);
661 case LE: return (direction <= 0);
662 case NE: return false;
663 }
664 UNREACHABLE();
665 return false;
666 }
667
668 private:
669 explicit NumericRelation(Kind kind) : kind_(kind) {}
670
671 Kind kind_;
672};
673
674
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000675typedef EnumSet<GVNFlag> GVNFlagSet;
676
677
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000678class HValue: public ZoneObject {
679 public:
680 static const int kNoNumber = -1;
681
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000682 enum Flag {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000683 kFlexibleRepresentation,
whesse@chromium.org7b260152011-06-20 15:33:18 +0000684 // Participate in Global Value Numbering, i.e. elimination of
685 // unnecessary recomputations. If an instruction sets this flag, it must
686 // implement DataEquals(), which will be used to determine if other
687 // occurrences of the instruction are indeed the same.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000688 kUseGVN,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000689 // Track instructions that are dominating side effects. If an instruction
690 // sets this flag, it must implement SetSideEffectDominator() and should
691 // indicate which side effects to track by setting GVN flags.
692 kTrackSideEffectDominators,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000693 kCanOverflow,
694 kBailoutOnMinusZero,
695 kCanBeDivByZero,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000696 kDeoptimizeOnUndefined,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000697 kIsArguments,
698 kTruncatingToInt32,
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000699 kIsDead,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000700 // Instructions that are allowed to produce full range unsigned integer
701 // values are marked with kUint32 flag. If arithmetic shift or a load from
702 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
703 // it will deoptimize if result does not fit into signed integer range.
704 // HGraph::ComputeSafeUint32Operations is responsible for setting this
705 // flag.
706 kUint32,
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000707 // If a phi is involved in the evaluation of a numeric constraint the
708 // recursion can cause an endless cycle: we use this flag to exit the loop.
709 kNumericConstraintEvaluationInProgress,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000710 // This flag is set to true after the SetupInformativeDefinitions() pass
711 // has processed this instruction.
712 kIDefsProcessingDone,
713 kLastFlag = kIDefsProcessingDone
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000714 };
715
716 STATIC_ASSERT(kLastFlag < kBitsPerInt);
717
718 static const int kChangesToDependsFlagsLeftShift = 1;
719
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000720 static GVNFlag ChangesFlagFromInt(int x) {
721 return static_cast<GVNFlag>(x * 2);
722 }
723 static GVNFlag DependsOnFlagFromInt(int x) {
724 return static_cast<GVNFlag>(x * 2 + 1);
725 }
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000726 static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
727 return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000728 }
729
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000730 static HValue* cast(HValue* value) { return value; }
731
732 enum Opcode {
733 // Declare a unique enum value for each hydrogen instruction.
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000734 #define DECLARE_OPCODE(type) k##type,
735 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
736 kPhi
737 #undef DECLARE_OPCODE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000738 };
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000739 virtual Opcode opcode() const = 0;
740
741 // Declare a non-virtual predicates for each concrete HInstruction or HValue.
742 #define DECLARE_PREDICATE(type) \
743 bool Is##type() const { return opcode() == k##type; }
744 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
745 #undef DECLARE_PREDICATE
746 bool IsPhi() const { return opcode() == kPhi; }
747
748 // Declare virtual predicates for abstract HInstruction or HValue
749 #define DECLARE_PREDICATE(type) \
750 virtual bool Is##type() const { return false; }
751 HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
752 #undef DECLARE_PREDICATE
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000753
754 HValue() : block_(NULL),
755 id_(kNoNumber),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000756 type_(HType::Tagged()),
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000757 use_list_(NULL),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000758 range_(NULL),
759 flags_(0) {}
760 virtual ~HValue() {}
761
762 HBasicBlock* block() const { return block_; }
763 void SetBlock(HBasicBlock* block);
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000764 int LoopWeight() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000765
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000766 // Note: Never call this method for an unlinked value.
767 Isolate* isolate() const;
768
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000769 int id() const { return id_; }
770 void set_id(int id) { id_ = id; }
771
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000772 HUseIterator uses() const { return HUseIterator(use_list_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000773
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000774 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000775 Representation representation() const { return representation_; }
776 void ChangeRepresentation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000777 ASSERT(CheckFlag(kFlexibleRepresentation));
778 RepresentationChanged(r);
779 representation_ = r;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000780 if (r.IsTagged()) {
781 // Tagged is the bottom of the lattice, don't go any further.
782 ClearFlag(kFlexibleRepresentation);
783 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000784 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000785 virtual void AssumeRepresentation(Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000786
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000787 virtual bool IsConvertibleToInteger() const { return true; }
788
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000789 HType type() const { return type_; }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000790 void set_type(HType new_type) {
791 ASSERT(new_type.IsSubtypeOf(type_));
792 type_ = new_type;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000793 }
794
795 // An operation needs to override this function iff:
796 // 1) it can produce an int32 output.
797 // 2) the true value of its output can potentially be minus zero.
798 // The implementation must set a flag so that it bails out in the case where
799 // it would otherwise output what should be a minus zero as an int32 zero.
800 // If the operation also exists in a form that takes int32 and outputs int32
801 // then the operation should return its input value so that we can propagate
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +0000802 // back. There are three operations that need to propagate back to more than
803 // one input. They are phi and binary div and mul. They always return NULL
804 // and expect the caller to take care of things.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000805 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
806 visited->Add(id());
807 return NULL;
808 }
809
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000810 // There are HInstructions that do not really change a value, they
811 // only add pieces of information to it (like bounds checks, map checks,
812 // smi checks...).
813 // We call these instructions "informative definitions", or "iDef".
814 // One of the iDef operands is special because it is the value that is
815 // "transferred" to the output, we call it the "redefined operand".
816 // If an HValue is an iDef it must override RedefinedOperandIndex() so that
817 // it does not return kNoRedefinedOperand;
818 static const int kNoRedefinedOperand = -1;
819 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
820 bool IsInformativeDefinition() {
821 return RedefinedOperandIndex() != kNoRedefinedOperand;
822 }
823 HValue* RedefinedOperand() {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000824 return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex())
825 : NULL;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000826 }
827
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000828 // A purely informative definition is an idef that will not emit code and
829 // should therefore be removed from the graph in the RestoreActualValues
830 // phase (so that live ranges will be shorter).
831 virtual bool IsPurelyInformativeDefinition() { return false; }
832
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +0000833 // This method must always return the original HValue SSA definition
834 // (regardless of any iDef of this value).
835 HValue* ActualValue() {
836 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue()
837 : this;
838 }
839
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000840 virtual void AddInformativeDefinitions() {}
841
842 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
843 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
844 }
845 void UpdateRedefinedUses() {
846 UpdateRedefinedUsesInner<Dominates>();
847 }
848
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000849 bool IsInteger32Constant();
850 int32_t GetInteger32Constant();
851
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000852 bool IsDefinedAfter(HBasicBlock* other) const;
853
854 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000855 virtual int OperandCount() = 0;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000856 virtual HValue* OperandAt(int index) const = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000857 void SetOperandAt(int index, HValue* value);
858
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000859 void DeleteAndReplaceWith(HValue* other);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000860 void ReplaceAllUsesWith(HValue* other);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000861 bool HasNoUses() const { return use_list_ == NULL; }
862 bool HasMultipleUses() const {
863 return use_list_ != NULL && use_list_->tail() != NULL;
864 }
865 int UseCount() const;
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +0000866
867 // Mark this HValue as dead and to be removed from other HValues' use lists.
868 void Kill();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000869
870 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000871 void SetFlag(Flag f) { flags_ |= (1 << f); }
872 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
873 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
874
ulan@chromium.org812308e2012-02-29 15:58:45 +0000875 // Returns true if the flag specified is set for all uses, false otherwise.
876 bool CheckUsesForFlag(Flag f);
877
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000878 GVNFlagSet gvn_flags() const { return gvn_flags_; }
879 void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
880 void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
881 bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
882 void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
883 void ClearAllSideEffects() {
884 gvn_flags_.Remove(AllSideEffectsFlagSet());
885 }
886 bool HasSideEffects() const {
887 return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
888 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000889 bool HasObservableSideEffects() const {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000890 return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000891 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000892
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000893 GVNFlagSet DependsOnFlags() const {
894 GVNFlagSet result = gvn_flags_;
895 result.Intersect(AllDependsOnFlagSet());
896 return result;
897 }
898
899 GVNFlagSet SideEffectFlags() const {
900 GVNFlagSet result = gvn_flags_;
901 result.Intersect(AllSideEffectsFlagSet());
902 return result;
903 }
904
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000905 GVNFlagSet ChangesFlags() const {
906 GVNFlagSet result = gvn_flags_;
907 result.Intersect(AllChangesFlagSet());
908 return result;
909 }
910
911 GVNFlagSet ObservableChangesFlags() const {
912 GVNFlagSet result = gvn_flags_;
913 result.Intersect(AllChangesFlagSet());
914 result.Intersect(AllObservableSideEffectsFlagSet());
915 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000916 }
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000917
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000918 Range* range() const { return range_; }
919 bool HasRange() const { return range_ != NULL; }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000920 void AddNewRange(Range* r, Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000921 void RemoveLastAddedRange();
ulan@chromium.org812308e2012-02-29 15:58:45 +0000922 void ComputeInitialRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000923
924 // Representation helpers.
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000925 virtual Representation observed_input_representation(int index) {
926 return Representation::None();
927 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000928 virtual Representation RequiredInputRepresentation(int index) = 0;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +0000929 virtual void InferRepresentation(HInferRepresentation* h_infer);
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000930
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000931 // This gives the instruction an opportunity to replace itself with an
932 // instruction that does the same in some better way. To replace an
933 // instruction with a new one, first add the new instruction to the graph,
934 // then return it. Return NULL to have the instruction deleted.
935 virtual HValue* Canonicalize() { return this; }
936
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000937 bool Equals(HValue* other);
938 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000939
940 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000941 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000942 void PrintNameTo(StringStream* stream);
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000943 void PrintTypeTo(StringStream* stream);
944 void PrintRangeTo(StringStream* stream);
945 void PrintChangesTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000946
ricow@chromium.orgdcebac02011-04-20 09:44:50 +0000947 const char* Mnemonic() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000948
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +0000949 // Type information helpers.
950 bool HasMonomorphicJSObjectType();
951
952 // TODO(mstarzinger): For now instructions can override this function to
953 // specify statically known types, once HType can convey more information
954 // it should be based on the HType.
955 virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
956
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000957 // Updated the inferred type of this instruction and returns true if
958 // it has changed.
959 bool UpdateInferredType();
960
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000961 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000962
jkummerow@chromium.org28faa982012-04-13 09:58:30 +0000963 // This function must be overridden for instructions which have the
964 // kTrackSideEffectDominators flag set, to track instructions that are
965 // dominating side effects.
966 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
967 UNREACHABLE();
968 }
969
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000970 bool IsDead() const {
971 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
972 }
973
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000974#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000975 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976#endif
977
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000978 // This method is recursive but it is guaranteed to terminate because
979 // RedefinedOperand() always dominates "this".
980 bool IsRelationTrue(NumericRelation relation, HValue* other) {
981 if (this == other) {
982 return NumericRelation::Eq().Implies(relation);
983 }
984
985 bool result = IsRelationTrueInternal(relation, other) ||
986 other->IsRelationTrueInternal(relation.Reversed(), this);
987 if (!result) {
988 HValue* redefined = RedefinedOperand();
989 if (redefined != NULL) {
990 result = redefined->IsRelationTrue(relation, other);
991 }
992 }
993 return result;
994 }
995
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000996 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000997 // This function must be overridden for instructions with flag kUseGVN, to
998 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000999 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00001000 UNREACHABLE();
1001 return false;
1002 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001003
1004 virtual Representation RepresentationFromInputs() {
1005 return representation();
1006 }
1007 Representation RepresentationFromUses();
1008 virtual void UpdateRepresentation(Representation new_rep,
1009 HInferRepresentation* h_infer,
1010 const char* reason);
1011 void AddDependantsToWorklist(HInferRepresentation* h_infer);
1012
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001013 virtual void RepresentationChanged(Representation to) { }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001014
ulan@chromium.org812308e2012-02-29 15:58:45 +00001015 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001016 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001017 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001018 void clear_block() {
1019 ASSERT(block_ != NULL);
1020 block_ = NULL;
1021 }
1022
1023 void set_representation(Representation r) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001024 ASSERT(representation_.IsNone() && !r.IsNone());
1025 representation_ = r;
1026 }
1027
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00001028 // Signature of a function testing if a HValue properly dominates another.
1029 typedef bool (*DominanceTest)(HValue*, HValue*);
1030
1031 // Simple implementation of DominanceTest implemented walking the chain
1032 // of Hinstructions (used in UpdateRedefinedUsesInner).
1033 static bool Dominates(HValue* dominator, HValue* dominated);
1034
1035 // A fast implementation of DominanceTest that works only for the
1036 // "current" instruction in the SetupInformativeDefinitions() phase.
1037 // During that phase we use a flag to mark processed instructions, and by
1038 // checking the flag we can quickly test if an instruction comes before or
1039 // after the "current" one.
1040 static bool TestDominanceUsingProcessedFlag(HValue* dominator,
1041 HValue* dominated);
1042
1043 // If we are redefining an operand, update all its dominated uses (the
1044 // function that checks if a use is dominated is the template argument).
1045 template<DominanceTest TestDominance>
1046 void UpdateRedefinedUsesInner() {
1047 HValue* input = RedefinedOperand();
1048 if (input != NULL) {
1049 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
1050 HValue* use = uses.value();
1051 if (TestDominance(this, use)) {
1052 use->SetOperandAt(uses.index(), this);
1053 }
1054 }
1055 }
1056 }
1057
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001058 // Informative definitions can override this method to state any numeric
1059 // relation they provide on the redefined value.
1060 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
1061 return false;
1062 }
1063
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001064 static GVNFlagSet AllDependsOnFlagSet() {
1065 GVNFlagSet result;
1066 // Create changes mask.
1067#define ADD_FLAG(type) result.Add(kDependsOn##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001068 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1069 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001070#undef ADD_FLAG
1071 return result;
1072 }
1073
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001074 static GVNFlagSet AllChangesFlagSet() {
1075 GVNFlagSet result;
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001076 // Create changes mask.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001077#define ADD_FLAG(type) result.Add(kChanges##type);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001078 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1079 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
fschneider@chromium.org1805e212011-09-05 10:49:12 +00001080#undef ADD_FLAG
1081 return result;
1082 }
1083
ager@chromium.org378b34e2011-01-28 08:04:38 +00001084 // A flag mask to mark an instruction as having arbitrary side effects.
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001085 static GVNFlagSet AllSideEffectsFlagSet() {
1086 GVNFlagSet result = AllChangesFlagSet();
1087 result.Remove(kChangesOsrEntries);
1088 return result;
ager@chromium.org378b34e2011-01-28 08:04:38 +00001089 }
1090
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001091 // A flag mask of all side effects that can make observable changes in
1092 // an executing program (i.e. are not safe to repeat, move or remove);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001093 static GVNFlagSet AllObservableSideEffectsFlagSet() {
1094 GVNFlagSet result = AllChangesFlagSet();
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001095 result.Remove(kChangesNewSpacePromotion);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001096 result.Remove(kChangesElementsKind);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001097 result.Remove(kChangesElementsPointer);
1098 result.Remove(kChangesMaps);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001099 return result;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001100 }
1101
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001102 // Remove the matching use from the use list if present. Returns the
1103 // removed list node or NULL.
1104 HUseListNode* RemoveUse(HValue* value, int index);
1105
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001106 void RegisterUse(int index, HValue* new_value);
1107
1108 HBasicBlock* block_;
1109
1110 // The id of this instruction in the hydrogen graph, assigned when first
1111 // added to the graph. Reflects creation order.
1112 int id_;
1113
1114 Representation representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001115 HType type_;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001116 HUseListNode* use_list_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001117 Range* range_;
1118 int flags_;
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001119 GVNFlagSet gvn_flags_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001120
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001121 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001122 virtual bool IsDeletable() const { return false; }
1123
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001124 DISALLOW_COPY_AND_ASSIGN(HValue);
1125};
1126
1127
1128class HInstruction: public HValue {
1129 public:
1130 HInstruction* next() const { return next_; }
1131 HInstruction* previous() const { return previous_; }
1132
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001133 virtual void PrintTo(StringStream* stream);
1134 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001135
1136 bool IsLinked() const { return block() != NULL; }
1137 void Unlink();
1138 void InsertBefore(HInstruction* next);
1139 void InsertAfter(HInstruction* previous);
1140
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001141 // The position is a write-once variable.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001142 int position() const { return position_; }
1143 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001144 void set_position(int position) {
1145 ASSERT(!has_position());
1146 ASSERT(position != RelocInfo::kNoPosition);
1147 position_ = position;
1148 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001149
ulan@chromium.org812308e2012-02-29 15:58:45 +00001150 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1151
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001152 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1153
1154#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001155 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001156#endif
1157
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001158 virtual bool IsCall() { return false; }
1159
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001160 DECLARE_ABSTRACT_INSTRUCTION(Instruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001161
1162 protected:
1163 HInstruction()
1164 : next_(NULL),
1165 previous_(NULL),
1166 position_(RelocInfo::kNoPosition) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001167 SetGVNFlag(kDependsOnOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001168 }
1169
1170 virtual void DeleteFromGraph() { Unlink(); }
1171
1172 private:
1173 void InitializeAsFirst(HBasicBlock* block) {
1174 ASSERT(!IsLinked());
1175 SetBlock(block);
1176 }
1177
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001178 void PrintMnemonicTo(StringStream* stream);
1179
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001180 HInstruction* next_;
1181 HInstruction* previous_;
1182 int position_;
1183
1184 friend class HBasicBlock;
1185};
1186
1187
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001188template<int V>
1189class HTemplateInstruction : public HInstruction {
1190 public:
1191 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001192 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001193
1194 protected:
1195 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1196
1197 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001198 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001199};
1200
1201
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001202class HControlInstruction: public HInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001204 virtual HBasicBlock* SuccessorAt(int i) = 0;
1205 virtual int SuccessorCount() = 0;
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001206 virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001207
1208 virtual void PrintDataTo(StringStream* stream);
1209
1210 HBasicBlock* FirstSuccessor() {
1211 return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
1212 }
1213 HBasicBlock* SecondSuccessor() {
1214 return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
1215 }
1216
1217 DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
1218};
1219
1220
1221class HSuccessorIterator BASE_EMBEDDED {
1222 public:
1223 explicit HSuccessorIterator(HControlInstruction* instr)
1224 : instr_(instr), current_(0) { }
1225
1226 bool Done() { return current_ >= instr_->SuccessorCount(); }
1227 HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
1228 void Advance() { current_++; }
1229
1230 private:
1231 HControlInstruction* instr_;
1232 int current_;
1233};
1234
1235
1236template<int S, int V>
1237class HTemplateControlInstruction: public HControlInstruction {
1238 public:
1239 int SuccessorCount() { return S; }
1240 HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001241 void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001242
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001243 int OperandCount() { return V; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001244 HValue* OperandAt(int i) const { return inputs_[i]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001245
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001246
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001247 protected:
1248 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
1249
1250 private:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001251 EmbeddedContainer<HBasicBlock*, S> successors_;
1252 EmbeddedContainer<HValue*, V> inputs_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001253};
1254
1255
1256class HBlockEntry: public HTemplateInstruction<0> {
1257 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001258 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001259 return Representation::None();
1260 }
1261
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001262 DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001263};
1264
1265
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001266class HDummyUse: public HTemplateInstruction<1> {
1267 public:
1268 explicit HDummyUse(HValue* value) {
1269 SetOperandAt(0, value);
1270 // Pretend to be a Smi so that the HChange instructions inserted
1271 // before any use generate as little code as possible.
1272 set_representation(Representation::Tagged());
1273 set_type(HType::Smi());
1274 }
1275
1276 HValue* value() { return OperandAt(0); }
1277
1278 virtual Representation RequiredInputRepresentation(int index) {
1279 return Representation::None();
1280 }
1281
1282 virtual void PrintDataTo(StringStream* stream);
1283
1284 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1285};
1286
1287
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001288class HNumericConstraint : public HTemplateInstruction<2> {
1289 public:
1290 static HNumericConstraint* AddToGraph(HValue* constrained_value,
1291 NumericRelation relation,
1292 HValue* related_value,
1293 HInstruction* insertion_point = NULL);
1294
1295 HValue* constrained_value() { return OperandAt(0); }
1296 HValue* related_value() { return OperandAt(1); }
1297 NumericRelation relation() { return relation_; }
1298
1299 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00001300 virtual bool IsPurelyInformativeDefinition() { return true; }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001301
1302 virtual Representation RequiredInputRepresentation(int index) {
1303 return representation();
1304 }
1305
1306 virtual void PrintDataTo(StringStream* stream);
1307
1308 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1309 HValue* other_related_value) {
1310 if (related_value() == other_related_value) {
1311 return relation().Implies(other_relation);
1312 } else {
1313 return false;
1314 }
1315 }
1316
1317 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1318
1319 private:
1320 HNumericConstraint(HValue* constrained_value,
1321 NumericRelation relation,
1322 HValue* related_value)
1323 : relation_(relation) {
1324 SetOperandAt(0, constrained_value);
1325 SetOperandAt(1, related_value);
1326 set_representation(constrained_value->representation());
1327 }
1328
1329 NumericRelation relation_;
1330};
1331
1332
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001333// We insert soft-deoptimize when we hit code with unknown typefeedback,
1334// so that we get a chance of re-optimizing with useful typefeedback.
1335// HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1336class HSoftDeoptimize: public HTemplateInstruction<0> {
1337 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001338 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001339 return Representation::None();
1340 }
1341
1342 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
1343};
1344
1345
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001346class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001347 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001348 HDeoptimize(int environment_length, Zone* zone)
1349 : values_(environment_length, zone) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001350
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001351 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001352 return Representation::None();
1353 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001354
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001355 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001356 virtual HValue* OperandAt(int index) const { return values_[index]; }
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001357 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001358
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001359 virtual int SuccessorCount() { return 0; }
1360 virtual HBasicBlock* SuccessorAt(int i) {
1361 UNREACHABLE();
1362 return NULL;
1363 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001364 virtual void SetSuccessorAt(int i, HBasicBlock* block) {
1365 UNREACHABLE();
1366 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001367
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001368 void AddEnvironmentValue(HValue* value, Zone* zone) {
1369 values_.Add(NULL, zone);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001370 SetOperandAt(values_.length() - 1, value);
1371 }
1372
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001373 DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001375 enum UseEnvironment {
1376 kNoUses,
1377 kUseAll
1378 };
1379
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001380 protected:
1381 virtual void InternalSetOperandAt(int index, HValue* value) {
1382 values_[index] = value;
1383 }
1384
1385 private:
1386 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001387};
1388
1389
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001390class HGoto: public HTemplateControlInstruction<1, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001391 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001392 explicit HGoto(HBasicBlock* target) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001393 SetSuccessorAt(0, target);
1394 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001395
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001396 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001397 return Representation::None();
1398 }
1399
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001400 virtual void PrintDataTo(StringStream* stream);
1401
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001402 DECLARE_CONCRETE_INSTRUCTION(Goto)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403};
1404
1405
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001406class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001407 public:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001408 HUnaryControlInstruction(HValue* value,
1409 HBasicBlock* true_target,
1410 HBasicBlock* false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001411 SetOperandAt(0, value);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001412 SetSuccessorAt(0, true_target);
1413 SetSuccessorAt(1, false_target);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001414 }
1415
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001416 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001418 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001419};
1420
1421
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001422class HBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001423 public:
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001424 HBranch(HValue* value,
1425 HBasicBlock* true_target,
1426 HBasicBlock* false_target,
1427 ToBooleanStub::Types expected_input_types = ToBooleanStub::no_types())
1428 : HUnaryControlInstruction(value, true_target, false_target),
1429 expected_input_types_(expected_input_types) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001430 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001431 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001432 explicit HBranch(HValue* value)
1433 : HUnaryControlInstruction(value, NULL, NULL) { }
1434
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001435
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001436 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001437 return Representation::None();
1438 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001439 virtual Representation observed_input_representation(int index);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001441 ToBooleanStub::Types expected_input_types() const {
1442 return expected_input_types_;
1443 }
1444
ricow@chromium.org4f693d62011-07-04 14:01:31 +00001445 DECLARE_CONCRETE_INSTRUCTION(Branch)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00001446
1447 private:
1448 ToBooleanStub::Types expected_input_types_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001449};
1450
1451
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001452class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001453 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001454 HCompareMap(HValue* value,
1455 Handle<Map> map,
1456 HBasicBlock* true_target,
1457 HBasicBlock* false_target)
1458 : HUnaryControlInstruction(value, true_target, false_target),
1459 map_(map) {
1460 ASSERT(true_target != NULL);
1461 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001462 ASSERT(!map.is_null());
1463 }
1464
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001465 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +00001466
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001467 Handle<Map> map() const { return map_; }
1468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001469 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001470 return Representation::Tagged();
1471 }
1472
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001473 DECLARE_CONCRETE_INSTRUCTION(CompareMap)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001474
1475 private:
1476 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001477};
1478
1479
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001480class HReturn: public HTemplateControlInstruction<0, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001481 public:
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001482 HReturn(HValue* value, HValue* context) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001483 SetOperandAt(0, value);
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001484 SetOperandAt(1, context);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001485 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001486
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001487 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001488 return Representation::Tagged();
1489 }
1490
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001491 virtual void PrintDataTo(StringStream* stream);
1492
1493 HValue* value() { return OperandAt(0); }
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001494 HValue* context() { return OperandAt(1); }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001495
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001496 DECLARE_CONCRETE_INSTRUCTION(Return)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001497};
1498
1499
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001500class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001501 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001502 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001503 return Representation::None();
1504 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001505
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001506 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507};
1508
1509
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001510class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001511 public:
1512 explicit HUnaryOperation(HValue* value) {
1513 SetOperandAt(0, value);
1514 }
1515
ricow@chromium.orgc54d3652011-05-30 09:20:16 +00001516 static HUnaryOperation* cast(HValue* value) {
1517 return reinterpret_cast<HUnaryOperation*>(value);
1518 }
1519
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001520 HValue* value() const { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001521 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001522};
1523
1524
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001525class HThrow: public HTemplateInstruction<2> {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001526 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001527 HThrow(HValue* context, HValue* value) {
1528 SetOperandAt(0, context);
1529 SetOperandAt(1, value);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001530 SetAllSideEffects();
1531 }
1532
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001533 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001534 return Representation::Tagged();
1535 }
1536
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001537 HValue* context() { return OperandAt(0); }
1538 HValue* value() { return OperandAt(1); }
1539
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001540 DECLARE_CONCRETE_INSTRUCTION(Throw)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001541};
1542
1543
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001544class HUseConst: public HUnaryOperation {
1545 public:
1546 explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1547
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001548 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001549 return Representation::None();
1550 }
1551
1552 DECLARE_CONCRETE_INSTRUCTION(UseConst)
1553};
1554
1555
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001556class HForceRepresentation: public HTemplateInstruction<1> {
1557 public:
1558 HForceRepresentation(HValue* value, Representation required_representation) {
1559 SetOperandAt(0, value);
1560 set_representation(required_representation);
1561 }
1562
1563 HValue* value() { return OperandAt(0); }
1564
1565 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1566
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001567 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001568 return representation(); // Same as the output representation.
1569 }
1570
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001571 virtual void PrintDataTo(StringStream* stream);
1572
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001573 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1574};
1575
1576
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001577class HChange: public HUnaryOperation {
1578 public:
1579 HChange(HValue* value,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001580 Representation to,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001581 bool is_truncating,
1582 bool deoptimize_on_undefined)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001583 : HUnaryOperation(value) {
1584 ASSERT(!value->representation().IsNone() && !to.IsNone());
1585 ASSERT(!value->representation().Equals(to));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001586 set_representation(to);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001587 set_type(HType::TaggedNumber());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001588 SetFlag(kUseGVN);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001589 if (deoptimize_on_undefined) SetFlag(kDeoptimizeOnUndefined);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +00001590 if (is_truncating) SetFlag(kTruncatingToInt32);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001591 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001592 }
1593
1594 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001595 virtual HType CalculateInferredType();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001596 virtual HValue* Canonicalize();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001597
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001598 Representation from() const { return value()->representation(); }
1599 Representation to() const { return representation(); }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001600 bool deoptimize_on_undefined() const {
1601 return CheckFlag(kDeoptimizeOnUndefined);
1602 }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001603 bool deoptimize_on_minus_zero() const {
1604 return CheckFlag(kBailoutOnMinusZero);
1605 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001606 virtual Representation RequiredInputRepresentation(int index) {
1607 return from();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001608 }
1609
ulan@chromium.org812308e2012-02-29 15:58:45 +00001610 virtual Range* InferRange(Zone* zone);
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00001611
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001612 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001613
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001614 DECLARE_CONCRETE_INSTRUCTION(Change)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001615
1616 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001617 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001618
1619 private:
1620 virtual bool IsDeletable() const {
1621 return !from().IsTagged() || value()->type().IsSmi();
1622 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001623};
1624
1625
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001626class HClampToUint8: public HUnaryOperation {
1627 public:
1628 explicit HClampToUint8(HValue* value)
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001629 : HUnaryOperation(value) {
1630 set_representation(Representation::Integer32());
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001631 SetFlag(kUseGVN);
1632 }
1633
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001634 virtual Representation RequiredInputRepresentation(int index) {
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001635 return Representation::None();
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001636 }
1637
1638 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1639
1640 protected:
1641 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001642
1643 private:
1644 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +00001645};
1646
1647
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001648enum RemovableSimulate {
1649 REMOVABLE_SIMULATE,
1650 FIXED_SIMULATE
1651};
1652
1653
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001654class HSimulate: public HInstruction {
1655 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001656 HSimulate(BailoutId ast_id,
1657 int pop_count,
1658 Zone* zone,
1659 RemovableSimulate removable)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001660 : ast_id_(ast_id),
1661 pop_count_(pop_count),
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001662 values_(2, zone),
1663 assigned_indexes_(2, zone),
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001664 zone_(zone),
1665 removable_(removable) {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001666 virtual ~HSimulate() {}
1667
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001668 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001669
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001670 bool HasAstId() const { return !ast_id_.IsNone(); }
1671 BailoutId ast_id() const { return ast_id_; }
1672 void set_ast_id(BailoutId id) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001673 ASSERT(!HasAstId());
1674 ast_id_ = id;
1675 }
1676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001677 int pop_count() const { return pop_count_; }
1678 const ZoneList<HValue*>* values() const { return &values_; }
1679 int GetAssignedIndexAt(int index) const {
1680 ASSERT(HasAssignedIndexAt(index));
1681 return assigned_indexes_[index];
1682 }
1683 bool HasAssignedIndexAt(int index) const {
1684 return assigned_indexes_[index] != kNoIndex;
1685 }
1686 void AddAssignedValue(int index, HValue* value) {
1687 AddValue(index, value);
1688 }
1689 void AddPushedValue(HValue* value) {
1690 AddValue(kNoIndex, value);
1691 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001692 virtual int OperandCount() { return values_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001693 virtual HValue* OperandAt(int index) const { return values_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001694
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001695 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001696 return Representation::None();
1697 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001698
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001699 void MergeInto(HSimulate* other);
1700 bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
1701
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001702 DECLARE_CONCRETE_INSTRUCTION(Simulate)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001703
1704#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001705 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001706#endif
1707
1708 protected:
1709 virtual void InternalSetOperandAt(int index, HValue* value) {
1710 values_[index] = value;
1711 }
1712
1713 private:
1714 static const int kNoIndex = -1;
1715 void AddValue(int index, HValue* value) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001716 assigned_indexes_.Add(index, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001717 // Resize the list of pushed values.
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001718 values_.Add(NULL, zone_);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001719 // Set the operand through the base method in HValue to make sure that the
1720 // use lists are correctly updated.
1721 SetOperandAt(values_.length() - 1, value);
1722 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001723 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001724 int pop_count_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001725 ZoneList<HValue*> values_;
1726 ZoneList<int> assigned_indexes_;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00001727 Zone* zone_;
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00001728 RemovableSimulate removable_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001729};
1730
1731
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001732class HStackCheck: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001733 public:
ager@chromium.org04921a82011-06-27 13:21:41 +00001734 enum Type {
1735 kFunctionEntry,
1736 kBackwardsBranch
1737 };
1738
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001739 HStackCheck(HValue* context, Type type) : type_(type) {
1740 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00001741 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001742 }
1743
1744 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001745
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001746 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001747 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001748 }
1749
ager@chromium.org04921a82011-06-27 13:21:41 +00001750 void Eliminate() {
1751 // The stack check eliminator might try to eliminate the same stack
1752 // check instruction multiple times.
1753 if (IsLinked()) {
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00001754 DeleteAndReplaceWith(NULL);
ager@chromium.org04921a82011-06-27 13:21:41 +00001755 }
1756 }
1757
1758 bool is_function_entry() { return type_ == kFunctionEntry; }
1759 bool is_backwards_branch() { return type_ == kBackwardsBranch; }
1760
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001761 DECLARE_CONCRETE_INSTRUCTION(StackCheck)
ager@chromium.org04921a82011-06-27 13:21:41 +00001762
1763 private:
1764 Type type_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001765};
1766
1767
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001768enum InliningKind {
1769 NORMAL_RETURN, // Normal function/method call and return.
1770 DROP_EXTRA_ON_RETURN, // Drop an extra value from the environment on return.
1771 CONSTRUCT_CALL_RETURN, // Either use allocated receiver or return value.
mstarzinger@chromium.orgde886792012-09-11 13:22:37 +00001772 GETTER_CALL_RETURN, // Returning from a getter, need to restore context.
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001773 SETTER_CALL_RETURN // Use the RHS of the assignment as the return value.
1774};
1775
1776
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001777class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001778 public:
danno@chromium.org40cb8782011-05-25 07:58:50 +00001779 HEnterInlined(Handle<JSFunction> closure,
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001780 int arguments_count,
danno@chromium.org40cb8782011-05-25 07:58:50 +00001781 FunctionLiteral* function,
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001782 InliningKind inlining_kind,
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001783 Variable* arguments_var,
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001784 ZoneList<HValue*>* arguments_values,
1785 bool undefined_receiver)
danno@chromium.org40cb8782011-05-25 07:58:50 +00001786 : closure_(closure),
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001787 arguments_count_(arguments_count),
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001788 arguments_pushed_(false),
danno@chromium.org40cb8782011-05-25 07:58:50 +00001789 function_(function),
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001790 inlining_kind_(inlining_kind),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001791 arguments_var_(arguments_var),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001792 arguments_values_(arguments_values),
1793 undefined_receiver_(undefined_receiver) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001794 }
1795
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001796 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001797
1798 Handle<JSFunction> closure() const { return closure_; }
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001799 int arguments_count() const { return arguments_count_; }
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001800 bool arguments_pushed() const { return arguments_pushed_; }
1801 void set_arguments_pushed() { arguments_pushed_ = true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001802 FunctionLiteral* function() const { return function_; }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001803 InliningKind inlining_kind() const { return inlining_kind_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001804 bool undefined_receiver() const { return undefined_receiver_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001805
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001806 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001807 return Representation::None();
1808 }
1809
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001810 Variable* arguments_var() { return arguments_var_; }
1811 ZoneList<HValue*>* arguments_values() { return arguments_values_; }
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001812
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001813 DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001814
1815 private:
1816 Handle<JSFunction> closure_;
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00001817 int arguments_count_;
ulan@chromium.org56c14af2012-09-20 12:51:09 +00001818 bool arguments_pushed_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001819 FunctionLiteral* function_;
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00001820 InliningKind inlining_kind_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00001821 Variable* arguments_var_;
1822 ZoneList<HValue*>* arguments_values_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001823 bool undefined_receiver_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001824};
1825
1826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001827class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001828 public:
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00001829 HLeaveInlined() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001830
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001831 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001832 return Representation::None();
1833 }
1834
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001835 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836};
1837
1838
1839class HPushArgument: public HUnaryOperation {
1840 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001841 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1842 set_representation(Representation::Tagged());
1843 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001844
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001845 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001846 return Representation::Tagged();
1847 }
1848
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001849 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001850
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001851 DECLARE_CONCRETE_INSTRUCTION(PushArgument)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001852};
1853
1854
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001855class HThisFunction: public HTemplateInstruction<0> {
1856 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001857 HThisFunction() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001858 set_representation(Representation::Tagged());
1859 SetFlag(kUseGVN);
1860 }
1861
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001862 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001863 return Representation::None();
1864 }
1865
1866 DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
1867
1868 protected:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001869 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001870
1871 private:
1872 virtual bool IsDeletable() const { return true; }
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001873};
1874
1875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001876class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001877 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001878 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001879 set_representation(Representation::Tagged());
1880 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001881 }
1882
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001883 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001884 return Representation::None();
1885 }
1886
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001887 DECLARE_CONCRETE_INSTRUCTION(Context)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001888
1889 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001890 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001891
1892 private:
1893 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001894};
1895
1896
1897class HOuterContext: public HUnaryOperation {
1898 public:
1899 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1900 set_representation(Representation::Tagged());
1901 SetFlag(kUseGVN);
1902 }
1903
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001904 DECLARE_CONCRETE_INSTRUCTION(OuterContext);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001905
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001906 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001907 return Representation::Tagged();
1908 }
1909
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001910 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001911 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001912
1913 private:
1914 virtual bool IsDeletable() const { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001915};
1916
1917
yangguo@chromium.org56454712012-02-16 15:33:53 +00001918class HDeclareGlobals: public HUnaryOperation {
1919 public:
1920 HDeclareGlobals(HValue* context,
1921 Handle<FixedArray> pairs,
1922 int flags)
1923 : HUnaryOperation(context),
1924 pairs_(pairs),
1925 flags_(flags) {
1926 set_representation(Representation::Tagged());
1927 SetAllSideEffects();
1928 }
1929
1930 HValue* context() { return OperandAt(0); }
1931 Handle<FixedArray> pairs() const { return pairs_; }
1932 int flags() const { return flags_; }
1933
1934 DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
1935
1936 virtual Representation RequiredInputRepresentation(int index) {
1937 return Representation::Tagged();
1938 }
1939 private:
1940 Handle<FixedArray> pairs_;
1941 int flags_;
1942};
1943
1944
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001945class HGlobalObject: public HUnaryOperation {
1946 public:
1947 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1948 set_representation(Representation::Tagged());
1949 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001950 }
1951
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001952 DECLARE_CONCRETE_INSTRUCTION(GlobalObject)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001953
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001954 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001955 return Representation::Tagged();
1956 }
1957
ager@chromium.org378b34e2011-01-28 08:04:38 +00001958 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001959 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001960
1961 private:
1962 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001963};
1964
1965
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001966class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001967 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001968 explicit HGlobalReceiver(HValue* global_object)
1969 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001970 set_representation(Representation::Tagged());
1971 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001972 }
1973
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00001974 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver)
ager@chromium.org378b34e2011-01-28 08:04:38 +00001975
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001976 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001977 return Representation::Tagged();
1978 }
1979
ager@chromium.org378b34e2011-01-28 08:04:38 +00001980 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001981 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00001982
1983 private:
1984 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001985};
1986
1987
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001988template <int V>
1989class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001990 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001991 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001992 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1993 this->set_representation(Representation::Tagged());
1994 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001995 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001996
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001997 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001998
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001999 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002000
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002001 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002002
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002003 private:
2004 int argument_count_;
2005};
2006
2007
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002008class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002009 public:
2010 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002011 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002012 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002013 }
2014
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002015 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002016 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002017 }
2018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002019 virtual void PrintDataTo(StringStream* stream);
2020
2021 HValue* value() { return OperandAt(0); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002022};
2023
2024
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002025class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002026 public:
2027 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002028 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002029 SetOperandAt(0, first);
2030 SetOperandAt(1, second);
2031 }
2032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002033 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002034
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002035 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002036 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002037 }
2038
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002039 HValue* first() { return OperandAt(0); }
2040 HValue* second() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002041};
2042
2043
danno@chromium.org160a7b02011-04-18 15:51:38 +00002044class HInvokeFunction: public HBinaryCall {
2045 public:
2046 HInvokeFunction(HValue* context, HValue* function, int argument_count)
2047 : HBinaryCall(context, function, argument_count) {
2048 }
2049
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002050 HInvokeFunction(HValue* context,
2051 HValue* function,
2052 Handle<JSFunction> known_function,
2053 int argument_count)
2054 : HBinaryCall(context, function, argument_count),
2055 known_function_(known_function) {
2056 }
2057
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002058 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00002059 return Representation::Tagged();
2060 }
2061
2062 HValue* context() { return first(); }
2063 HValue* function() { return second(); }
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002064 Handle<JSFunction> known_function() { return known_function_; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00002065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002066 DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002067
2068 private:
2069 Handle<JSFunction> known_function_;
danno@chromium.org160a7b02011-04-18 15:51:38 +00002070};
2071
2072
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002073class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002074 public:
2075 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002076 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002077
2078 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002079
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002080 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002081 return function_->code() ==
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002082 Isolate::Current()->builtins()->builtin(Builtins::kFunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002083 }
2084
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002085 virtual void PrintDataTo(StringStream* stream);
2086
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002087 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002088 return Representation::None();
2089 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002090
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002091 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002092
2093 private:
2094 Handle<JSFunction> function_;
2095};
2096
2097
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002098class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002099 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002100 HCallKeyed(HValue* context, HValue* key, int argument_count)
2101 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102 }
2103
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002104 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105 return Representation::Tagged();
2106 }
2107
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002108 HValue* context() { return first(); }
2109 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002110
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002111 DECLARE_CONCRETE_INSTRUCTION(CallKeyed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002112};
2113
2114
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002115class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002117 HCallNamed(HValue* context, Handle<String> name, int argument_count)
2118 : HUnaryCall(context, argument_count), name_(name) {
2119 }
2120
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002121 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002122
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002123 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002124 Handle<String> name() const { return name_; }
2125
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002126 DECLARE_CONCRETE_INSTRUCTION(CallNamed)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002127
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002128 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002129 return Representation::Tagged();
2130 }
2131
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002132 private:
2133 Handle<String> name_;
2134};
2135
2136
danno@chromium.orgc612e022011-11-10 11:38:15 +00002137class HCallFunction: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002138 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +00002139 HCallFunction(HValue* context, HValue* function, int argument_count)
2140 : HBinaryCall(context, function, argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002141 }
2142
danno@chromium.orgc612e022011-11-10 11:38:15 +00002143 HValue* context() { return first(); }
2144 HValue* function() { return second(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002145
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002146 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002147 return Representation::Tagged();
2148 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002149
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002150 DECLARE_CONCRETE_INSTRUCTION(CallFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002151};
2152
2153
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002154class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002155 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002156 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
2157 : HUnaryCall(context, argument_count), name_(name) {
2158 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002160 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002162 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002163 Handle<String> name() const { return name_; }
2164
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002165 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002166 return Representation::Tagged();
2167 }
2168
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002169 DECLARE_CONCRETE_INSTRUCTION(CallGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002170
2171 private:
2172 Handle<String> name_;
2173};
2174
2175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002176class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002177 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002178 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002179 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002180
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002181 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002182
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002183 Handle<JSFunction> target() const { return target_; }
2184
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002185 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002186 return Representation::None();
2187 }
2188
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002189 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002190
2191 private:
2192 Handle<JSFunction> target_;
2193};
2194
2195
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002196class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002197 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002198 HCallNew(HValue* context, HValue* constructor, int argument_count)
2199 : HBinaryCall(context, constructor, argument_count) {
2200 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002201
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002202 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002203 return Representation::Tagged();
2204 }
2205
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002206 HValue* context() { return first(); }
2207 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002208
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002209 DECLARE_CONCRETE_INSTRUCTION(CallNew)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002210};
2211
2212
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002213class HCallRuntime: public HCall<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002214 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002215 HCallRuntime(HValue* context,
2216 Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002217 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002218 int argument_count)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002219 : HCall<1>(argument_count), c_function_(c_function), name_(name) {
2220 SetOperandAt(0, context);
2221 }
2222
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002223 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002224
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002225 HValue* context() { return OperandAt(0); }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002226 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002227 Handle<String> name() const { return name_; }
2228
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002229 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002230 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002231 }
2232
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002233 DECLARE_CONCRETE_INSTRUCTION(CallRuntime)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002234
2235 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002236 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002237 Handle<String> name_;
2238};
2239
2240
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002241class HJSArrayLength: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002242 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002243 HJSArrayLength(HValue* value, HValue* typecheck,
2244 HType type = HType::Tagged()) {
2245 set_type(type);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002246 // The length of an array is stored as a tagged value in the array
2247 // object. It is guaranteed to be 32 bit integer, but it can be
2248 // represented as either a smi or heap number.
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002249 SetOperandAt(0, value);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002250 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002251 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002252 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002253 SetGVNFlag(kDependsOnArrayLengths);
2254 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002255 }
2256
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002257 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002258 return Representation::Tagged();
2259 }
2260
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00002261 virtual void PrintDataTo(StringStream* stream);
2262
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002263 HValue* value() { return OperandAt(0); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002264 HValue* typecheck() {
2265 ASSERT(HasTypeCheck());
2266 return OperandAt(1);
2267 }
2268 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002269
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002270 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002271
2272 protected:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002273 virtual bool DataEquals(HValue* other_raw) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002274
2275 private:
2276 virtual bool IsDeletable() const { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002277};
2278
2279
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002280class HFixedArrayBaseLength: public HUnaryOperation {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002281 public:
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002282 explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002283 set_type(HType::Smi());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002284 set_representation(Representation::Tagged());
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002285 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002286 SetGVNFlag(kDependsOnArrayLengths);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002287 }
2288
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002289 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002290 return Representation::Tagged();
2291 }
2292
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00002293 DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002294
2295 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002296 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002297
2298 private:
2299 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002300};
2301
2302
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002303class HMapEnumLength: public HUnaryOperation {
2304 public:
2305 explicit HMapEnumLength(HValue* value) : HUnaryOperation(value) {
2306 set_type(HType::Smi());
2307 set_representation(Representation::Tagged());
2308 SetFlag(kUseGVN);
2309 SetGVNFlag(kDependsOnMaps);
2310 }
2311
2312 virtual Representation RequiredInputRepresentation(int index) {
2313 return Representation::Tagged();
2314 }
2315
2316 DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
2317
2318 protected:
2319 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002320
2321 private:
2322 virtual bool IsDeletable() const { return true; }
yangguo@chromium.org355cfd12012-08-29 15:32:24 +00002323};
2324
2325
whesse@chromium.org7b260152011-06-20 15:33:18 +00002326class HElementsKind: public HUnaryOperation {
2327 public:
2328 explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
2329 set_representation(Representation::Integer32());
2330 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002331 SetGVNFlag(kDependsOnElementsKind);
whesse@chromium.org7b260152011-06-20 15:33:18 +00002332 }
2333
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002334 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00002335 return Representation::Tagged();
2336 }
2337
2338 DECLARE_CONCRETE_INSTRUCTION(ElementsKind)
2339
2340 protected:
2341 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002342
2343 private:
2344 virtual bool IsDeletable() const { return true; }
whesse@chromium.org7b260152011-06-20 15:33:18 +00002345};
2346
2347
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002348class HBitNot: public HUnaryOperation {
2349 public:
2350 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
2351 set_representation(Representation::Integer32());
2352 SetFlag(kUseGVN);
2353 SetFlag(kTruncatingToInt32);
2354 }
2355
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002356 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002357 return Representation::Integer32();
2358 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002359 virtual Representation observed_input_representation(int index) {
2360 return Representation::Integer32();
2361 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002362 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002363
mstarzinger@chromium.org88d326b2012-04-23 12:57:22 +00002364 virtual HValue* Canonicalize();
2365
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002366 DECLARE_CONCRETE_INSTRUCTION(BitNot)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002367
2368 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002369 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002370
2371 private:
2372 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002373};
2374
2375
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002376class HUnaryMathOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002377 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002378 static HInstruction* New(Zone* zone,
2379 HValue* context,
2380 HValue* value,
2381 BuiltinFunctionId op);
2382
2383 HValue* context() { return OperandAt(0); }
2384 HValue* value() { return OperandAt(1); }
2385
2386 virtual void PrintDataTo(StringStream* stream);
2387
2388 virtual HType CalculateInferredType();
2389
2390 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2391
2392 virtual Representation RequiredInputRepresentation(int index) {
2393 if (index == 0) {
2394 return Representation::Tagged();
2395 } else {
2396 switch (op_) {
2397 case kMathFloor:
2398 case kMathRound:
2399 case kMathSqrt:
2400 case kMathPowHalf:
2401 case kMathLog:
2402 case kMathExp:
2403 case kMathSin:
2404 case kMathCos:
2405 case kMathTan:
2406 return Representation::Double();
2407 case kMathAbs:
2408 return representation();
2409 default:
2410 UNREACHABLE();
2411 return Representation::None();
2412 }
2413 }
2414 }
2415
2416 virtual HValue* Canonicalize();
2417
2418 BuiltinFunctionId op() const { return op_; }
2419 const char* OpName() const;
2420
2421 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
2422
2423 protected:
2424 virtual bool DataEquals(HValue* other) {
2425 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
2426 return op_ == b->op();
2427 }
2428
2429 private:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00002430 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op)
2431 : op_(op) {
2432 SetOperandAt(0, context);
2433 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002434 switch (op) {
2435 case kMathFloor:
2436 case kMathRound:
2437 case kMathCeil:
2438 set_representation(Representation::Integer32());
2439 break;
2440 case kMathAbs:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002441 // Not setting representation here: it is None intentionally.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002442 SetFlag(kFlexibleRepresentation);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002443 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002444 break;
2445 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002446 case kMathPowHalf:
2447 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00002448 case kMathSin:
2449 case kMathCos:
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00002450 case kMathTan:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002451 set_representation(Representation::Double());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00002452 SetGVNFlag(kChangesNewSpacePromotion);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002453 break;
danno@chromium.org1f34ad32012-11-26 14:53:56 +00002454 case kMathExp:
2455 set_representation(Representation::Double());
2456 break;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002457 default:
2458 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002459 }
2460 SetFlag(kUseGVN);
2461 }
2462
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002463 virtual bool IsDeletable() const { return true; }
2464
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002465 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002466};
2467
2468
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002469class HLoadElements: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002470 public:
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002471 HLoadElements(HValue* value, HValue* typecheck) {
2472 SetOperandAt(0, value);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002473 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002474 set_representation(Representation::Tagged());
2475 SetFlag(kUseGVN);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002476 SetGVNFlag(kDependsOnElementsPointer);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002477 }
2478
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002479 HValue* value() { return OperandAt(0); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00002480 HValue* typecheck() {
2481 ASSERT(HasTypeCheck());
2482 return OperandAt(1);
2483 }
2484 bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
rossberg@chromium.org89e18f52012-10-22 13:09:53 +00002485
2486 virtual void PrintDataTo(StringStream* stream);
verwaest@chromium.org68c05782012-09-04 09:58:32 +00002487
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002488 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002489 return Representation::Tagged();
2490 }
2491
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002492 DECLARE_CONCRETE_INSTRUCTION(LoadElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002493
2494 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002495 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002496
2497 private:
2498 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002499};
2500
2501
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002502class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002503 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002504 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002505 : HUnaryOperation(value) {
2506 set_representation(Representation::External());
2507 // The result of this instruction is idempotent as long as its inputs don't
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002508 // change. The external array of a specialized array elements object cannot
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002509 // change once set, so it's no necessary to introduce any additional
2510 // dependencies on top of the inputs.
2511 SetFlag(kUseGVN);
2512 }
2513
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002514 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002515 return Representation::Tagged();
2516 }
2517
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002518 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002519
2520 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002521 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002522
2523 private:
2524 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002525};
2526
2527
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002528class HCheckMaps: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002529 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002530 HCheckMaps(HValue* value, Handle<Map> map, Zone* zone,
2531 HValue* typecheck = NULL) {
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002532 SetOperandAt(0, value);
2533 // If callers don't depend on a typecheck, they can pass in NULL. In that
2534 // case we use a copy of the |value| argument as a dummy value.
2535 SetOperandAt(1, typecheck != NULL ? typecheck : value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536 set_representation(Representation::Tagged());
2537 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002538 SetFlag(kTrackSideEffectDominators);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002539 SetGVNFlag(kDependsOnMaps);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002540 SetGVNFlag(kDependsOnElementsKind);
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002541 map_set()->Add(map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002542 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002543 HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002544 SetOperandAt(0, value);
2545 SetOperandAt(1, value);
2546 set_representation(Representation::Tagged());
2547 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002548 SetFlag(kTrackSideEffectDominators);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002549 SetGVNFlag(kDependsOnMaps);
2550 SetGVNFlag(kDependsOnElementsKind);
2551 for (int i = 0; i < maps->length(); i++) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002552 map_set()->Add(maps->at(i), zone);
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00002553 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002554 map_set()->Sort();
2555 }
2556
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002557 static HCheckMaps* NewWithTransitions(HValue* object, Handle<Map> map,
2558 Zone* zone) {
2559 HCheckMaps* check_map = new(zone) HCheckMaps(object, map, zone);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002560 SmallMapList* map_set = check_map->map_set();
2561
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002562 // Since transitioned elements maps of the initial map don't fail the map
2563 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds.
2564 check_map->ClearGVNFlag(kDependsOnElementsKind);
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002565
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002566 ElementsKind kind = map->elements_kind();
2567 bool packed = IsFastPackedElementsKind(kind);
2568 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) {
2569 kind = GetNextMoreGeneralFastElementsKind(kind, packed);
2570 Map* transitioned_map =
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002571 map->LookupElementsTransitionMap(kind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002572 if (transitioned_map) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002573 map_set->Add(Handle<Map>(transitioned_map), zone);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00002574 }
2575 };
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002576 map_set->Sort();
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002577 return check_map;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002578 }
2579
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002580 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 return Representation::Tagged();
2582 }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002583 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002584 virtual void PrintDataTo(StringStream* stream);
2585 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002586
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002587 HValue* value() { return OperandAt(0); }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002588 SmallMapList* map_set() { return &map_set_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002589
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002590 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002591
2592 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002593 virtual bool DataEquals(HValue* other) {
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002594 HCheckMaps* b = HCheckMaps::cast(other);
2595 // Relies on the fact that map_set has been sorted before.
2596 if (map_set()->length() != b->map_set()->length()) return false;
2597 for (int i = 0; i < map_set()->length(); i++) {
2598 if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false;
2599 }
2600 return true;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 }
2602
2603 private:
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00002604 SmallMapList map_set_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002605};
2606
2607
2608class HCheckFunction: public HUnaryOperation {
2609 public:
2610 HCheckFunction(HValue* value, Handle<JSFunction> function)
2611 : HUnaryOperation(value), target_(function) {
2612 set_representation(Representation::Tagged());
2613 SetFlag(kUseGVN);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002614 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002615 }
2616
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002617 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618 return Representation::Tagged();
2619 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002620 virtual void PrintDataTo(StringStream* stream);
2621 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002622
2623#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002624 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002625#endif
2626
2627 Handle<JSFunction> target() const { return target_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002628 bool target_in_new_space() const { return target_in_new_space_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002629
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002630 DECLARE_CONCRETE_INSTRUCTION(CheckFunction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002631
2632 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002633 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002634 HCheckFunction* b = HCheckFunction::cast(other);
2635 return target_.is_identical_to(b->target());
2636 }
2637
2638 private:
2639 Handle<JSFunction> target_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002640 bool target_in_new_space_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641};
2642
2643
2644class HCheckInstanceType: public HUnaryOperation {
2645 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002646 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) {
2647 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002648 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002649 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) {
2650 return new(zone) HCheckInstanceType(value, IS_JS_ARRAY);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002651 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002652 static HCheckInstanceType* NewIsString(HValue* value, Zone* zone) {
2653 return new(zone) HCheckInstanceType(value, IS_STRING);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002654 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002655 static HCheckInstanceType* NewIsSymbol(HValue* value, Zone* zone) {
2656 return new(zone) HCheckInstanceType(value, IS_SYMBOL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002657 }
2658
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002659 virtual void PrintDataTo(StringStream* stream);
2660
2661 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002662 return Representation::Tagged();
2663 }
2664
sgjesse@chromium.org6db88712011-07-11 11:41:22 +00002665 virtual HValue* Canonicalize();
danno@chromium.org160a7b02011-04-18 15:51:38 +00002666
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002667 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
2668 void GetCheckInterval(InstanceType* first, InstanceType* last);
2669 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002670
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002671 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002672
2673 protected:
2674 // TODO(ager): It could be nice to allow the ommision of instance
2675 // type checks if we have already performed an instance type check
2676 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002677 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002678 HCheckInstanceType* b = HCheckInstanceType::cast(other);
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002679 return check_ == b->check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002680 }
2681
2682 private:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002683 enum Check {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002684 IS_SPEC_OBJECT,
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002685 IS_JS_ARRAY,
2686 IS_STRING,
2687 IS_SYMBOL,
2688 LAST_INTERVAL_CHECK = IS_JS_ARRAY
2689 };
2690
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002691 const char* GetCheckName();
2692
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002693 HCheckInstanceType(HValue* value, Check check)
2694 : HUnaryOperation(value), check_(check) {
2695 set_representation(Representation::Tagged());
2696 SetFlag(kUseGVN);
2697 }
2698
2699 const Check check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700};
2701
2702
2703class HCheckNonSmi: public HUnaryOperation {
2704 public:
2705 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
2706 set_representation(Representation::Tagged());
2707 SetFlag(kUseGVN);
2708 }
2709
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002710 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711 return Representation::Tagged();
2712 }
2713
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002714 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715
2716#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002717 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718#endif
2719
danno@chromium.org160a7b02011-04-18 15:51:38 +00002720 virtual HValue* Canonicalize() {
2721 HType value_type = value()->type();
2722 if (!value_type.IsUninitialized() &&
2723 (value_type.IsHeapNumber() ||
2724 value_type.IsString() ||
2725 value_type.IsBoolean() ||
2726 value_type.IsNonPrimitive())) {
2727 return NULL;
2728 }
2729 return this;
2730 }
2731
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002732 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002733
2734 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002735 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002736};
2737
2738
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002739class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740 public:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002741 HCheckPrototypeMaps(Handle<JSObject> prototype,
2742 Handle<JSObject> holder,
2743 Zone* zone) : prototypes_(2, zone), maps_(2, zone) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002744 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00002745 SetGVNFlag(kDependsOnMaps);
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002746 // Keep a list of all objects on the prototype chain up to the holder
2747 // and the expected maps.
2748 while (true) {
2749 prototypes_.Add(prototype, zone);
2750 maps_.Add(Handle<Map>(prototype->map()), zone);
2751 if (prototype.is_identical_to(holder)) break;
2752 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype()));
2753 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002754 }
2755
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002756 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; }
2757
2758 ZoneList<Handle<Map> >* maps() { return &maps_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002759
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002760 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002761
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002762 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002763 return Representation::None();
2764 }
2765
danno@chromium.org81cac2b2012-07-10 11:28:27 +00002766 virtual void PrintDataTo(StringStream* stream);
2767
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002768 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00002769 ASSERT_ALLOCATION_DISABLED;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00002770 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00002771 AllowHandleDereference allow_handle_deref(isolate());
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002772 intptr_t hash = 0;
2773 for (int i = 0; i < prototypes_.length(); i++) {
2774 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]);
2775 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]);
2776 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002777 return hash;
2778 }
2779
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002780 bool CanOmitPrototypeChecks() {
2781 for (int i = 0; i < maps()->length(); i++) {
2782 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false;
2783 }
2784 return true;
2785 }
2786
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002788 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002789 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002790#ifdef DEBUG
2791 if (prototypes_.length() != b->prototypes()->length()) return false;
2792 for (int i = 0; i < prototypes_.length(); i++) {
2793 if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false;
2794 if (!maps_[i].is_identical_to(b->maps()->at(i))) return false;
2795 }
2796 return true;
2797#else
2798 return prototypes_.first().is_identical_to(b->prototypes()->first()) &&
2799 prototypes_.last().is_identical_to(b->prototypes()->last());
2800#endif // DEBUG
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002801 }
2802
2803 private:
mvstanton@chromium.org6bec0092013-01-23 13:46:53 +00002804 ZoneList<Handle<JSObject> > prototypes_;
2805 ZoneList<Handle<Map> > maps_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002806};
2807
2808
2809class HCheckSmi: public HUnaryOperation {
2810 public:
2811 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
2812 set_representation(Representation::Tagged());
2813 SetFlag(kUseGVN);
2814 }
2815
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002816 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002817 return Representation::Tagged();
2818 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002819 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002820
2821#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002822 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002823#endif
2824
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002825 DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
ager@chromium.org378b34e2011-01-28 08:04:38 +00002826
2827 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002828 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002829};
2830
2831
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002832class HCheckSmiOrInt32: public HUnaryOperation {
2833 public:
2834 explicit HCheckSmiOrInt32(HValue* value) : HUnaryOperation(value) {
2835 SetFlag(kFlexibleRepresentation);
2836 SetFlag(kUseGVN);
2837 }
2838
2839 virtual int RedefinedOperandIndex() { return 0; }
2840 virtual Representation RequiredInputRepresentation(int index) {
2841 return representation();
2842 }
2843 virtual void InferRepresentation(HInferRepresentation* h_infer);
2844
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002845 virtual Representation observed_input_representation(int index) {
2846 return Representation::Integer32();
2847 }
2848
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002849 virtual HValue* Canonicalize() {
2850 if (representation().IsTagged() && !type().IsSmi()) {
2851 return this;
2852 } else {
2853 return value();
2854 }
2855 }
2856
2857 DECLARE_CONCRETE_INSTRUCTION(CheckSmiOrInt32)
2858
2859 protected:
2860 virtual bool DataEquals(HValue* other) { return true; }
2861};
2862
2863
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002864class HPhi: public HValue {
2865 public:
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002866 HPhi(int merged_index, Zone* zone)
2867 : inputs_(2, zone),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002868 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002869 phi_id_(-1),
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002870 is_live_(false),
2871 is_convertible_to_integer_(true) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002872 for (int i = 0; i < Representation::kNumRepresentations; i++) {
2873 non_phi_uses_[i] = 0;
2874 indirect_uses_[i] = 0;
2875 }
2876 ASSERT(merged_index >= 0);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002877 SetFlag(kFlexibleRepresentation);
2878 }
2879
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002880 virtual Representation RepresentationFromInputs();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002881
ulan@chromium.org812308e2012-02-29 15:58:45 +00002882 virtual Range* InferRange(Zone* zone);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002883 virtual void InferRepresentation(HInferRepresentation* h_infer);
2884 Representation RepresentationObservedByAllNonPhiUses();
2885 Representation RepresentationFromUseRequirements();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002886 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002887 return representation();
2888 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002889 virtual HType CalculateInferredType();
2890 virtual int OperandCount() { return inputs_.length(); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00002891 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002892 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002893 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002894 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002895
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002896 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897
2898 int merged_index() const { return merged_index_; }
2899
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00002900 virtual void AddInformativeDefinitions();
2901
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002902 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903
2904#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002905 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002906#endif
2907
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002908 void InitRealUses(int id);
2909 void AddNonPhiUsesFrom(HPhi* other);
2910 void AddIndirectUsesTo(int* use_count);
2911
2912 int tagged_non_phi_uses() const {
2913 return non_phi_uses_[Representation::kTagged];
2914 }
2915 int int32_non_phi_uses() const {
2916 return non_phi_uses_[Representation::kInteger32];
2917 }
2918 int double_non_phi_uses() const {
2919 return non_phi_uses_[Representation::kDouble];
2920 }
2921 int tagged_indirect_uses() const {
2922 return indirect_uses_[Representation::kTagged];
2923 }
2924 int int32_indirect_uses() const {
2925 return indirect_uses_[Representation::kInteger32];
2926 }
2927 int double_indirect_uses() const {
2928 return indirect_uses_[Representation::kDouble];
2929 }
2930 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002931 bool is_live() { return is_live_; }
2932 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002933
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00002934 static HPhi* cast(HValue* value) {
2935 ASSERT(value->IsPhi());
2936 return reinterpret_cast<HPhi*>(value);
2937 }
2938 virtual Opcode opcode() const { return HValue::kPhi; }
2939
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002940 virtual bool IsConvertibleToInteger() const {
2941 return is_convertible_to_integer_;
2942 }
2943
2944 void set_is_convertible_to_integer(bool b) {
2945 is_convertible_to_integer_ = b;
2946 }
2947
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002948 bool AllOperandsConvertibleToInteger() {
2949 for (int i = 0; i < OperandCount(); ++i) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002950 if (!OperandAt(i)->IsConvertibleToInteger()) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00002951 if (FLAG_trace_representation) {
2952 HValue* input = OperandAt(i);
2953 PrintF("#%d %s: Input #%d %s at %d is NCTI\n",
2954 id(), Mnemonic(), input->id(), input->Mnemonic(), i);
2955 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00002956 return false;
2957 }
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002958 }
2959 return true;
2960 }
2961
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002962 protected:
2963 virtual void DeleteFromGraph();
2964 virtual void InternalSetOperandAt(int index, HValue* value) {
2965 inputs_[index] = value;
2966 }
2967
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002968 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other);
2969
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002970 private:
2971 ZoneList<HValue*> inputs_;
2972 int merged_index_;
2973
2974 int non_phi_uses_[Representation::kNumRepresentations];
2975 int indirect_uses_[Representation::kNumRepresentations];
2976 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002977 bool is_live_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00002978 bool is_convertible_to_integer_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979};
2980
2981
ulan@chromium.org2e04b582013-02-21 14:06:02 +00002982class HInductionVariableAnnotation : public HUnaryOperation {
2983 public:
2984 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
2985 NumericRelation relation,
2986 int operand_index);
2987
2988 NumericRelation relation() { return relation_; }
2989 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
2990
2991 virtual int RedefinedOperandIndex() { return 0; }
2992 virtual bool IsPurelyInformativeDefinition() { return true; }
2993 virtual Representation RequiredInputRepresentation(int index) {
2994 return representation();
2995 }
2996
2997 virtual void PrintDataTo(StringStream* stream);
2998
2999 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3000 HValue* other_related_value) {
3001 if (induction_base() == other_related_value) {
3002 return relation().Implies(other_relation);
3003 } else {
3004 return false;
3005 }
3006 }
3007
3008 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3009
3010 private:
3011 HInductionVariableAnnotation(HPhi* phi,
3012 NumericRelation relation,
3013 int operand_index)
3014 : HUnaryOperation(phi),
3015 phi_(phi), relation_(relation), operand_index_(operand_index) {
3016 set_representation(phi->representation());
3017 }
3018
3019 // We need to store the phi both here and in the instruction operand because
3020 // the operand can change if a new idef of the phi is added between the phi
3021 // and this instruction (inserting an idef updates every use).
3022 HPhi* phi_;
3023 NumericRelation relation_;
3024 int operand_index_;
3025};
3026
3027
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003028class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003029 public:
3030 HArgumentsObject() {
3031 set_representation(Representation::Tagged());
3032 SetFlag(kIsArguments);
3033 }
3034
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003035 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003036 return Representation::None();
3037 }
3038
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003039 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003040
3041 private:
3042 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043};
3044
3045
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003046class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003047 public:
3048 HConstant(Handle<Object> handle, Representation r);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003049 HConstant(int32_t value, Representation r);
3050 HConstant(double value, Representation r);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003051
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003052 Handle<Object> handle() {
3053 if (handle_.is_null()) {
3054 handle_ = FACTORY->NewNumber(double_value_, TENURED);
3055 }
3056 ASSERT(has_int32_value_ || !handle_->IsSmi());
3057 return handle_;
3058 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003059
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003060 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003061
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003062 bool ImmortalImmovable() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003063 if (has_int32_value_) {
3064 return false;
3065 }
3066 if (has_double_value_) {
3067 if (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3068 isnan(double_value_)) {
3069 return true;
3070 }
3071 return false;
3072 }
3073
3074 ASSERT(!handle_.is_null());
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003075 Heap* heap = isolate()->heap();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003076 // We should have handled minus_zero_value and nan_value in the
3077 // has_double_value_ clause above.
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003078 // Dereferencing is safe to compare against singletons.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003079 AllowHandleDereference allow_handle_deref(isolate());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003080 ASSERT(*handle_ != heap->minus_zero_value());
3081 ASSERT(*handle_ != heap->nan_value());
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003082 return *handle_ == heap->undefined_value() ||
3083 *handle_ == heap->null_value() ||
3084 *handle_ == heap->true_value() ||
3085 *handle_ == heap->false_value() ||
3086 *handle_ == heap->the_hole_value() ||
3087 *handle_ == heap->empty_string();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003088 }
3089
3090 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003091 return Representation::None();
3092 }
3093
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003094 virtual bool IsConvertibleToInteger() const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003095 return has_int32_value_;
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +00003096 }
3097
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003098 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003099 virtual void PrintDataTo(StringStream* stream);
3100 virtual HType CalculateInferredType();
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003101 bool IsInteger() { return handle()->IsSmi(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003102 HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
3103 HConstant* CopyToTruncatedInt32(Zone* zone) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003104 bool HasInteger32Value() const { return has_int32_value_; }
3105 int32_t Integer32Value() const {
3106 ASSERT(HasInteger32Value());
3107 return int32_value_;
3108 }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003109 bool HasSmiValue() const {
3110 return HasInteger32Value() && Smi::IsValid(Integer32Value());
3111 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003112 bool HasDoubleValue() const { return has_double_value_; }
3113 double DoubleValue() const {
3114 ASSERT(HasDoubleValue());
3115 return double_value_;
3116 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003117 bool HasNumberValue() const { return has_double_value_; }
erikcorry0ad885c2011-11-21 13:51:57 +00003118 int32_t NumberValueAsInteger32() const {
3119 ASSERT(HasNumberValue());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003120 // Irrespective of whether a numeric HConstant can be safely
3121 // represented as an int32, we store the (in some cases lossy)
3122 // representation of the number in int32_value_.
3123 return int32_value_;
erikcorry0ad885c2011-11-21 13:51:57 +00003124 }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003125 bool HasStringValue() const {
3126 if (has_double_value_ || has_int32_value_) return false;
3127 ASSERT(!handle_.is_null());
3128 return handle_->IsString();
3129 }
3130 Handle<String> StringValue() const {
3131 ASSERT(HasStringValue());
3132 return Handle<String>::cast(handle_);
3133 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003134
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003135 bool ToBoolean();
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003136
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00003137 bool IsUint32() {
3138 return HasInteger32Value() && (Integer32Value() >= 0);
3139 }
3140
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003141 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003142 ASSERT_ALLOCATION_DISABLED;
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003143 intptr_t hash;
3144
3145 if (has_int32_value_) {
3146 hash = static_cast<intptr_t>(int32_value_);
3147 } else if (has_double_value_) {
3148 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3149 } else {
3150 ASSERT(!handle_.is_null());
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003151 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00003152 AllowHandleDereference allow_handle_deref(isolate());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003153 hash = reinterpret_cast<intptr_t>(*handle_);
3154 }
3155
3156 return hash;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157 }
3158
3159#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00003160 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003161#endif
3162
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003163 DECLARE_CONCRETE_INSTRUCTION(Constant)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164
3165 protected:
ulan@chromium.org812308e2012-02-29 15:58:45 +00003166 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003167
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003168 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003169 HConstant* other_constant = HConstant::cast(other);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003170 if (has_int32_value_) {
3171 return other_constant->has_int32_value_ &&
3172 int32_value_ == other_constant->int32_value_;
3173 } else if (has_double_value_) {
3174 return other_constant->has_double_value_ &&
3175 BitCast<int64_t>(double_value_) ==
3176 BitCast<int64_t>(other_constant->double_value_);
3177 } else {
3178 ASSERT(!handle_.is_null());
3179 return !other_constant->handle_.is_null() &&
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003180 handle_.is_identical_to(other_constant->handle_);
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003181 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003182 }
3183
3184 private:
hpayer@chromium.org8432c912013-02-28 15:55:26 +00003185 void Initialize(Representation r);
3186
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003187 virtual bool IsDeletable() const { return true; }
3188
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003189 // If this is a numerical constant, handle_ either points to to the
3190 // HeapObject the constant originated from or is null. If the
3191 // constant is non-numeric, handle_ always points to a valid
3192 // constant HeapObject.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003193 Handle<Object> handle_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194
rossberg@chromium.org657d53b2012-07-12 11:06:03 +00003195 // We store the HConstant in the most specific form safely possible.
3196 // The two flags, has_int32_value_ and has_double_value_ tell us if
3197 // int32_value_ and double_value_ hold valid, safe representations
3198 // of the constant. has_int32_value_ implies has_double_value_ but
3199 // not the converse.
danno@chromium.org160a7b02011-04-18 15:51:38 +00003200 bool has_int32_value_ : 1;
3201 bool has_double_value_ : 1;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003202 int32_t int32_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 double double_value_;
3204};
3205
3206
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003207class HBinaryOperation: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003208 public:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003209 HBinaryOperation(HValue* context, HValue* left, HValue* right)
3210 : observed_output_representation_(Representation::None()) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003211 ASSERT(left != NULL && right != NULL);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003212 SetOperandAt(0, context);
3213 SetOperandAt(1, left);
3214 SetOperandAt(2, right);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003215 observed_input_representation_[0] = Representation::None();
3216 observed_input_representation_[1] = Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003217 }
3218
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003219 HValue* context() { return OperandAt(0); }
3220 HValue* left() { return OperandAt(1); }
3221 HValue* right() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003222
3223 // TODO(kasperl): Move these helpers to the IA-32 Lithium
3224 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003225 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003226 if (IsCommutative() && left()->IsConstant()) return right();
3227 return left();
3228 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003229
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003230 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003231 if (IsCommutative() && left()->IsConstant()) return left();
3232 return right();
3233 }
3234
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003235 void set_observed_input_representation(Representation left,
3236 Representation right) {
3237 observed_input_representation_[0] = left;
3238 observed_input_representation_[1] = right;
3239 }
3240
3241 virtual void initialize_output_representation(Representation observed) {
3242 observed_output_representation_ = observed;
3243 }
3244
3245 virtual Representation observed_input_representation(int index) {
3246 if (index == 0) return Representation::Tagged();
3247 return observed_input_representation_[index - 1];
3248 }
3249
3250 virtual void InferRepresentation(HInferRepresentation* h_infer);
3251 virtual Representation RepresentationFromInputs();
3252 virtual void AssumeRepresentation(Representation r);
3253
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003254 virtual bool IsCommutative() const { return false; }
3255
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003256 virtual void PrintDataTo(StringStream* stream);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +00003257
3258 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003259
3260 private:
3261 Representation observed_input_representation_[2];
3262 Representation observed_output_representation_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263};
3264
3265
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003266class HWrapReceiver: public HTemplateInstruction<2> {
3267 public:
3268 HWrapReceiver(HValue* receiver, HValue* function) {
3269 set_representation(Representation::Tagged());
3270 SetOperandAt(0, receiver);
3271 SetOperandAt(1, function);
3272 }
3273
3274 virtual Representation RequiredInputRepresentation(int index) {
3275 return Representation::Tagged();
3276 }
3277
3278 HValue* receiver() { return OperandAt(0); }
3279 HValue* function() { return OperandAt(1); }
3280
3281 virtual HValue* Canonicalize();
3282
yangguo@chromium.org39110192013-01-16 09:55:08 +00003283 virtual void PrintDataTo(StringStream* stream);
3284
yangguo@chromium.org154ff992012-03-13 08:09:54 +00003285 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
3286};
3287
3288
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003289class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003290 public:
3291 HApplyArguments(HValue* function,
3292 HValue* receiver,
3293 HValue* length,
3294 HValue* elements) {
3295 set_representation(Representation::Tagged());
3296 SetOperandAt(0, function);
3297 SetOperandAt(1, receiver);
3298 SetOperandAt(2, length);
3299 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003300 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301 }
3302
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003303 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003304 // The length is untagged, all other inputs are tagged.
3305 return (index == 2)
3306 ? Representation::Integer32()
3307 : Representation::Tagged();
3308 }
3309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003310 HValue* function() { return OperandAt(0); }
3311 HValue* receiver() { return OperandAt(1); }
3312 HValue* length() { return OperandAt(2); }
3313 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003314
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003315 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003316};
3317
3318
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003319class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003320 public:
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003321 explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003322 // The value produced by this instruction is a pointer into the stack
3323 // that looks as if it was a smi because of alignment.
3324 set_representation(Representation::Tagged());
3325 SetFlag(kUseGVN);
3326 }
3327
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003328 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003329
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003330 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003331 return Representation::None();
3332 }
3333
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003334 bool from_inlined() const { return from_inlined_; }
3335
ager@chromium.org378b34e2011-01-28 08:04:38 +00003336 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003337 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003338
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003339 private:
3340 virtual bool IsDeletable() const { return true; }
3341
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00003342 bool from_inlined_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003343};
3344
3345
3346class HArgumentsLength: public HUnaryOperation {
3347 public:
3348 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
3349 set_representation(Representation::Integer32());
3350 SetFlag(kUseGVN);
3351 }
3352
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003353 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003354 return Representation::Tagged();
3355 }
3356
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003357 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003358
3359 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003360 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003361
3362 private:
3363 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003364};
3365
3366
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003367class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003368 public:
3369 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
3370 set_representation(Representation::Tagged());
3371 SetFlag(kUseGVN);
3372 SetOperandAt(0, arguments);
3373 SetOperandAt(1, length);
3374 SetOperandAt(2, index);
3375 }
3376
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003377 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003378
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003379 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003380 // The arguments elements is considered tagged.
3381 return index == 0
3382 ? Representation::Tagged()
3383 : Representation::Integer32();
3384 }
3385
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003386 HValue* arguments() { return OperandAt(0); }
3387 HValue* length() { return OperandAt(1); }
3388 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003390 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003391
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003392 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003393};
3394
3395
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003396enum BoundsCheckKeyMode {
3397 DONT_ALLOW_SMI_KEY,
3398 ALLOW_SMI_KEY
3399};
3400
3401
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003402class HBoundsCheck: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403 public:
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003404 // Normally HBoundsCheck should be created using the
3405 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3406 // a HCheckSmiOrInt32 check.
3407 // However when building stubs, where we know that the arguments are Int32,
3408 // it makes sense to invoke this constructor directly.
3409 HBoundsCheck(HValue* index,
3410 HValue* length,
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003411 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3412 Representation r = Representation::None())
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003413 : key_mode_(key_mode), skip_check_(false) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003414 SetOperandAt(0, index);
3415 SetOperandAt(1, length);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003416 if (r.IsNone()) {
3417 // In the normal compilation pipeline the representation is flexible
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003418 // (see InferRepresentation).
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003419 SetFlag(kFlexibleRepresentation);
3420 } else {
3421 // When compiling stubs we want to set the representation explicitly
3422 // so the compilation pipeline can skip the HInferRepresentation phase.
3423 set_representation(r);
3424 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003425 SetFlag(kUseGVN);
3426 }
3427
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003428 bool skip_check() { return skip_check_; }
3429 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3430
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003431 virtual Representation RequiredInputRepresentation(int arg_index) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003432 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003433 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003434 virtual Representation observed_input_representation(int index) {
3435 return Representation::Integer32();
3436 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003437
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003438 virtual bool IsRelationTrueInternal(NumericRelation relation,
3439 HValue* related_value);
3440
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003441 virtual void PrintDataTo(StringStream* stream);
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003442 virtual void InferRepresentation(HInferRepresentation* h_infer);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00003443
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003444 HValue* index() { return OperandAt(0); }
3445 HValue* length() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003446
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003447 virtual int RedefinedOperandIndex() { return 0; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003448 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003449 virtual void AddInformativeDefinitions();
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00003450
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003451 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003452
3453 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003454 virtual bool DataEquals(HValue* other) { return true; }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00003455 BoundsCheckKeyMode key_mode_;
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003456 bool skip_check_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003457};
3458
3459
3460class HBitwiseBinaryOperation: public HBinaryOperation {
3461 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003462 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3463 : HBinaryOperation(context, left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003464 SetFlag(kFlexibleRepresentation);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003465 SetFlag(kTruncatingToInt32);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003466 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003467 }
3468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003469 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003470 return index == 0
3471 ? Representation::Tagged()
3472 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003473 }
3474
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003475 virtual void RepresentationChanged(Representation to) {
3476 if (!to.IsTagged()) {
3477 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003478 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003479 SetFlag(kUseGVN);
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003480 } else {
3481 SetAllSideEffects();
3482 ClearFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003483 }
3484 }
3485
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003486 virtual void UpdateRepresentation(Representation new_rep,
3487 HInferRepresentation* h_infer,
3488 const char* reason) {
3489 // We only generate either int32 or generic tagged bitwise operations.
3490 if (new_rep.IsDouble()) new_rep = Representation::Integer32();
3491 HValue::UpdateRepresentation(new_rep, h_infer, reason);
3492 }
3493
3494 virtual void initialize_output_representation(Representation observed) {
3495 if (observed.IsDouble()) observed = Representation::Integer32();
3496 HBinaryOperation::initialize_output_representation(observed);
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003500
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003501 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00003502
3503 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003504 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003505};
3506
3507
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003508class HMathFloorOfDiv: public HBinaryOperation {
3509 public:
3510 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
3511 : HBinaryOperation(context, left, right) {
3512 set_representation(Representation::Integer32());
3513 SetFlag(kUseGVN);
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003514 SetFlag(kCanOverflow);
yangguo@chromium.org003650e2013-01-24 16:31:08 +00003515 if (!right->IsConstant()) {
3516 SetFlag(kCanBeDivByZero);
3517 }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003518 }
3519
yangguo@chromium.orgd2899aa2012-06-21 11:16:20 +00003520 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3521
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003522 virtual Representation RequiredInputRepresentation(int index) {
3523 return Representation::Integer32();
3524 }
3525
3526 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
3527
3528 protected:
3529 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003530
3531 private:
3532 virtual bool IsDeletable() const { return true; }
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00003533};
3534
3535
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003536class HArithmeticBinaryOperation: public HBinaryOperation {
3537 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003538 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right)
3539 : HBinaryOperation(context, left, right) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003540 SetAllSideEffects();
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003541 SetFlag(kFlexibleRepresentation);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003542 }
3543
3544 virtual void RepresentationChanged(Representation to) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003545 if (to.IsTagged()) {
3546 SetAllSideEffects();
3547 ClearFlag(kUseGVN);
3548 } else {
ager@chromium.org378b34e2011-01-28 08:04:38 +00003549 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003550 SetFlag(kUseGVN);
3551 }
3552 }
3553
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003554 virtual HType CalculateInferredType();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003555 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003556 return index == 0
3557 ? Representation::Tagged()
3558 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003559 }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003560
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003561 private:
3562 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003563};
3564
3565
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003566class HCompareGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003567 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003568 HCompareGeneric(HValue* context,
3569 HValue* left,
3570 HValue* right,
3571 Token::Value token)
3572 : HBinaryOperation(context, left, right), token_(token) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003573 ASSERT(Token::IsCompareOp(token));
3574 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003575 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003576 }
3577
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003578 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003579 return index == 0
3580 ? Representation::Tagged()
3581 : representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003582 }
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003583
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003584 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003585 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003586
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003587 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003588
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003589 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
3590
3591 private:
3592 Token::Value token_;
3593};
3594
3595
3596class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
3597 public:
3598 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
3599 : token_(token) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003600 SetFlag(kFlexibleRepresentation);
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003601 ASSERT(Token::IsCompareOp(token));
3602 SetOperandAt(0, left);
3603 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003604 }
3605
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003606 HValue* left() { return OperandAt(0); }
3607 HValue* right() { return OperandAt(1); }
3608 Token::Value token() const { return token_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003609
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003610 void set_observed_input_representation(Representation left,
3611 Representation right) {
3612 observed_input_representation_[0] = left;
3613 observed_input_representation_[1] = right;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614 }
3615
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003616 virtual void InferRepresentation(HInferRepresentation* h_infer);
3617
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003618 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003619 return representation();
3620 }
3621 virtual Representation observed_input_representation(int index) {
3622 return observed_input_representation_[index];
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003623 }
3624 virtual void PrintDataTo(StringStream* stream);
3625
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00003626 virtual void AddInformativeDefinitions();
3627
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003628 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
3629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630 private:
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003631 Representation observed_input_representation_[2];
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632 Token::Value token_;
3633};
3634
3635
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003636class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003637 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003638 HCompareObjectEqAndBranch(HValue* left, HValue* right) {
3639 SetOperandAt(0, left);
3640 SetOperandAt(1, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003641 }
3642
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003643 HValue* left() { return OperandAt(0); }
3644 HValue* right() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003645
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003646 virtual void PrintDataTo(StringStream* stream);
3647
3648 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003649 return Representation::Tagged();
3650 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003651
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003652 DECLARE_CONCRETE_INSTRUCTION(CompareObjectEqAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003653};
3654
3655
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003656class HCompareConstantEqAndBranch: public HUnaryControlInstruction {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003657 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003658 HCompareConstantEqAndBranch(HValue* left, int right, Token::Value op)
3659 : HUnaryControlInstruction(left, NULL, NULL), op_(op), right_(right) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003660 ASSERT(op == Token::EQ_STRICT);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003661 }
3662
3663 Token::Value op() const { return op_; }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003664 HValue* left() { return value(); }
whesse@chromium.org7b260152011-06-20 15:33:18 +00003665 int right() const { return right_; }
3666
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003667 virtual Representation RequiredInputRepresentation(int index) {
whesse@chromium.org7b260152011-06-20 15:33:18 +00003668 return Representation::Integer32();
3669 }
3670
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003671 DECLARE_CONCRETE_INSTRUCTION(CompareConstantEqAndBranch);
whesse@chromium.org7b260152011-06-20 15:33:18 +00003672
3673 private:
3674 const Token::Value op_;
3675 const int right_;
3676};
3677
3678
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003679class HIsNilAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003681 HIsNilAndBranch(HValue* value, EqualityKind kind, NilValue nil)
3682 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003683
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003684 EqualityKind kind() const { return kind_; }
3685 NilValue nil() const { return nil_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003686
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003687 virtual void PrintDataTo(StringStream* stream);
3688
3689 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690 return Representation::Tagged();
3691 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003692 virtual Representation observed_input_representation(int index) {
3693 return Representation::Tagged();
3694 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003696 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch)
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003697
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003698 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003699 EqualityKind kind_;
3700 NilValue nil_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003701};
3702
3703
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003704class HIsObjectAndBranch: public HUnaryControlInstruction {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003705 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003706 explicit HIsObjectAndBranch(HValue* value)
3707 : HUnaryControlInstruction(value, NULL, NULL) { }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003708
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003709 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003710 return Representation::Tagged();
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003711 }
3712
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003713 DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
3714};
3715
erikcorry0ad885c2011-11-21 13:51:57 +00003716class HIsStringAndBranch: public HUnaryControlInstruction {
3717 public:
3718 explicit HIsStringAndBranch(HValue* value)
3719 : HUnaryControlInstruction(value, NULL, NULL) { }
3720
3721 virtual Representation RequiredInputRepresentation(int index) {
3722 return Representation::Tagged();
3723 }
3724
3725 DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
3726};
3727
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003728
3729class HIsSmiAndBranch: public HUnaryControlInstruction {
3730 public:
3731 explicit HIsSmiAndBranch(HValue* value)
3732 : HUnaryControlInstruction(value, NULL, NULL) { }
3733
3734 DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
3735
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003736 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003737 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003738 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003739
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003740 protected:
3741 virtual bool DataEquals(HValue* other) { return true; }
3742};
3743
3744
3745class HIsUndetectableAndBranch: public HUnaryControlInstruction {
3746 public:
3747 explicit HIsUndetectableAndBranch(HValue* value)
3748 : HUnaryControlInstruction(value, NULL, NULL) { }
3749
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003750 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003751 return Representation::Tagged();
3752 }
3753
3754 DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
3755};
3756
3757
erikcorry0ad885c2011-11-21 13:51:57 +00003758class HStringCompareAndBranch: public HTemplateControlInstruction<2, 3> {
3759 public:
3760 HStringCompareAndBranch(HValue* context,
3761 HValue* left,
3762 HValue* right,
3763 Token::Value token)
3764 : token_(token) {
3765 ASSERT(Token::IsCompareOp(token));
3766 SetOperandAt(0, context);
3767 SetOperandAt(1, left);
3768 SetOperandAt(2, right);
3769 set_representation(Representation::Tagged());
3770 }
3771
3772 HValue* context() { return OperandAt(0); }
3773 HValue* left() { return OperandAt(1); }
3774 HValue* right() { return OperandAt(2); }
3775 Token::Value token() const { return token_; }
3776
3777 virtual void PrintDataTo(StringStream* stream);
3778
3779 virtual Representation RequiredInputRepresentation(int index) {
3780 return Representation::Tagged();
3781 }
3782
3783 Representation GetInputRepresentation() const {
3784 return Representation::Tagged();
3785 }
3786
3787 DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch)
3788
3789 private:
3790 Token::Value token_;
3791};
3792
3793
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003794class HIsConstructCallAndBranch: public HTemplateControlInstruction<2, 0> {
3795 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003796 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003797 return Representation::None();
3798 }
3799
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003800 DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00003801};
3802
3803
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003804class HHasInstanceTypeAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003805 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003806 HHasInstanceTypeAndBranch(HValue* value, InstanceType type)
3807 : HUnaryControlInstruction(value, NULL, NULL), from_(type), to_(type) { }
3808 HHasInstanceTypeAndBranch(HValue* value, InstanceType from, InstanceType to)
3809 : HUnaryControlInstruction(value, NULL, NULL), from_(from), to_(to) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003810 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
3811 }
3812
3813 InstanceType from() { return from_; }
3814 InstanceType to() { return to_; }
3815
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003816 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003817
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003818 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003819 return Representation::Tagged();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003820 }
3821
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003822 DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
3823
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824 private:
3825 InstanceType from_;
3826 InstanceType to_; // Inclusive range, not all combinations work.
3827};
3828
3829
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003830class HHasCachedArrayIndexAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003831 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003832 explicit HHasCachedArrayIndexAndBranch(HValue* value)
3833 : HUnaryControlInstruction(value, NULL, NULL) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003834
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003835 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003836 return Representation::Tagged();
3837 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003838
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003839 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003840};
3841
3842
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003843class HGetCachedArrayIndex: public HUnaryOperation {
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003844 public:
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003845 explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
3846 set_representation(Representation::Tagged());
3847 SetFlag(kUseGVN);
3848 }
3849
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003850 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org3cf47312011-06-29 13:20:01 +00003851 return Representation::Tagged();
3852 }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003853
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003854 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003855
3856 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003857 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003858
3859 private:
3860 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00003861};
3862
3863
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003864class HClassOfTestAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003865 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003866 HClassOfTestAndBranch(HValue* value, Handle<String> class_name)
3867 : HUnaryControlInstruction(value, NULL, NULL),
3868 class_name_(class_name) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003869
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003870 DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
3871
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003872 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003873 return Representation::Tagged();
3874 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003875
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003876 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003877
3878 Handle<String> class_name() const { return class_name_; }
3879
3880 private:
3881 Handle<String> class_name_;
3882};
3883
3884
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003885class HTypeofIsAndBranch: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003886 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003887 HTypeofIsAndBranch(HValue* value, Handle<String> type_literal)
3888 : HUnaryControlInstruction(value, NULL, NULL),
3889 type_literal_(type_literal) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003890
3891 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003892 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003893
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003894 DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003895
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003896 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org4f693d62011-07-04 14:01:31 +00003897 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003898 }
3899
3900 private:
3901 Handle<String> type_literal_;
3902};
3903
3904
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003905class HInstanceOf: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003906 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003907 HInstanceOf(HValue* context, HValue* left, HValue* right)
3908 : HBinaryOperation(context, left, right) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003909 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003910 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003911 }
3912
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003913 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003914 return Representation::Tagged();
3915 }
3916
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003917 virtual HType CalculateInferredType();
3918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003919 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003920
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003921 DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003922};
3923
3924
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003925class HInstanceOfKnownGlobal: public HTemplateInstruction<2> {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003926 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003927 HInstanceOfKnownGlobal(HValue* context,
3928 HValue* left,
3929 Handle<JSFunction> right)
3930 : function_(right) {
3931 SetOperandAt(0, context);
3932 SetOperandAt(1, left);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003933 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003934 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003935 }
3936
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003937 HValue* context() { return OperandAt(0); }
3938 HValue* left() { return OperandAt(1); }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003939 Handle<JSFunction> function() { return function_; }
3940
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003941 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003942 return Representation::Tagged();
3943 }
3944
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003945 virtual HType CalculateInferredType();
3946
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003947 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal)
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00003948
3949 private:
3950 Handle<JSFunction> function_;
3951};
3952
3953
mstarzinger@chromium.org71fc3462013-02-27 09:34:27 +00003954// TODO(mstarzinger): This instruction should be modeled as a load of the map
3955// field followed by a load of the instance size field once HLoadNamedField is
3956// flexible enough to accommodate byte-field loads.
3957class HInstanceSize: public HTemplateInstruction<1> {
3958 public:
3959 explicit HInstanceSize(HValue* object) {
3960 SetOperandAt(0, object);
3961 set_representation(Representation::Integer32());
3962 }
3963
3964 HValue* object() { return OperandAt(0); }
3965
3966 virtual Representation RequiredInputRepresentation(int index) {
3967 return Representation::Tagged();
3968 }
3969
3970 DECLARE_CONCRETE_INSTRUCTION(InstanceSize)
3971};
3972
3973
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003974class HPower: public HTemplateInstruction<2> {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003975 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003976 static HInstruction* New(Zone* zone, HValue* left, HValue* right);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003977
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003978 HValue* left() { return OperandAt(0); }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003979 HValue* right() const { return OperandAt(1); }
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003980
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003981 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003982 return index == 0
3983 ? Representation::Double()
3984 : Representation::None();
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003985 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00003986 virtual Representation observed_input_representation(int index) {
3987 return RequiredInputRepresentation(index);
3988 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003989
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00003990 DECLARE_CONCRETE_INSTRUCTION(Power)
ager@chromium.org378b34e2011-01-28 08:04:38 +00003991
3992 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003993 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00003994
3995 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00003996 HPower(HValue* left, HValue* right) {
3997 SetOperandAt(0, left);
3998 SetOperandAt(1, right);
3999 set_representation(Representation::Double());
4000 SetFlag(kUseGVN);
4001 SetGVNFlag(kChangesNewSpacePromotion);
4002 }
4003
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004004 virtual bool IsDeletable() const {
4005 return !right()->representation().IsTagged();
4006 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00004007};
4008
4009
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004010class HRandom: public HTemplateInstruction<1> {
4011 public:
4012 explicit HRandom(HValue* global_object) {
4013 SetOperandAt(0, global_object);
4014 set_representation(Representation::Double());
4015 }
4016
4017 HValue* global_object() { return OperandAt(0); }
4018
4019 virtual Representation RequiredInputRepresentation(int index) {
4020 return Representation::Tagged();
4021 }
4022
4023 DECLARE_CONCRETE_INSTRUCTION(Random)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004024
4025 private:
4026 virtual bool IsDeletable() const { return true; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004027};
4028
4029
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004030class HAdd: public HArithmeticBinaryOperation {
4031 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004032 static HInstruction* New(Zone* zone,
4033 HValue* context,
4034 HValue* left,
4035 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004036
4037 // Add is only commutative if two integer values are added and not if two
4038 // tagged values are added (because it might be a String concatenation).
4039 virtual bool IsCommutative() const {
4040 return !representation().IsTagged();
4041 }
4042
4043 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4044
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004045 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004046
ulan@chromium.org812308e2012-02-29 15:58:45 +00004047 virtual HValue* Canonicalize();
4048
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004049 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
4050 HValue* base = NULL;
4051 int32_t offset = 0;
4052 if (left()->IsInteger32Constant()) {
4053 base = right();
4054 offset = left()->GetInteger32Constant();
4055 } else if (right()->IsInteger32Constant()) {
4056 base = left();
4057 offset = right()->GetInteger32Constant();
4058 } else {
4059 return false;
4060 }
4061
4062 return relation.IsExtendable(offset)
4063 ? base->IsRelationTrue(relation, other) : false;
4064 }
4065
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004066 DECLARE_CONCRETE_INSTRUCTION(Add)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004067
4068 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004069 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004070
ulan@chromium.org812308e2012-02-29 15:58:45 +00004071 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004072
4073 private:
4074 HAdd(HValue* context, HValue* left, HValue* right)
4075 : HArithmeticBinaryOperation(context, left, right) {
4076 SetFlag(kCanOverflow);
4077 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004078};
4079
4080
4081class HSub: public HArithmeticBinaryOperation {
4082 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004083 static HInstruction* New(Zone* zone,
4084 HValue* context,
4085 HValue* left,
4086 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004087
4088 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4089
ulan@chromium.org812308e2012-02-29 15:58:45 +00004090 virtual HValue* Canonicalize();
4091
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +00004092 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
4093 if (right()->IsInteger32Constant()) {
4094 HValue* base = left();
4095 int32_t offset = right()->GetInteger32Constant();
4096 return relation.IsExtendable(-offset)
4097 ? base->IsRelationTrue(relation, other) : false;
4098 } else {
4099 return false;
4100 }
4101 }
4102
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004103 DECLARE_CONCRETE_INSTRUCTION(Sub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004104
4105 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004106 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004107
ulan@chromium.org812308e2012-02-29 15:58:45 +00004108 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004109
4110 private:
4111 HSub(HValue* context, HValue* left, HValue* right)
4112 : HArithmeticBinaryOperation(context, left, right) {
4113 SetFlag(kCanOverflow);
4114 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004115};
4116
4117
4118class HMul: public HArithmeticBinaryOperation {
4119 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004120 static HInstruction* New(Zone* zone,
4121 HValue* context,
4122 HValue* left,
4123 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004124
4125 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4126
4127 // Only commutative if it is certain that not two objects are multiplicated.
4128 virtual bool IsCommutative() const {
4129 return !representation().IsTagged();
4130 }
4131
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004132 DECLARE_CONCRETE_INSTRUCTION(Mul)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004133
4134 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004135 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004136
ulan@chromium.org812308e2012-02-29 15:58:45 +00004137 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004138
4139 private:
4140 HMul(HValue* context, HValue* left, HValue* right)
4141 : HArithmeticBinaryOperation(context, left, right) {
4142 SetFlag(kCanOverflow);
4143 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004144};
4145
4146
4147class HMod: public HArithmeticBinaryOperation {
4148 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004149 static HInstruction* New(Zone* zone,
4150 HValue* context,
4151 HValue* left,
4152 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004153
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004154 bool HasPowerOf2Divisor() {
4155 if (right()->IsConstant() &&
4156 HConstant::cast(right())->HasInteger32Value()) {
4157 int32_t value = HConstant::cast(right())->Integer32Value();
4158 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4159 }
4160
4161 return false;
4162 }
4163
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004164 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4165
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004166 DECLARE_CONCRETE_INSTRUCTION(Mod)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004167
4168 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004169 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004170
ulan@chromium.org812308e2012-02-29 15:58:45 +00004171 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004172
4173 private:
4174 HMod(HValue* context, HValue* left, HValue* right)
4175 : HArithmeticBinaryOperation(context, left, right) {
4176 SetFlag(kCanBeDivByZero);
4177 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004178};
4179
4180
4181class HDiv: public HArithmeticBinaryOperation {
4182 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004183 static HInstruction* New(Zone* zone,
4184 HValue* context,
4185 HValue* left,
4186 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004187
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004188 bool HasPowerOf2Divisor() {
4189 if (right()->IsConstant() &&
4190 HConstant::cast(right())->HasInteger32Value()) {
4191 int32_t value = HConstant::cast(right())->Integer32Value();
4192 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
4193 }
4194
4195 return false;
4196 }
4197
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004198 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4199
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004200 DECLARE_CONCRETE_INSTRUCTION(Div)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004201
4202 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004203 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004204
ulan@chromium.org812308e2012-02-29 15:58:45 +00004205 virtual Range* InferRange(Zone* zone);
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004206
4207 private:
4208 HDiv(HValue* context, HValue* left, HValue* right)
4209 : HArithmeticBinaryOperation(context, left, right) {
4210 SetFlag(kCanBeDivByZero);
4211 SetFlag(kCanOverflow);
4212 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004213};
4214
4215
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004216class HMathMinMax: public HArithmeticBinaryOperation {
4217 public:
4218 enum Operation { kMathMin, kMathMax };
4219
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004220 static HInstruction* New(Zone* zone,
4221 HValue* context,
4222 HValue* left,
4223 HValue* right,
4224 Operation op);
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004225
4226 virtual Representation RequiredInputRepresentation(int index) {
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004227 return index == 0 ? Representation::Tagged()
4228 : representation();
4229 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004230
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004231 virtual Representation observed_input_representation(int index) {
4232 return RequiredInputRepresentation(index);
4233 }
4234
jkummerow@chromium.org5323a9c2012-12-10 19:00:50 +00004235 virtual void InferRepresentation(HInferRepresentation* h_infer);
4236
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00004237 virtual Representation RepresentationFromInputs() {
4238 Representation left_rep = left()->representation();
4239 Representation right_rep = right()->representation();
4240 if ((left_rep.IsNone() || left_rep.IsInteger32()) &&
4241 (right_rep.IsNone() || right_rep.IsInteger32())) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004242 return Representation::Integer32();
4243 }
4244 return Representation::Double();
4245 }
4246
4247 virtual bool IsCommutative() const { return true; }
4248
4249 Operation operation() { return operation_; }
4250
4251 DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
4252
4253 protected:
4254 virtual bool DataEquals(HValue* other) {
4255 return other->IsMathMinMax() &&
4256 HMathMinMax::cast(other)->operation_ == operation_;
4257 }
4258
4259 virtual Range* InferRange(Zone* zone);
4260
4261 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004262 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
4263 : HArithmeticBinaryOperation(context, left, right),
4264 operation_(op) { }
4265
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004266 Operation operation_;
4267};
4268
4269
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004270class HBitwise: public HBitwiseBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004271 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004272 static HInstruction* New(Zone* zone,
4273 Token::Value op,
4274 HValue* context,
4275 HValue* left,
4276 HValue* right);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004277
4278 Token::Value op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004279
4280 virtual bool IsCommutative() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004281
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004282 virtual HValue* Canonicalize();
4283
erik.corry@gmail.comed49e962012-04-17 11:57:53 +00004284 virtual void PrintDataTo(StringStream* stream);
4285
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004286 DECLARE_CONCRETE_INSTRUCTION(Bitwise)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004287
4288 protected:
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004289 virtual bool DataEquals(HValue* other) {
4290 return op() == HBitwise::cast(other)->op();
4291 }
ager@chromium.org378b34e2011-01-28 08:04:38 +00004292
ulan@chromium.org812308e2012-02-29 15:58:45 +00004293 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004294
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004295 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004296 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right)
4297 : HBitwiseBinaryOperation(context, left, right), op_(op) {
4298 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
4299 }
4300
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004301 Token::Value op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004302};
4303
4304
4305class HShl: public HBitwiseBinaryOperation {
4306 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004307 static HInstruction* New(Zone* zone,
4308 HValue* context,
4309 HValue* left,
4310 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004311
ulan@chromium.org812308e2012-02-29 15:58:45 +00004312 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004313
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004314 DECLARE_CONCRETE_INSTRUCTION(Shl)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004315
4316 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004317 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004318
4319 private:
4320 HShl(HValue* context, HValue* left, HValue* right)
4321 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004322};
4323
4324
4325class HShr: public HBitwiseBinaryOperation {
4326 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004327 static HInstruction* New(Zone* zone,
4328 HValue* context,
4329 HValue* left,
4330 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004331
ulan@chromium.org812308e2012-02-29 15:58:45 +00004332 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004333
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004334 DECLARE_CONCRETE_INSTRUCTION(Shr)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004335
4336 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004337 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004338
4339 private:
4340 HShr(HValue* context, HValue* left, HValue* right)
4341 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004342};
4343
4344
4345class HSar: public HBitwiseBinaryOperation {
4346 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004347 static HInstruction* New(Zone* zone,
4348 HValue* context,
4349 HValue* left,
4350 HValue* right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004351
ulan@chromium.org812308e2012-02-29 15:58:45 +00004352 virtual Range* InferRange(Zone* zone);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004353
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004354 DECLARE_CONCRETE_INSTRUCTION(Sar)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004355
4356 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004357 virtual bool DataEquals(HValue* other) { return true; }
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004358
4359 private:
4360 HSar(HValue* context, HValue* left, HValue* right)
4361 : HBitwiseBinaryOperation(context, left, right) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004362};
4363
4364
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004365class HRor: public HBitwiseBinaryOperation {
4366 public:
4367 HRor(HValue* context, HValue* left, HValue* right)
ulan@chromium.org2e04b582013-02-21 14:06:02 +00004368 : HBitwiseBinaryOperation(context, left, right) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004369 ChangeRepresentation(Representation::Integer32());
4370 }
4371
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00004372 DECLARE_CONCRETE_INSTRUCTION(Ror)
4373
4374 protected:
4375 virtual bool DataEquals(HValue* other) { return true; }
4376};
4377
4378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004379class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004380 public:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004381 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004382 SetGVNFlag(kChangesOsrEntries);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004383 }
4384
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004385 BailoutId ast_id() const { return ast_id_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004386
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004387 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004388 return Representation::None();
4389 }
4390
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004391 DECLARE_CONCRETE_INSTRUCTION(OsrEntry)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004392
4393 private:
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +00004394 BailoutId ast_id_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004395};
4396
4397
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004398class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004399 public:
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004400 enum ParameterKind {
4401 STACK_PARAMETER,
4402 REGISTER_PARAMETER
4403 };
4404
4405 explicit HParameter(unsigned index,
4406 ParameterKind kind = STACK_PARAMETER)
4407 : index_(index),
4408 kind_(kind) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004409 set_representation(Representation::Tagged());
4410 }
4411
4412 unsigned index() const { return index_; }
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004413 ParameterKind kind() const { return kind_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004415 virtual void PrintDataTo(StringStream* stream);
4416
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004417 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004418 return Representation::None();
4419 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004420
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004421 DECLARE_CONCRETE_INSTRUCTION(Parameter)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004422
4423 private:
4424 unsigned index_;
mmassi@chromium.org2f0efde2013-02-06 14:12:58 +00004425 ParameterKind kind_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004426};
4427
4428
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004429class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004430 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004431 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
4432 : HUnaryCall(context, argument_count),
4433 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004434 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004435 }
4436
4437 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004439 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004440
4441 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
4442 transcendental_type_ = transcendental_type;
4443 }
4444 TranscendentalCache::Type transcendental_type() {
4445 return transcendental_type_;
4446 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004447
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004448 virtual void PrintDataTo(StringStream* stream);
4449
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004450 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004451 return Representation::Tagged();
4452 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004453
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004454 DECLARE_CONCRETE_INSTRUCTION(CallStub)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004455
4456 private:
4457 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004458 TranscendentalCache::Type transcendental_type_;
4459};
4460
4461
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004462class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004463 public:
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004464 HUnknownOSRValue()
4465 : incoming_value_(NULL) {
4466 set_representation(Representation::Tagged());
4467 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004468
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004469 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004470 return Representation::None();
4471 }
4472
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004473 void set_incoming_value(HPhi* value) {
4474 incoming_value_ = value;
4475 }
4476
4477 HPhi* incoming_value() {
4478 return incoming_value_;
4479 }
4480
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004481 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
rossberg@chromium.org2c067b12012-03-19 11:01:52 +00004482
4483 private:
4484 HPhi* incoming_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004485};
4486
4487
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004488class HLoadGlobalCell: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004489 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004490 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details)
4491 : cell_(cell), details_(details) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004492 set_representation(Representation::Tagged());
4493 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004494 SetGVNFlag(kDependsOnGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004495 }
4496
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004497 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004498 bool RequiresHoleCheck() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004499
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004500 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004501
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004502 virtual intptr_t Hashcode() {
yangguo@chromium.org304cc332012-07-24 07:59:48 +00004503 ASSERT_ALLOCATION_DISABLED;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00004504 // Dereferencing to use the object's raw address for hashing is safe.
ulan@chromium.org09d7ab52013-02-25 15:50:35 +00004505 AllowHandleDereference allow_handle_deref(isolate());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004506 return reinterpret_cast<intptr_t>(*cell_);
4507 }
4508
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004509 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004510 return Representation::None();
4511 }
4512
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004513 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004514
4515 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004516 virtual bool DataEquals(HValue* other) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004517 HLoadGlobalCell* b = HLoadGlobalCell::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004518 return cell_.is_identical_to(b->cell());
4519 }
4520
4521 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004522 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4523
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004524 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004525 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004526};
4527
4528
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004529class HLoadGlobalGeneric: public HTemplateInstruction<2> {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004530 public:
4531 HLoadGlobalGeneric(HValue* context,
4532 HValue* global_object,
4533 Handle<Object> name,
4534 bool for_typeof)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004535 : name_(name),
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004536 for_typeof_(for_typeof) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004537 SetOperandAt(0, context);
4538 SetOperandAt(1, global_object);
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004539 set_representation(Representation::Tagged());
4540 SetAllSideEffects();
4541 }
4542
4543 HValue* context() { return OperandAt(0); }
4544 HValue* global_object() { return OperandAt(1); }
4545 Handle<Object> name() const { return name_; }
4546 bool for_typeof() const { return for_typeof_; }
4547
4548 virtual void PrintDataTo(StringStream* stream);
4549
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004550 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004551 return Representation::Tagged();
4552 }
4553
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004554 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric)
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00004555
4556 private:
4557 Handle<Object> name_;
4558 bool for_typeof_;
4559};
4560
4561
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004562class HAllocateObject: public HTemplateInstruction<1> {
4563 public:
4564 HAllocateObject(HValue* context, Handle<JSFunction> constructor)
4565 : constructor_(constructor) {
4566 SetOperandAt(0, context);
4567 set_representation(Representation::Tagged());
4568 SetGVNFlag(kChangesNewSpacePromotion);
4569 }
4570
4571 // Maximum instance size for which allocations will be inlined.
4572 static const int kMaxSize = 64 * kPointerSize;
4573
4574 HValue* context() { return OperandAt(0); }
4575 Handle<JSFunction> constructor() { return constructor_; }
4576
4577 virtual Representation RequiredInputRepresentation(int index) {
4578 return Representation::Tagged();
4579 }
4580 virtual Handle<Map> GetMonomorphicJSObjectMap() {
4581 ASSERT(constructor()->has_initial_map());
4582 return Handle<Map>(constructor()->initial_map());
4583 }
4584 virtual HType CalculateInferredType();
4585
4586 DECLARE_CONCRETE_INSTRUCTION(AllocateObject)
4587
4588 private:
4589 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
4590 // virtual bool IsDeletable() const { return true; }
4591
4592 Handle<JSFunction> constructor_;
4593};
4594
4595
4596class HAllocate: public HTemplateInstruction<2> {
4597 public:
4598 enum Flags {
4599 CAN_ALLOCATE_IN_NEW_SPACE = 1 << 0,
4600 CAN_ALLOCATE_IN_OLD_DATA_SPACE = 1 << 1,
4601 CAN_ALLOCATE_IN_OLD_POINTER_SPACE = 1 << 2,
4602 ALLOCATE_DOUBLE_ALIGNED = 1 << 3
4603 };
4604
4605 HAllocate(HValue* context, HValue* size, HType type, Flags flags)
4606 : type_(type),
4607 flags_(flags) {
4608 ASSERT((flags & CAN_ALLOCATE_IN_OLD_DATA_SPACE) == 0); // unimplemented
4609 ASSERT((flags & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) == 0); // unimplemented
4610 SetOperandAt(0, context);
4611 SetOperandAt(1, size);
4612 set_representation(Representation::Tagged());
4613 SetGVNFlag(kChangesNewSpacePromotion);
4614 }
4615
4616 HValue* context() { return OperandAt(0); }
4617 HValue* size() { return OperandAt(1); }
4618
4619 virtual Representation RequiredInputRepresentation(int index) {
4620 if (index == 0) {
4621 return Representation::Tagged();
4622 } else {
4623 return Representation::Integer32();
4624 }
4625 }
4626
4627 virtual HType CalculateInferredType();
4628
4629 bool CanAllocateInNewSpace() const {
4630 return (flags_ & CAN_ALLOCATE_IN_NEW_SPACE) != 0;
4631 }
4632
4633 bool CanAllocateInOldDataSpace() const {
4634 return (flags_ & CAN_ALLOCATE_IN_OLD_DATA_SPACE) != 0;
4635 }
4636
4637 bool CanAllocateInOldPointerSpace() const {
4638 return (flags_ & CAN_ALLOCATE_IN_OLD_POINTER_SPACE) != 0;
4639 }
4640
4641 bool CanAllocateInOldSpace() const {
4642 return CanAllocateInOldDataSpace() ||
4643 CanAllocateInOldPointerSpace();
4644 }
4645
4646 bool GuaranteedInNewSpace() const {
4647 return CanAllocateInNewSpace() && !CanAllocateInOldSpace();
4648 }
4649
4650 bool MustAllocateDoubleAligned() const {
4651 return (flags_ & ALLOCATE_DOUBLE_ALIGNED) != 0;
4652 }
4653
4654 DECLARE_CONCRETE_INSTRUCTION(Allocate)
4655
4656 private:
4657 HType type_;
4658 Flags flags_;
4659};
4660
4661
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004662inline bool StoringValueNeedsWriteBarrier(HValue* value) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004663 return !value->type().IsBoolean()
4664 && !value->type().IsSmi()
4665 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable());
4666}
4667
4668
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004669inline bool ReceiverObjectNeedsWriteBarrier(HValue* object,
4670 HValue* new_space_dominator) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00004671 if (object != new_space_dominator) return true;
4672 if (object->IsFastLiteral()) return false;
4673 if (object->IsAllocateObject()) return false;
4674 if (object->IsAllocate()) {
4675 return !HAllocate::cast(object)->GuaranteedInNewSpace();
4676 }
4677 return true;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00004678}
4679
4680
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004681class HStoreGlobalCell: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004682 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004683 HStoreGlobalCell(HValue* value,
4684 Handle<JSGlobalPropertyCell> cell,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004685 PropertyDetails details)
ager@chromium.org378b34e2011-01-28 08:04:38 +00004686 : HUnaryOperation(value),
4687 cell_(cell),
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004688 details_(details) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004689 SetGVNFlag(kChangesGlobalVars);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004690 }
4691
4692 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004693 bool RequiresHoleCheck() {
4694 return !details_.IsDontDelete() || details_.IsReadOnly();
4695 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004696 bool NeedsWriteBarrier() {
4697 return StoringValueNeedsWriteBarrier(value());
4698 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004699
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004700 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004701 return Representation::Tagged();
4702 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004703 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004704
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004705 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004706
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004707 private:
4708 Handle<JSGlobalPropertyCell> cell_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004709 PropertyDetails details_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004710};
4711
4712
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004713class HStoreGlobalGeneric: public HTemplateInstruction<3> {
4714 public:
4715 HStoreGlobalGeneric(HValue* context,
4716 HValue* global_object,
4717 Handle<Object> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004718 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004719 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004720 : name_(name),
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004721 strict_mode_flag_(strict_mode_flag) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004722 SetOperandAt(0, context);
4723 SetOperandAt(1, global_object);
4724 SetOperandAt(2, value);
4725 set_representation(Representation::Tagged());
4726 SetAllSideEffects();
4727 }
4728
4729 HValue* context() { return OperandAt(0); }
4730 HValue* global_object() { return OperandAt(1); }
4731 Handle<Object> name() const { return name_; }
4732 HValue* value() { return OperandAt(2); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004733 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004734
4735 virtual void PrintDataTo(StringStream* stream);
4736
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004737 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004738 return Representation::Tagged();
4739 }
4740
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004741 DECLARE_CONCRETE_INSTRUCTION(StoreGlobalGeneric)
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004742
4743 private:
4744 Handle<Object> name_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00004745 StrictModeFlag strict_mode_flag_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +00004746};
4747
4748
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004749class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004750 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004751 enum Mode {
4752 // Perform a normal load of the context slot without checking its value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004753 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004754 // Load and check the value of the context slot. Deoptimize if it's the
4755 // hole value. This is used for checking for loading of uninitialized
4756 // harmony bindings where we deoptimize into full-codegen generated code
4757 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004758 kCheckDeoptimize,
4759 // Load and check the value of the context slot. Return undefined if it's
4760 // the hole value. This is used for non-harmony const assignments
4761 kCheckReturnUndefined
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004762 };
4763
4764 HLoadContextSlot(HValue* context, Variable* var)
4765 : HUnaryOperation(context), slot_index_(var->index()) {
4766 ASSERT(var->IsContextSlot());
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004767 switch (var->mode()) {
4768 case LET:
4769 case CONST_HARMONY:
4770 mode_ = kCheckDeoptimize;
4771 break;
4772 case CONST:
4773 mode_ = kCheckReturnUndefined;
4774 break;
4775 default:
4776 mode_ = kNoCheck;
4777 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004778 set_representation(Representation::Tagged());
4779 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004780 SetGVNFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004781 }
4782
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004783 int slot_index() const { return slot_index_; }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004784 Mode mode() const { return mode_; }
4785
4786 bool DeoptimizesOnHole() {
4787 return mode_ == kCheckDeoptimize;
4788 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004789
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004790 bool RequiresHoleCheck() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004791 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004792 }
4793
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004794 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004795 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004796 }
4797
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004798 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004799
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004800 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004801
4802 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004803 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004804 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004805 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004806 }
4807
4808 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004809 virtual bool IsDeletable() const { return !RequiresHoleCheck(); }
4810
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004811 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004812 Mode mode_;
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004813};
4814
4815
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004816class HStoreContextSlot: public HTemplateInstruction<2> {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004817 public:
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004818 enum Mode {
4819 // Perform a normal store to the context slot without checking its previous
4820 // value.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004821 kNoCheck,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004822 // Check the previous value of the context slot and deoptimize if it's the
4823 // hole value. This is used for checking for assignments to uninitialized
4824 // harmony bindings where we deoptimize into full-codegen generated code
4825 // which will subsequently throw a reference error.
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004826 kCheckDeoptimize,
4827 // Check the previous value and ignore assignment if it isn't a hole value
4828 kCheckIgnoreAssignment
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004829 };
4830
4831 HStoreContextSlot(HValue* context, int slot_index, Mode mode, HValue* value)
4832 : slot_index_(slot_index), mode_(mode) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004833 SetOperandAt(0, context);
4834 SetOperandAt(1, value);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004835 SetGVNFlag(kChangesContextSlots);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004836 }
4837
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004838 HValue* context() { return OperandAt(0); }
4839 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004840 int slot_index() const { return slot_index_; }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004841 Mode mode() const { return mode_; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004842
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004843 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004844 return StoringValueNeedsWriteBarrier(value());
4845 }
4846
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004847 bool DeoptimizesOnHole() {
4848 return mode_ == kCheckDeoptimize;
4849 }
4850
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004851 bool RequiresHoleCheck() {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004852 return mode_ != kNoCheck;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004853 }
4854
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004855 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004856 return Representation::Tagged();
4857 }
4858
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004859 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004860
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004861 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00004862
4863 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004864 int slot_index_;
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004865 Mode mode_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004866};
4867
4868
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004869class HLoadNamedField: public HUnaryOperation {
4870 public:
4871 HLoadNamedField(HValue* object, bool is_in_object, int offset)
4872 : HUnaryOperation(object),
4873 is_in_object_(is_in_object),
4874 offset_(offset) {
4875 set_representation(Representation::Tagged());
4876 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004877 SetGVNFlag(kDependsOnMaps);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004878 if (is_in_object) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004879 SetGVNFlag(kDependsOnInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004880 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004881 SetGVNFlag(kDependsOnBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004882 }
4883 }
4884
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004885 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004886 bool is_in_object() const { return is_in_object_; }
4887 int offset() const { return offset_; }
4888
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004889 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004890 return Representation::Tagged();
4891 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004892 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004893
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004894 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004895
4896 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004897 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004898 HLoadNamedField* b = HLoadNamedField::cast(other);
4899 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
4900 }
4901
4902 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00004903 virtual bool IsDeletable() const { return true; }
4904
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004905 bool is_in_object_;
4906 int offset_;
4907};
4908
4909
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004910class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004911 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004912 HLoadNamedFieldPolymorphic(HValue* context,
4913 HValue* object,
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004914 SmallMapList* types,
mmassi@chromium.org7028c052012-06-13 11:51:58 +00004915 Handle<String> name,
4916 Zone* zone);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004917
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004918 HValue* context() { return OperandAt(0); }
4919 HValue* object() { return OperandAt(1); }
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004920 SmallMapList* types() { return &types_; }
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004921 Handle<String> name() { return name_; }
4922 bool need_generic() { return need_generic_; }
4923
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004924 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004925 return Representation::Tagged();
4926 }
4927
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00004928 virtual void PrintDataTo(StringStream* stream);
4929
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004930 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic)
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004931
4932 static const int kMaxLoadPolymorphism = 4;
4933
4934 protected:
4935 virtual bool DataEquals(HValue* value);
4936
4937 private:
ricow@chromium.orgddd545c2011-08-24 12:02:41 +00004938 SmallMapList types_;
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004939 Handle<String> name_;
4940 bool need_generic_;
4941};
4942
4943
4944
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004945class HLoadNamedGeneric: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004946 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00004947 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004948 : name_(name) {
4949 SetOperandAt(0, context);
4950 SetOperandAt(1, object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004951 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004952 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004953 }
4954
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004955 HValue* context() { return OperandAt(0); }
4956 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004957 Handle<Object> name() const { return name_; }
4958
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004959 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004960 return Representation::Tagged();
4961 }
4962
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00004963 virtual void PrintDataTo(StringStream* stream);
4964
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004965 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004967 private:
4968 Handle<Object> name_;
4969};
4970
4971
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004972class HLoadFunctionPrototype: public HUnaryOperation {
4973 public:
4974 explicit HLoadFunctionPrototype(HValue* function)
4975 : HUnaryOperation(function) {
4976 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00004977 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00004978 SetGVNFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004979 }
4980
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004981 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004982
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004983 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004984 return Representation::Tagged();
4985 }
4986
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00004987 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004988
4989 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00004990 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00004991};
4992
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00004993class ArrayInstructionInterface {
4994 public:
4995 virtual HValue* GetKey() = 0;
4996 virtual void SetKey(HValue* key) = 0;
4997 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4998 virtual bool IsDehoisted() = 0;
4999 virtual void SetDehoisted(bool is_dehoisted) = 0;
5000 virtual ~ArrayInstructionInterface() { };
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005001
5002 static Representation KeyedAccessIndexRequirement(Representation r) {
5003 return r.IsInteger32() ? Representation::Integer32()
5004 : Representation::Tagged();
5005 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005006};
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00005007
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005008
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005009enum LoadKeyedHoleMode {
5010 NEVER_RETURN_HOLE,
5011 ALLOW_RETURN_HOLE
5012};
5013
5014
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005015class HLoadKeyed
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005016 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005017 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005018 HLoadKeyed(HValue* obj,
5019 HValue* key,
5020 HValue* dependency,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005021 ElementsKind elements_kind,
5022 LoadKeyedHoleMode mode = NEVER_RETURN_HOLE)
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005023 : bit_field_(0) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005024 bit_field_ = ElementsKindField::encode(elements_kind) |
5025 HoleModeField::encode(mode);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005026
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005027 SetOperandAt(0, obj);
5028 SetOperandAt(1, key);
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005029 SetOperandAt(2, dependency != NULL ? dependency : obj);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005030
5031 if (!is_external()) {
5032 // I can detect the case between storing double (holey and fast) and
5033 // smi/object by looking at elements_kind_.
5034 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
5035 IsFastDoubleElementsKind(elements_kind));
5036
5037 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005038 if (IsFastSmiElementsKind(elements_kind)) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005039 set_type(HType::Smi());
5040 }
5041
5042 set_representation(Representation::Tagged());
5043 SetGVNFlag(kDependsOnArrayElements);
5044 } else {
5045 set_representation(Representation::Double());
5046 SetGVNFlag(kDependsOnDoubleArrayElements);
5047 }
5048 } else {
5049 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
5050 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
5051 set_representation(Representation::Double());
5052 } else {
5053 set_representation(Representation::Integer32());
5054 }
5055
5056 SetGVNFlag(kDependsOnSpecializedArrayElements);
5057 // Native code could change the specialized array.
5058 SetGVNFlag(kDependsOnCalls);
5059 }
5060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005061 SetFlag(kUseGVN);
5062 }
5063
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005064 bool is_external() const {
5065 return IsExternalArrayElementsKind(elements_kind());
5066 }
5067 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005068 HValue* key() { return OperandAt(1); }
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00005069 HValue* dependency() {
5070 ASSERT(HasDependency());
5071 return OperandAt(2);
5072 }
5073 bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005074 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
5075 void SetIndexOffset(uint32_t index_offset) {
5076 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
5077 }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005078 HValue* GetKey() { return key(); }
5079 void SetKey(HValue* key) { SetOperandAt(1, key); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005080 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
5081 void SetDehoisted(bool is_dehoisted) {
5082 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
5083 }
5084 ElementsKind elements_kind() const {
5085 return ElementsKindField::decode(bit_field_);
5086 }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005087 LoadKeyedHoleMode hole_mode() const {
5088 return HoleModeField::decode(bit_field_);
5089 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005090
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005091 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005092 // kind_fast: tagged[int32] (none)
5093 // kind_double: tagged[int32] (none)
5094 // kind_external: external[int32] (none)
5095 if (index == 0) {
5096 return is_external() ? Representation::External()
5097 : Representation::Tagged();
5098 }
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005099 if (index == 1) {
5100 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5101 OperandAt(1)->representation());
5102 }
yangguo@chromium.org304cc332012-07-24 07:59:48 +00005103 return Representation::None();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005104 }
5105
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005106 virtual Representation observed_input_representation(int index) {
5107 return RequiredInputRepresentation(index);
5108 }
5109
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005110 virtual void PrintDataTo(StringStream* stream);
5111
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005112 bool UsesMustHandleHole() const;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005113 bool RequiresHoleCheck() const;
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005114
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005115 virtual Range* InferRange(Zone* zone);
5116
5117 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
ager@chromium.org378b34e2011-01-28 08:04:38 +00005118
5119 protected:
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005120 virtual bool DataEquals(HValue* other) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005121 if (!other->IsLoadKeyed()) return false;
5122 HLoadKeyed* other_load = HLoadKeyed::cast(other);
5123
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005124 if (IsDehoisted() && index_offset() != other_load->index_offset())
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005125 return false;
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005126 return elements_kind() == other_load->elements_kind();
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005127 }
5128
5129 private:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005130 virtual bool IsDeletable() const {
5131 return !RequiresHoleCheck();
5132 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005133
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005134 // Establish some checks around our packed fields
5135 enum LoadKeyedBits {
5136 kBitsForElementsKind = 5,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005137 kBitsForHoleMode = 1,
5138 kBitsForIndexOffset = 25,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005139 kBitsForIsDehoisted = 1,
5140
5141 kStartElementsKind = 0,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005142 kStartHoleMode = kStartElementsKind + kBitsForElementsKind,
5143 kStartIndexOffset = kStartHoleMode + kBitsForHoleMode,
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005144 kStartIsDehoisted = kStartIndexOffset + kBitsForIndexOffset
5145 };
5146
5147 STATIC_ASSERT((kBitsForElementsKind + kBitsForIndexOffset +
5148 kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
5149 STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
5150 class ElementsKindField:
5151 public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
5152 {}; // NOLINT
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005153 class HoleModeField:
5154 public BitField<LoadKeyedHoleMode, kStartHoleMode, kBitsForHoleMode>
5155 {}; // NOLINT
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005156 class IndexOffsetField:
5157 public BitField<uint32_t, kStartIndexOffset, kBitsForIndexOffset>
5158 {}; // NOLINT
5159 class IsDehoistedField:
5160 public BitField<bool, kStartIsDehoisted, kBitsForIsDehoisted>
5161 {}; // NOLINT
mmassi@chromium.org7028c052012-06-13 11:51:58 +00005162 uint32_t bit_field_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005163};
5164
5165
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005166class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005167 public:
karlklose@chromium.org83a47282011-05-11 11:54:09 +00005168 HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005169 set_representation(Representation::Tagged());
5170 SetOperandAt(0, obj);
5171 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005172 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005173 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005174 }
5175
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005176 HValue* object() { return OperandAt(0); }
5177 HValue* key() { return OperandAt(1); }
5178 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005180 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005181
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005182 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005183 // tagged[tagged]
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005184 return Representation::Tagged();
5185 }
5186
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00005187 virtual HValue* Canonicalize();
5188
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005189 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005190};
5191
5192
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005193class HStoreNamedField: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005194 public:
5195 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005196 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005197 HValue* val,
5198 bool in_object,
5199 int offset)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005200 : name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005201 is_in_object_(in_object),
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005202 offset_(offset),
5203 new_space_dominator_(NULL) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005204 SetOperandAt(0, obj);
5205 SetOperandAt(1, val);
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005206 SetFlag(kTrackSideEffectDominators);
5207 SetGVNFlag(kDependsOnNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005208 if (is_in_object_) {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005209 SetGVNFlag(kChangesInobjectFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005210 } else {
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005211 SetGVNFlag(kChangesBackingStoreFields);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005212 }
5213 }
5214
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005215 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005216
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005217 virtual Representation RequiredInputRepresentation(int index) {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005218 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005219 }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005220 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5221 ASSERT(side_effect == kChangesNewSpacePromotion);
5222 new_space_dominator_ = dominator;
5223 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005224 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005225
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005226 HValue* object() { return OperandAt(0); }
5227 HValue* value() { return OperandAt(1); }
5228
5229 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005230 bool is_in_object() const { return is_in_object_; }
5231 int offset() const { return offset_; }
5232 Handle<Map> transition() const { return transition_; }
5233 void set_transition(Handle<Map> map) { transition_ = map; }
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005234 HValue* new_space_dominator() const { return new_space_dominator_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005235
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005236 bool NeedsWriteBarrier() {
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005237 return StoringValueNeedsWriteBarrier(value()) &&
5238 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
ricow@chromium.org83aa5492011-02-07 12:42:56 +00005239 }
5240
verwaest@chromium.org37141392012-05-31 13:27:02 +00005241 bool NeedsWriteBarrierForMap() {
5242 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
5243 }
5244
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005245 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005246 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005247 bool is_in_object_;
5248 int offset_;
5249 Handle<Map> transition_;
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005250 HValue* new_space_dominator_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005251};
5252
5253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005254class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005255 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005256 HStoreNamedGeneric(HValue* context,
5257 HValue* object,
5258 Handle<String> name,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005259 HValue* value,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005260 StrictModeFlag strict_mode_flag)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005261 : name_(name),
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005262 strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005263 SetOperandAt(0, object);
5264 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005265 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005266 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005267 }
5268
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005269 HValue* object() { return OperandAt(0); }
5270 HValue* value() { return OperandAt(1); }
5271 HValue* context() { return OperandAt(2); }
5272 Handle<String> name() { return name_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005273 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005275 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005276
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005277 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005278 return Representation::Tagged();
5279 }
5280
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005281 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005282
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005283 private:
5284 Handle<String> name_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005285 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005286};
5287
5288
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005289class HStoreKeyed
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005290 : public HTemplateInstruction<3>, public ArrayInstructionInterface {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005291 public:
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005292 HStoreKeyed(HValue* obj, HValue* key, HValue* val,
5293 ElementsKind elements_kind)
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005294 : elements_kind_(elements_kind),
5295 index_offset_(0),
5296 is_dehoisted_(false),
5297 new_space_dominator_(NULL) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005298 SetOperandAt(0, obj);
5299 SetOperandAt(1, key);
5300 SetOperandAt(2, val);
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005301
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005302 if (IsFastObjectElementsKind(elements_kind)) {
5303 SetFlag(kTrackSideEffectDominators);
5304 SetGVNFlag(kDependsOnNewSpacePromotion);
5305 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005306 if (is_external()) {
5307 SetGVNFlag(kChangesSpecializedArrayElements);
5308 } else if (IsFastDoubleElementsKind(elements_kind)) {
5309 SetGVNFlag(kChangesDoubleArrayElements);
5310 SetFlag(kDeoptimizeOnUndefined);
5311 } else {
5312 SetGVNFlag(kChangesArrayElements);
5313 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005314
5315 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
5316 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
5317 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
5318 SetFlag(kTruncatingToInt32);
5319 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005320 }
5321
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005322 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005323 // kind_fast: tagged[int32] = tagged
5324 // kind_double: tagged[int32] = double
5325 // kind_external: external[int32] = (double | int32)
5326 if (index == 0) {
5327 return is_external() ? Representation::External()
5328 : Representation::Tagged();
5329 } else if (index == 1) {
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00005330 return ArrayInstructionInterface::KeyedAccessIndexRequirement(
5331 OperandAt(1)->representation());
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005332 }
5333
5334 ASSERT_EQ(index, 2);
5335 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5336 return Representation::Double();
5337 }
5338
5339 return is_external() ? Representation::Integer32()
5340 : Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005341 }
5342
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005343 bool is_external() const {
5344 return IsExternalArrayElementsKind(elements_kind());
5345 }
yangguo@chromium.orgfb377212012-11-16 14:43:43 +00005346
5347 virtual Representation observed_input_representation(int index) {
5348 if (index < 2) return RequiredInputRepresentation(index);
5349 if (IsDoubleOrFloatElementsKind(elements_kind())) {
5350 return Representation::Double();
5351 }
5352 if (is_external()) {
5353 return Representation::Integer32();
5354 }
5355 // For fast object elements kinds, don't assume anything.
5356 return Representation::None();
5357 }
5358
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005359 HValue* elements() { return OperandAt(0); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005360 HValue* key() { return OperandAt(1); }
5361 HValue* value() { return OperandAt(2); }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005362 bool value_is_smi() const {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005363 return IsFastSmiElementsKind(elements_kind_);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005364 }
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005365 ElementsKind elements_kind() const { return elements_kind_; }
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005366 uint32_t index_offset() { return index_offset_; }
5367 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
5368 HValue* GetKey() { return key(); }
5369 void SetKey(HValue* key) { SetOperandAt(1, key); }
5370 bool IsDehoisted() { return is_dehoisted_; }
5371 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005372
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005373 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator) {
5374 ASSERT(side_effect == kChangesNewSpacePromotion);
5375 new_space_dominator_ = dominator;
5376 }
5377
5378 HValue* new_space_dominator() const { return new_space_dominator_; }
5379
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005380 bool NeedsWriteBarrier() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005381 if (value_is_smi()) {
5382 return false;
5383 } else {
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005384 return StoringValueNeedsWriteBarrier(value()) &&
5385 ReceiverObjectNeedsWriteBarrier(elements(), new_space_dominator());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005386 }
5387 }
5388
jkummerow@chromium.org28faa982012-04-13 09:58:30 +00005389 bool NeedsCanonicalization();
5390
rossberg@chromium.org717967f2011-07-20 13:44:42 +00005391 virtual void PrintDataTo(StringStream* stream);
5392
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005393 DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005394
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00005395 private:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00005396 ElementsKind elements_kind_;
ulan@chromium.org0e3f88b2012-05-22 09:16:05 +00005397 uint32_t index_offset_;
5398 bool is_dehoisted_;
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005399 HValue* new_space_dominator_;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005400};
5401
5402
5403class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005404 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005405 HStoreKeyedGeneric(HValue* context,
5406 HValue* object,
5407 HValue* key,
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005408 HValue* value,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005409 StrictModeFlag strict_mode_flag)
5410 : strict_mode_flag_(strict_mode_flag) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005411 SetOperandAt(0, object);
5412 SetOperandAt(1, key);
5413 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005414 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00005415 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005416 }
5417
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005418 HValue* object() { return OperandAt(0); }
5419 HValue* key() { return OperandAt(1); }
5420 HValue* value() { return OperandAt(2); }
5421 HValue* context() { return OperandAt(3); }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005422 StrictModeFlag strict_mode_flag() { return strict_mode_flag_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005423
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005424 virtual Representation RequiredInputRepresentation(int index) {
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +00005425 // tagged[tagged] = tagged
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005426 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005427 }
5428
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005429 virtual void PrintDataTo(StringStream* stream);
5430
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005431 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00005432
5433 private:
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00005434 StrictModeFlag strict_mode_flag_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005435};
5436
5437
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005438class HTransitionElementsKind: public HTemplateInstruction<2> {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005439 public:
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005440 HTransitionElementsKind(HValue* context,
5441 HValue* object,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005442 Handle<Map> original_map,
5443 Handle<Map> transitioned_map)
5444 : original_map_(original_map),
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005445 transitioned_map_(transitioned_map),
5446 from_kind_(original_map->elements_kind()),
5447 to_kind_(transitioned_map->elements_kind()) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005448 SetOperandAt(0, object);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005449 SetOperandAt(1, context);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005450 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005451 SetGVNFlag(kChangesElementsKind);
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005452 if (original_map->has_fast_double_elements()) {
5453 SetGVNFlag(kChangesElementsPointer);
5454 SetGVNFlag(kChangesNewSpacePromotion);
5455 }
5456 if (transitioned_map->has_fast_double_elements()) {
5457 SetGVNFlag(kChangesElementsPointer);
5458 SetGVNFlag(kChangesNewSpacePromotion);
5459 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005460 set_representation(Representation::Tagged());
5461 }
5462
5463 virtual Representation RequiredInputRepresentation(int index) {
5464 return Representation::Tagged();
5465 }
5466
5467 HValue* object() { return OperandAt(0); }
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005468 HValue* context() { return OperandAt(1); }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005469 Handle<Map> original_map() { return original_map_; }
5470 Handle<Map> transitioned_map() { return transitioned_map_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005471 ElementsKind from_kind() { return from_kind_; }
5472 ElementsKind to_kind() { return to_kind_; }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005473
5474 virtual void PrintDataTo(StringStream* stream);
5475
5476 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
5477
5478 protected:
5479 virtual bool DataEquals(HValue* other) {
5480 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
5481 return original_map_.is_identical_to(instr->original_map()) &&
5482 transitioned_map_.is_identical_to(instr->transitioned_map());
5483 }
5484
5485 private:
5486 Handle<Map> original_map_;
5487 Handle<Map> transitioned_map_;
yangguo@chromium.org003650e2013-01-24 16:31:08 +00005488 ElementsKind from_kind_;
5489 ElementsKind to_kind_;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005490};
5491
5492
danno@chromium.org160a7b02011-04-18 15:51:38 +00005493class HStringAdd: public HBinaryOperation {
5494 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005495 static HInstruction* New(Zone* zone,
5496 HValue* context,
5497 HValue* left,
5498 HValue* right);
danno@chromium.org160a7b02011-04-18 15:51:38 +00005499
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005500 virtual Representation RequiredInputRepresentation(int index) {
danno@chromium.org160a7b02011-04-18 15:51:38 +00005501 return Representation::Tagged();
5502 }
5503
5504 virtual HType CalculateInferredType() {
5505 return HType::String();
5506 }
5507
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005508 DECLARE_CONCRETE_INSTRUCTION(StringAdd)
danno@chromium.org160a7b02011-04-18 15:51:38 +00005509
5510 protected:
5511 virtual bool DataEquals(HValue* other) { return true; }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005512
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005513
5514 private:
5515 HStringAdd(HValue* context, HValue* left, HValue* right)
5516 : HBinaryOperation(context, left, right) {
5517 set_representation(Representation::Tagged());
5518 SetFlag(kUseGVN);
5519 SetGVNFlag(kDependsOnMaps);
5520 SetGVNFlag(kChangesNewSpacePromotion);
5521 }
5522
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005523 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005524 // virtual bool IsDeletable() const { return true; }
danno@chromium.org160a7b02011-04-18 15:51:38 +00005525};
5526
5527
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005528class HStringCharCodeAt: public HTemplateInstruction<3> {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005529 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005530 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) {
5531 SetOperandAt(0, context);
5532 SetOperandAt(1, string);
5533 SetOperandAt(2, index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005534 set_representation(Representation::Integer32());
5535 SetFlag(kUseGVN);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00005536 SetGVNFlag(kDependsOnMaps);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005537 SetGVNFlag(kChangesNewSpacePromotion);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005538 }
5539
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005540 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005541 // The index is supposed to be Integer32.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005542 return index == 2
5543 ? Representation::Integer32()
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005544 : Representation::Tagged();
5545 }
5546
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005547 HValue* context() { return OperandAt(0); }
5548 HValue* string() { return OperandAt(1); }
5549 HValue* index() { return OperandAt(2); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005550
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005551 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005552
5553 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005554 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00005555
ulan@chromium.org812308e2012-02-29 15:58:45 +00005556 virtual Range* InferRange(Zone* zone) {
yangguo@chromium.org154ff992012-03-13 08:09:54 +00005557 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005558 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005559
5560 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
5561 // private:
5562 // virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005563};
5564
5565
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005566class HStringCharFromCode: public HTemplateInstruction<2> {
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005567 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005568 static HInstruction* New(Zone* zone,
5569 HValue* context,
5570 HValue* char_code);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005571
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005572 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005573 return index == 0
5574 ? Representation::Tagged()
5575 : Representation::Integer32();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005576 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005577 virtual HType CalculateInferredType();
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005578
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005579 HValue* context() { return OperandAt(0); }
5580 HValue* value() { return OperandAt(1); }
5581
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005582 virtual bool DataEquals(HValue* other) { return true; }
5583
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005584 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005585
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005586 private:
5587 HStringCharFromCode(HValue* context, HValue* char_code) {
5588 SetOperandAt(0, context);
5589 SetOperandAt(1, char_code);
5590 set_representation(Representation::Tagged());
5591 SetFlag(kUseGVN);
5592 SetGVNFlag(kChangesNewSpacePromotion);
5593 }
5594
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005595 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005596 // virtual bool IsDeletable() const { return true; }
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00005597};
5598
5599
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005600class HStringLength: public HUnaryOperation {
5601 public:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005602 static HInstruction* New(Zone* zone, HValue* string);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005603
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005604 virtual Representation RequiredInputRepresentation(int index) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005605 return Representation::Tagged();
5606 }
5607
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005608 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005609 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
5610 return HType::Smi();
5611 }
5612
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005613 DECLARE_CONCRETE_INSTRUCTION(StringLength)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005614
5615 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005616 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00005617
ulan@chromium.org812308e2012-02-29 15:58:45 +00005618 virtual Range* InferRange(Zone* zone) {
5619 return new(zone) Range(0, String::kMaxLength);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005620 }
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005621
5622 private:
ulan@chromium.org2e04b582013-02-21 14:06:02 +00005623 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
5624 set_representation(Representation::Tagged());
5625 SetFlag(kUseGVN);
5626 SetGVNFlag(kDependsOnMaps);
5627 }
5628
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005629 virtual bool IsDeletable() const { return true; }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00005630};
5631
5632
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005633template <int V>
5634class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005635 public:
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005636 HMaterializedLiteral<V>(int index, int depth, AllocationSiteMode mode)
5637 : literal_index_(index), depth_(depth), allocation_site_mode_(mode) {
5638 this->set_representation(Representation::Tagged());
5639 }
5640
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005641 HMaterializedLiteral<V>(int index, int depth)
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005642 : literal_index_(index), depth_(depth),
5643 allocation_site_mode_(DONT_TRACK_ALLOCATION_SITE) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005644 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005645 }
5646
5647 int literal_index() const { return literal_index_; }
5648 int depth() const { return depth_; }
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005649 AllocationSiteMode allocation_site_mode() const {
5650 return allocation_site_mode_;
5651 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005652
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005653 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005654 virtual bool IsDeletable() const { return true; }
5655
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005656 int literal_index_;
5657 int depth_;
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005658 AllocationSiteMode allocation_site_mode_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005659};
5660
5661
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005662class HFastLiteral: public HMaterializedLiteral<1> {
5663 public:
5664 HFastLiteral(HValue* context,
5665 Handle<JSObject> boilerplate,
5666 int total_size,
5667 int literal_index,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005668 int depth,
5669 AllocationSiteMode mode)
5670 : HMaterializedLiteral<1>(literal_index, depth, mode),
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005671 boilerplate_(boilerplate),
5672 total_size_(total_size) {
5673 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005674 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005675 }
5676
5677 // Maximum depth and total number of elements and properties for literal
5678 // graphs to be considered for fast deep-copying.
5679 static const int kMaxLiteralDepth = 3;
5680 static const int kMaxLiteralProperties = 8;
5681
5682 HValue* context() { return OperandAt(0); }
5683 Handle<JSObject> boilerplate() const { return boilerplate_; }
5684 int total_size() const { return total_size_; }
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005685 virtual Representation RequiredInputRepresentation(int index) {
5686 return Representation::Tagged();
5687 }
mvstanton@chromium.orgd16d8532013-01-25 13:29:10 +00005688 virtual Handle<Map> GetMonomorphicJSObjectMap() {
5689 return Handle<Map>(boilerplate()->map());
5690 }
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005691 virtual HType CalculateInferredType();
5692
5693 DECLARE_CONCRETE_INSTRUCTION(FastLiteral)
5694
5695 private:
5696 Handle<JSObject> boilerplate_;
5697 int total_size_;
5698};
5699
5700
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005701class HArrayLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005702 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005703 HArrayLiteral(HValue* context,
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005704 Handle<HeapObject> boilerplate_object,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005705 int length,
5706 int literal_index,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00005707 int depth,
5708 AllocationSiteMode mode)
5709 : HMaterializedLiteral<1>(literal_index, depth, mode),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005710 length_(length),
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005711 boilerplate_object_(boilerplate_object) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005712 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005713 SetGVNFlag(kChangesNewSpacePromotion);
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005714 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005715
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005716 HValue* context() { return OperandAt(0); }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005717 ElementsKind boilerplate_elements_kind() const {
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005718 if (!boilerplate_object_->IsJSObject()) {
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00005719 return TERMINAL_FAST_ELEMENTS_KIND;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005720 }
5721 return Handle<JSObject>::cast(boilerplate_object_)->GetElementsKind();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00005722 }
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005723 Handle<HeapObject> boilerplate_object() const { return boilerplate_object_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005724 int length() const { return length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005725 bool IsCopyOnWrite() const;
5726
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005727 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005728 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005729 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005730 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005731
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005732 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005733
5734 private:
5735 int length_;
ricow@chromium.org7ad65222011-12-19 12:13:11 +00005736 Handle<HeapObject> boilerplate_object_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005737};
5738
5739
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005740class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005741 public:
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005742 HObjectLiteral(HValue* context,
5743 Handle<FixedArray> constant_properties,
5744 bool fast_elements,
5745 int literal_index,
5746 int depth,
5747 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005748 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005749 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005750 fast_elements_(fast_elements),
5751 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005752 SetOperandAt(0, context);
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005753 SetGVNFlag(kChangesNewSpacePromotion);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005754 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005755
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005756 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005757 Handle<FixedArray> constant_properties() const {
5758 return constant_properties_;
5759 }
5760 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005761 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005762
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005763 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005764 return Representation::Tagged();
5765 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005766 virtual HType CalculateInferredType();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00005767
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005768 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005769
5770 private:
5771 Handle<FixedArray> constant_properties_;
5772 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005773 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005774};
5775
5776
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005777class HRegExpLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005778 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005779 HRegExpLiteral(HValue* context,
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005780 Handle<FixedArray> literals,
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005781 Handle<String> pattern,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005782 Handle<String> flags,
5783 int literal_index)
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005784 : HMaterializedLiteral<1>(literal_index, 0),
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005785 literals_(literals),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005786 pattern_(pattern),
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005787 flags_(flags) {
5788 SetOperandAt(0, context);
ricow@chromium.org27bf2882011-11-17 08:34:43 +00005789 SetAllSideEffects();
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005790 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005791
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005792 HValue* context() { return OperandAt(0); }
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005793 Handle<FixedArray> literals() { return literals_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005794 Handle<String> pattern() { return pattern_; }
5795 Handle<String> flags() { return flags_; }
5796
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005797 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005798 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005799 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005800 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005801
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005802 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005803
5804 private:
yangguo@chromium.org9c741c82012-06-28 15:04:22 +00005805 Handle<FixedArray> literals_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005806 Handle<String> pattern_;
5807 Handle<String> flags_;
5808};
5809
5810
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005811class HFunctionLiteral: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005812 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005813 HFunctionLiteral(HValue* context,
5814 Handle<SharedFunctionInfo> shared,
5815 bool pretenure)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005816 : shared_info_(shared), pretenure_(pretenure) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005817 SetOperandAt(0, context);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005818 set_representation(Representation::Tagged());
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +00005819 SetGVNFlag(kChangesNewSpacePromotion);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005820 }
5821
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005822 HValue* context() { return OperandAt(0); }
5823
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005824 virtual Representation RequiredInputRepresentation(int index) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005825 return Representation::Tagged();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005826 }
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00005827 virtual HType CalculateInferredType();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005828
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005829 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005830
5831 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
5832 bool pretenure() const { return pretenure_; }
5833
5834 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005835 virtual bool IsDeletable() const { return true; }
5836
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005837 Handle<SharedFunctionInfo> shared_info_;
5838 bool pretenure_;
5839};
5840
5841
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005842class HTypeof: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005843 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005844 explicit HTypeof(HValue* context, HValue* value) {
5845 SetOperandAt(0, context);
5846 SetOperandAt(1, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005847 set_representation(Representation::Tagged());
5848 }
5849
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005850 HValue* context() { return OperandAt(0); }
5851 HValue* value() { return OperandAt(1); }
5852
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005853 virtual void PrintDataTo(StringStream* stream);
5854
5855 virtual Representation RequiredInputRepresentation(int index) {
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00005856 return Representation::Tagged();
5857 }
5858
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005859 DECLARE_CONCRETE_INSTRUCTION(Typeof)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005860
5861 private:
5862 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005863};
5864
5865
danno@chromium.org94b0d6f2013-02-04 13:33:20 +00005866class HTrapAllocationMemento : public HTemplateInstruction<1> {
5867 public:
5868 explicit HTrapAllocationMemento(HValue* obj) {
5869 SetOperandAt(0, obj);
5870 }
5871
5872 virtual Representation RequiredInputRepresentation(int index) {
5873 return Representation::Tagged();
5874 }
5875
5876 HValue* object() { return OperandAt(0); }
5877
5878 DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento)
5879};
5880
5881
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005882class HToFastProperties: public HUnaryOperation {
5883 public:
5884 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
5885 // This instruction is not marked as having side effects, but
5886 // changes the map of the input operand. Use it only when creating
5887 // object literals.
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00005888 ASSERT(value->IsObjectLiteral() || value->IsFastLiteral());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005889 set_representation(Representation::Tagged());
5890 }
5891
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005892 virtual Representation RequiredInputRepresentation(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005893 return Representation::Tagged();
5894 }
5895
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005896 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005897
5898 private:
5899 virtual bool IsDeletable() const { return true; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00005900};
5901
5902
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005903class HValueOf: public HUnaryOperation {
5904 public:
5905 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
5906 set_representation(Representation::Tagged());
5907 }
5908
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005909 virtual Representation RequiredInputRepresentation(int index) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005910 return Representation::Tagged();
5911 }
5912
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005913 DECLARE_CONCRETE_INSTRUCTION(ValueOf)
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00005914
5915 private:
5916 virtual bool IsDeletable() const { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005917};
5918
5919
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00005920class HDateField: public HUnaryOperation {
5921 public:
5922 HDateField(HValue* date, Smi* index)
5923 : HUnaryOperation(date), index_(index) {
5924 set_representation(Representation::Tagged());
5925 }
5926
5927 Smi* index() const { return index_; }
5928
5929 virtual Representation RequiredInputRepresentation(int index) {
5930 return Representation::Tagged();
5931 }
5932
5933 DECLARE_CONCRETE_INSTRUCTION(DateField)
5934
5935 private:
5936 Smi* index_;
5937};
5938
5939
mstarzinger@chromium.org32280cf2012-12-06 17:32:37 +00005940class HSeqStringSetChar: public HTemplateInstruction<3> {
5941 public:
5942 HSeqStringSetChar(String::Encoding encoding,
5943 HValue* string,
5944 HValue* index,
5945 HValue* value) : encoding_(encoding) {
5946 SetOperandAt(0, string);
5947 SetOperandAt(1, index);
5948 SetOperandAt(2, value);
5949 }
5950
5951 String::Encoding encoding() { return encoding_; }
5952 HValue* string() { return OperandAt(0); }
5953 HValue* index() { return OperandAt(1); }
5954 HValue* value() { return OperandAt(2); }
5955
5956 virtual Representation RequiredInputRepresentation(int index) {
5957 return Representation::Tagged();
5958 }
5959
5960 DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar)
5961
5962 private:
5963 String::Encoding encoding_;
5964};
5965
5966
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005967class HDeleteProperty: public HBinaryOperation {
5968 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005969 HDeleteProperty(HValue* context, HValue* obj, HValue* key)
5970 : HBinaryOperation(context, obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005971 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00005972 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005973 }
5974
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00005975 virtual Representation RequiredInputRepresentation(int index) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005976 return Representation::Tagged();
5977 }
5978
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00005979 virtual HType CalculateInferredType();
5980
ricow@chromium.orgdcebac02011-04-20 09:44:50 +00005981 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00005983 HValue* object() { return left(); }
5984 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00005985};
5986
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005987
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005988class HIn: public HTemplateInstruction<3> {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005989 public:
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005990 HIn(HValue* context, HValue* key, HValue* object) {
5991 SetOperandAt(0, context);
5992 SetOperandAt(1, key);
5993 SetOperandAt(2, object);
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00005994 set_representation(Representation::Tagged());
5995 SetAllSideEffects();
5996 }
5997
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00005998 HValue* context() { return OperandAt(0); }
5999 HValue* key() { return OperandAt(1); }
6000 HValue* object() { return OperandAt(2); }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006001
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00006002 virtual Representation RequiredInputRepresentation(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00006003 return Representation::Tagged();
6004 }
6005
6006 virtual HType CalculateInferredType() {
6007 return HType::Boolean();
6008 }
6009
6010 virtual void PrintDataTo(StringStream* stream);
6011
6012 DECLARE_CONCRETE_INSTRUCTION(In)
6013};
6014
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006015
6016class HCheckMapValue: public HTemplateInstruction<2> {
6017 public:
6018 HCheckMapValue(HValue* value,
6019 HValue* map) {
6020 SetOperandAt(0, value);
6021 SetOperandAt(1, map);
6022 set_representation(Representation::Tagged());
6023 SetFlag(kUseGVN);
6024 SetGVNFlag(kDependsOnMaps);
6025 SetGVNFlag(kDependsOnElementsKind);
6026 }
6027
6028 virtual Representation RequiredInputRepresentation(int index) {
6029 return Representation::Tagged();
6030 }
6031
6032 virtual void PrintDataTo(StringStream* stream);
6033
6034 virtual HType CalculateInferredType() {
6035 return HType::Tagged();
6036 }
6037
6038 HValue* value() { return OperandAt(0); }
6039 HValue* map() { return OperandAt(1); }
6040
6041 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
6042
6043 protected:
6044 virtual bool DataEquals(HValue* other) {
6045 return true;
6046 }
6047};
6048
6049
6050class HForInPrepareMap : public HTemplateInstruction<2> {
6051 public:
6052 HForInPrepareMap(HValue* context,
6053 HValue* object) {
6054 SetOperandAt(0, context);
6055 SetOperandAt(1, object);
6056 set_representation(Representation::Tagged());
6057 SetAllSideEffects();
6058 }
6059
6060 virtual Representation RequiredInputRepresentation(int index) {
6061 return Representation::Tagged();
6062 }
6063
6064 HValue* context() { return OperandAt(0); }
6065 HValue* enumerable() { return OperandAt(1); }
6066
6067 virtual void PrintDataTo(StringStream* stream);
6068
6069 virtual HType CalculateInferredType() {
6070 return HType::Tagged();
6071 }
6072
6073 DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
6074};
6075
6076
6077class HForInCacheArray : public HTemplateInstruction<2> {
6078 public:
6079 HForInCacheArray(HValue* enumerable,
6080 HValue* keys,
6081 int idx) : idx_(idx) {
6082 SetOperandAt(0, enumerable);
6083 SetOperandAt(1, keys);
6084 set_representation(Representation::Tagged());
6085 }
6086
6087 virtual Representation RequiredInputRepresentation(int index) {
6088 return Representation::Tagged();
6089 }
6090
6091 HValue* enumerable() { return OperandAt(0); }
6092 HValue* map() { return OperandAt(1); }
6093 int idx() { return idx_; }
6094
6095 HForInCacheArray* index_cache() {
6096 return index_cache_;
6097 }
6098
6099 void set_index_cache(HForInCacheArray* index_cache) {
6100 index_cache_ = index_cache;
6101 }
6102
6103 virtual void PrintDataTo(StringStream* stream);
6104
6105 virtual HType CalculateInferredType() {
6106 return HType::Tagged();
6107 }
6108
6109 DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
6110
6111 private:
6112 int idx_;
6113 HForInCacheArray* index_cache_;
6114};
6115
6116
6117class HLoadFieldByIndex : public HTemplateInstruction<2> {
6118 public:
6119 HLoadFieldByIndex(HValue* object,
6120 HValue* index) {
6121 SetOperandAt(0, object);
6122 SetOperandAt(1, index);
6123 set_representation(Representation::Tagged());
6124 }
6125
6126 virtual Representation RequiredInputRepresentation(int index) {
6127 return Representation::Tagged();
6128 }
6129
6130 HValue* object() { return OperandAt(0); }
6131 HValue* index() { return OperandAt(1); }
6132
6133 virtual void PrintDataTo(StringStream* stream);
6134
6135 virtual HType CalculateInferredType() {
6136 return HType::Tagged();
6137 }
6138
6139 DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +00006140
6141 private:
6142 virtual bool IsDeletable() const { return true; }
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +00006143};
6144
6145
kasperl@chromium.orga5551262010-12-07 12:49:48 +00006146#undef DECLARE_INSTRUCTION
6147#undef DECLARE_CONCRETE_INSTRUCTION
6148
6149} } // namespace v8::internal
6150
6151#endif // V8_HYDROGEN_INSTRUCTIONS_H_