blob: 3ca76f71328f9810ea65b4bad795627e7756478e [file] [log] [blame]
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001// Copyright 2011 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"
32#include "code-stubs.h"
33#include "string-stream.h"
34#include "zone.h"
35
36namespace v8 {
37namespace internal {
38
39// Forward declarations.
40class HBasicBlock;
41class HEnvironment;
42class HInstruction;
43class HLoopInformation;
44class HValue;
45class LInstruction;
46class LChunkBuilder;
47
48
kasperl@chromium.orga5551262010-12-07 12:49:48 +000049#define HYDROGEN_ALL_INSTRUCTION_LIST(V) \
50 V(ArithmeticBinaryOperation) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000051 V(BinaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052 V(BinaryOperation) \
53 V(BitwiseBinaryOperation) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054 V(ControlInstruction) \
55 V(Instruction) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056 V(Phi) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +000057 V(UnaryCall) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 V(UnaryControlInstruction) \
59 V(UnaryOperation) \
60 HYDROGEN_CONCRETE_INSTRUCTION_LIST(V)
61
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) \
67 V(ApplyArguments) \
68 V(ArgumentsElements) \
69 V(ArgumentsLength) \
70 V(ArgumentsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071 V(ArrayLiteral) \
72 V(BitAnd) \
73 V(BitNot) \
74 V(BitOr) \
75 V(BitXor) \
76 V(BlockEntry) \
77 V(BoundsCheck) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000078 V(CallConstantFunction) \
79 V(CallFunction) \
80 V(CallGlobal) \
81 V(CallKeyed) \
82 V(CallKnownGlobal) \
83 V(CallNamed) \
84 V(CallNew) \
85 V(CallRuntime) \
86 V(CallStub) \
87 V(Change) \
88 V(CheckFunction) \
89 V(CheckInstanceType) \
90 V(CheckMap) \
91 V(CheckNonSmi) \
92 V(CheckPrototypeMaps) \
93 V(CheckSmi) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +000094 V(ClassOfTest) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000095 V(Compare) \
96 V(CompareJSObjectEq) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000097 V(CompareMap) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +000098 V(Constant) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +000099 V(Context) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000100 V(DeleteProperty) \
101 V(Deoptimize) \
102 V(Div) \
103 V(EnterInlined) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000104 V(ExternalArrayLength) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000105 V(FixedArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000106 V(FunctionLiteral) \
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000107 V(GetCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000108 V(GlobalObject) \
109 V(GlobalReceiver) \
110 V(Goto) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000111 V(HasInstanceType) \
112 V(HasCachedArrayIndex) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000113 V(InstanceOf) \
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000114 V(InstanceOfKnownGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000115 V(IsNull) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000116 V(IsObject) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000117 V(IsSmi) \
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000118 V(IsConstructCall) \
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000119 V(JSArrayLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000120 V(LeaveInlined) \
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000121 V(LoadContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000122 V(LoadElements) \
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000123 V(LoadExternalArrayPointer) \
ager@chromium.org378b34e2011-01-28 08:04:38 +0000124 V(LoadFunctionPrototype) \
ricow@chromium.org3842d832011-03-17 14:48:24 +0000125 V(LoadGlobal) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000126 V(LoadKeyedFastElement) \
127 V(LoadKeyedGeneric) \
128 V(LoadNamedField) \
129 V(LoadNamedGeneric) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000130 V(LoadPixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 V(Mod) \
132 V(Mul) \
133 V(ObjectLiteral) \
134 V(OsrEntry) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000135 V(OuterContext) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(Parameter) \
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000137 V(Power) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000138 V(PushArgument) \
139 V(RegExpLiteral) \
140 V(Return) \
141 V(Sar) \
142 V(Shl) \
143 V(Shr) \
144 V(Simulate) \
145 V(StackCheck) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000146 V(StoreContextSlot) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000147 V(StoreGlobal) \
148 V(StoreKeyedFastElement) \
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000149 V(StorePixelArrayElement) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000150 V(StoreKeyedGeneric) \
151 V(StoreNamedField) \
152 V(StoreNamedGeneric) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000153 V(StringCharCodeAt) \
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000154 V(StringCharFromCode) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000155 V(StringLength) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156 V(Sub) \
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000157 V(Test) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000158 V(Throw) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000159 V(ToFastProperties) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 V(Typeof) \
161 V(TypeofIs) \
162 V(UnaryMathOperation) \
163 V(UnknownOSRValue) \
164 V(ValueOf)
165
166#define GVN_FLAG_LIST(V) \
167 V(Calls) \
168 V(InobjectFields) \
169 V(BackingStoreFields) \
170 V(ArrayElements) \
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000171 V(PixelArrayElements) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 V(GlobalVars) \
173 V(Maps) \
174 V(ArrayLengths) \
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000175 V(ContextSlots) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000176 V(OsrEntries)
177
178#define DECLARE_INSTRUCTION(type) \
179 virtual bool Is##type() const { return true; } \
180 static H##type* cast(HValue* value) { \
181 ASSERT(value->Is##type()); \
182 return reinterpret_cast<H##type*>(value); \
183 } \
184 Opcode opcode() const { return HValue::k##type; }
185
186
187#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
188 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \
189 virtual const char* Mnemonic() const { return mnemonic; } \
190 DECLARE_INSTRUCTION(type)
191
192
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000193class Range: public ZoneObject {
194 public:
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000195 Range()
196 : lower_(kMinInt),
197 upper_(kMaxInt),
198 next_(NULL),
199 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000200
201 Range(int32_t lower, int32_t upper)
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000202 : lower_(lower),
203 upper_(upper),
204 next_(NULL),
205 can_be_minus_zero_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000206
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000207 int32_t upper() const { return upper_; }
208 int32_t lower() const { return lower_; }
209 Range* next() const { return next_; }
210 Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
211 Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212 Range* Copy() const { return new Range(lower_, upper_); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000213 int32_t Mask() const;
214 void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
215 bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
216 bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
217 bool CanBeNegative() const { return lower_ < 0; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000218 bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
219 bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
220 bool IsInSmiRange() const {
221 return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222 }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000223 void KeepOrder();
224 void Verify() const;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000225
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000226 void StackUpon(Range* other) {
227 Intersect(other);
228 next_ = other;
229 }
230
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000231 void Intersect(Range* other);
232 void Union(Range* other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000233
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000234 void AddConstant(int32_t value);
235 void Sar(int32_t value);
236 void Shl(int32_t value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000237 bool AddAndCheckOverflow(Range* other);
238 bool SubAndCheckOverflow(Range* other);
239 bool MulAndCheckOverflow(Range* other);
240
241 private:
242 int32_t lower_;
243 int32_t upper_;
244 Range* next_;
245 bool can_be_minus_zero_;
246};
247
248
249class Representation {
250 public:
251 enum Kind {
252 kNone,
253 kTagged,
254 kDouble,
255 kInteger32,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000256 kExternal,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000257 kNumRepresentations
258 };
259
260 Representation() : kind_(kNone) { }
261
262 static Representation None() { return Representation(kNone); }
263 static Representation Tagged() { return Representation(kTagged); }
264 static Representation Integer32() { return Representation(kInteger32); }
265 static Representation Double() { return Representation(kDouble); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000266 static Representation External() { return Representation(kExternal); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000267
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000268 bool Equals(const Representation& other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000269 return kind_ == other.kind_;
270 }
271
272 Kind kind() const { return kind_; }
273 bool IsNone() const { return kind_ == kNone; }
274 bool IsTagged() const { return kind_ == kTagged; }
275 bool IsInteger32() const { return kind_ == kInteger32; }
276 bool IsDouble() const { return kind_ == kDouble; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000277 bool IsExternal() const { return kind_ == kExternal; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000278 bool IsSpecialization() const {
279 return kind_ == kInteger32 || kind_ == kDouble;
280 }
281 const char* Mnemonic() const;
282
283 private:
284 explicit Representation(Kind k) : kind_(k) { }
285
286 Kind kind_;
287};
288
289
290class HType {
291 public:
292 HType() : type_(kUninitialized) { }
293
294 static HType Tagged() { return HType(kTagged); }
295 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
296 static HType TaggedNumber() { return HType(kTaggedNumber); }
297 static HType Smi() { return HType(kSmi); }
298 static HType HeapNumber() { return HType(kHeapNumber); }
299 static HType String() { return HType(kString); }
300 static HType Boolean() { return HType(kBoolean); }
301 static HType NonPrimitive() { return HType(kNonPrimitive); }
302 static HType JSArray() { return HType(kJSArray); }
303 static HType JSObject() { return HType(kJSObject); }
304 static HType Uninitialized() { return HType(kUninitialized); }
305
306 // Return the weakest (least precise) common type.
307 HType Combine(HType other) {
308 return HType(static_cast<Type>(type_ & other.type_));
309 }
310
311 bool Equals(const HType& other) {
312 return type_ == other.type_;
313 }
314
315 bool IsSubtypeOf(const HType& other) {
316 return Combine(other).Equals(other);
317 }
318
319 bool IsTagged() {
320 ASSERT(type_ != kUninitialized);
321 return ((type_ & kTagged) == kTagged);
322 }
323
324 bool IsTaggedPrimitive() {
325 ASSERT(type_ != kUninitialized);
326 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive);
327 }
328
329 bool IsTaggedNumber() {
330 ASSERT(type_ != kUninitialized);
331 return ((type_ & kTaggedNumber) == kTaggedNumber);
332 }
333
334 bool IsSmi() {
335 ASSERT(type_ != kUninitialized);
336 return ((type_ & kSmi) == kSmi);
337 }
338
339 bool IsHeapNumber() {
340 ASSERT(type_ != kUninitialized);
341 return ((type_ & kHeapNumber) == kHeapNumber);
342 }
343
344 bool IsString() {
345 ASSERT(type_ != kUninitialized);
346 return ((type_ & kString) == kString);
347 }
348
349 bool IsBoolean() {
350 ASSERT(type_ != kUninitialized);
351 return ((type_ & kBoolean) == kBoolean);
352 }
353
354 bool IsNonPrimitive() {
355 ASSERT(type_ != kUninitialized);
356 return ((type_ & kNonPrimitive) == kNonPrimitive);
357 }
358
359 bool IsJSArray() {
360 ASSERT(type_ != kUninitialized);
361 return ((type_ & kJSArray) == kJSArray);
362 }
363
364 bool IsJSObject() {
365 ASSERT(type_ != kUninitialized);
366 return ((type_ & kJSObject) == kJSObject);
367 }
368
369 bool IsUninitialized() {
370 return type_ == kUninitialized;
371 }
372
373 static HType TypeFromValue(Handle<Object> value);
374
375 const char* ToString();
376 const char* ToShortString();
377
378 private:
379 enum Type {
380 kTagged = 0x1, // 0000 0000 0000 0001
381 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101
382 kTaggedNumber = 0xd, // 0000 0000 0000 1101
383 kSmi = 0x1d, // 0000 0000 0001 1101
384 kHeapNumber = 0x2d, // 0000 0000 0010 1101
385 kString = 0x45, // 0000 0000 0100 0101
386 kBoolean = 0x85, // 0000 0000 1000 0101
387 kNonPrimitive = 0x101, // 0000 0001 0000 0001
388 kJSObject = 0x301, // 0000 0011 0000 0001
389 kJSArray = 0x701, // 0000 0111 1000 0001
390 kUninitialized = 0x1fff // 0001 1111 1111 1111
391 };
392
393 explicit HType(Type t) : type_(t) { }
394
395 Type type_;
396};
397
398
399class HValue: public ZoneObject {
400 public:
401 static const int kNoNumber = -1;
402
403 // There must be one corresponding kDepends flag for every kChanges flag and
404 // the order of the kChanges flags must be exactly the same as of the kDepends
405 // flags.
406 enum Flag {
407 // Declare global value numbering flags.
408 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
409 GVN_FLAG_LIST(DECLARE_DO)
410 #undef DECLARE_DO
411 kFlexibleRepresentation,
412 kUseGVN,
413 kCanOverflow,
414 kBailoutOnMinusZero,
415 kCanBeDivByZero,
416 kIsArguments,
417 kTruncatingToInt32,
418 kLastFlag = kTruncatingToInt32
419 };
420
421 STATIC_ASSERT(kLastFlag < kBitsPerInt);
422
423 static const int kChangesToDependsFlagsLeftShift = 1;
424
425 static int ChangesFlagsMask() {
426 int result = 0;
427 // Create changes mask.
428#define DECLARE_DO(type) result |= (1 << kChanges##type);
429 GVN_FLAG_LIST(DECLARE_DO)
430#undef DECLARE_DO
431 return result;
432 }
433
434 static int DependsFlagsMask() {
435 return ConvertChangesToDependsFlags(ChangesFlagsMask());
436 }
437
438 static int ConvertChangesToDependsFlags(int flags) {
439 return flags << kChangesToDependsFlagsLeftShift;
440 }
441
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000442 static HValue* cast(HValue* value) { return value; }
443
444 enum Opcode {
445 // Declare a unique enum value for each hydrogen instruction.
446 #define DECLARE_DO(type) k##type,
447 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
448 #undef DECLARE_DO
449 kMaxInstructionClass
450 };
451
452 HValue() : block_(NULL),
453 id_(kNoNumber),
454 uses_(2),
455 type_(HType::Tagged()),
456 range_(NULL),
457 flags_(0) {}
458 virtual ~HValue() {}
459
460 HBasicBlock* block() const { return block_; }
461 void SetBlock(HBasicBlock* block);
462
463 int id() const { return id_; }
464 void set_id(int id) { id_ = id; }
465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000466 ZoneList<HValue*>* uses() { return &uses_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000467
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000468 virtual bool EmitAtUses() { return false; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000469 Representation representation() const { return representation_; }
470 void ChangeRepresentation(Representation r) {
471 // Representation was already set and is allowed to be changed.
472 ASSERT(!representation_.IsNone());
473 ASSERT(!r.IsNone());
474 ASSERT(CheckFlag(kFlexibleRepresentation));
475 RepresentationChanged(r);
476 representation_ = r;
477 }
478
479 HType type() const { return type_; }
480 void set_type(HType type) {
481 ASSERT(uses_.length() == 0);
482 type_ = type;
483 }
484
485 // An operation needs to override this function iff:
486 // 1) it can produce an int32 output.
487 // 2) the true value of its output can potentially be minus zero.
488 // The implementation must set a flag so that it bails out in the case where
489 // it would otherwise output what should be a minus zero as an int32 zero.
490 // If the operation also exists in a form that takes int32 and outputs int32
491 // then the operation should return its input value so that we can propagate
492 // back. There are two operations that need to propagate back to more than
493 // one input. They are phi and binary add. They always return NULL and
494 // expect the caller to take care of things.
495 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
496 visited->Add(id());
497 return NULL;
498 }
499
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000500 bool IsDefinedAfter(HBasicBlock* other) const;
501
502 // Operands.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000503 virtual int OperandCount() = 0;
504 virtual HValue* OperandAt(int index) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000505 void SetOperandAt(int index, HValue* value);
506
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000507 int LookupOperandIndex(int occurrence_index, HValue* op);
508 bool UsesMultipleTimes(HValue* op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000509
510 void ReplaceAndDelete(HValue* other);
511 void ReplaceValue(HValue* other);
512 void ReplaceAtUse(HValue* use, HValue* other);
513 void ReplaceFirstAtUse(HValue* use, HValue* other, Representation r);
514 bool HasNoUses() const { return uses_.is_empty(); }
515 void ClearOperands();
516 void Delete();
517
518 int flags() const { return flags_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +0000519 void SetFlag(Flag f) { flags_ |= (1 << f); }
520 void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
521 bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
522
523 void SetAllSideEffects() { flags_ |= AllSideEffects(); }
524 void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); }
525 bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000526
527 Range* range() const { return range_; }
528 bool HasRange() const { return range_ != NULL; }
529 void AddNewRange(Range* r);
530 void RemoveLastAddedRange();
531 void ComputeInitialRange();
532
533 // Representation helpers.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000534 virtual Representation RequiredInputRepresentation(int index) const = 0;
535
536 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000537 return representation();
538 }
539
540 // This gives the instruction an opportunity to replace itself with an
541 // instruction that does the same in some better way. To replace an
542 // instruction with a new one, first add the new instruction to the graph,
543 // then return it. Return NULL to have the instruction deleted.
544 virtual HValue* Canonicalize() { return this; }
545
546 // Declare virtual type testers.
547#define DECLARE_DO(type) virtual bool Is##type() const { return false; }
548 HYDROGEN_ALL_INSTRUCTION_LIST(DECLARE_DO)
549#undef DECLARE_DO
550
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000551 bool Equals(HValue* other);
552 virtual intptr_t Hashcode();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000553
554 // Printing support.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000555 virtual void PrintTo(StringStream* stream) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000556 void PrintNameTo(StringStream* stream);
557 static void PrintTypeTo(HType type, StringStream* stream);
558
559 virtual const char* Mnemonic() const = 0;
560 virtual Opcode opcode() const = 0;
561
562 // Updated the inferred type of this instruction and returns true if
563 // it has changed.
564 bool UpdateInferredType();
565
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000566 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000567
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000568#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000569 virtual void Verify() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000570#endif
571
572 protected:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000573 // This function must be overridden for instructions with flag kUseGVN, to
574 // compare the non-Operand parts of the instruction.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000575 virtual bool DataEquals(HValue* other) {
ager@chromium.org378b34e2011-01-28 08:04:38 +0000576 UNREACHABLE();
577 return false;
578 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000579 virtual void RepresentationChanged(Representation to) { }
580 virtual Range* InferRange();
581 virtual void DeleteFromGraph() = 0;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000582 virtual void InternalSetOperandAt(int index, HValue* value) = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000583 void clear_block() {
584 ASSERT(block_ != NULL);
585 block_ = NULL;
586 }
587
588 void set_representation(Representation r) {
589 // Representation is set-once.
590 ASSERT(representation_.IsNone() && !r.IsNone());
591 representation_ = r;
592 }
593
594 private:
ager@chromium.org378b34e2011-01-28 08:04:38 +0000595 // A flag mask to mark an instruction as having arbitrary side effects.
596 static int AllSideEffects() {
597 return ChangesFlagsMask() & ~(1 << kChangesOsrEntries);
598 }
599
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000600 void InternalReplaceAtUse(HValue* use, HValue* other);
601 void RegisterUse(int index, HValue* new_value);
602
603 HBasicBlock* block_;
604
605 // The id of this instruction in the hydrogen graph, assigned when first
606 // added to the graph. Reflects creation order.
607 int id_;
608
609 Representation representation_;
610 ZoneList<HValue*> uses_;
611 HType type_;
612 Range* range_;
613 int flags_;
614
615 DISALLOW_COPY_AND_ASSIGN(HValue);
616};
617
618
619class HInstruction: public HValue {
620 public:
621 HInstruction* next() const { return next_; }
622 HInstruction* previous() const { return previous_; }
623
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000624 virtual void PrintTo(StringStream* stream);
625 virtual void PrintDataTo(StringStream* stream) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000626
627 bool IsLinked() const { return block() != NULL; }
628 void Unlink();
629 void InsertBefore(HInstruction* next);
630 void InsertAfter(HInstruction* previous);
631
632 int position() const { return position_; }
633 bool has_position() const { return position_ != RelocInfo::kNoPosition; }
634 void set_position(int position) { position_ = position; }
635
636 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
637
638#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +0000639 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000640#endif
641
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000642 // Returns whether this is some kind of deoptimizing check
643 // instruction.
644 virtual bool IsCheckInstruction() const { return false; }
645
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000646 virtual bool IsCall() { return false; }
647
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000648 DECLARE_INSTRUCTION(Instruction)
649
650 protected:
651 HInstruction()
652 : next_(NULL),
653 previous_(NULL),
654 position_(RelocInfo::kNoPosition) {
655 SetFlag(kDependsOnOsrEntries);
656 }
657
658 virtual void DeleteFromGraph() { Unlink(); }
659
660 private:
661 void InitializeAsFirst(HBasicBlock* block) {
662 ASSERT(!IsLinked());
663 SetBlock(block);
664 }
665
666 HInstruction* next_;
667 HInstruction* previous_;
668 int position_;
669
670 friend class HBasicBlock;
671};
672
673
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000674class HControlInstruction: public HInstruction {
675 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000676 HControlInstruction(HBasicBlock* first, HBasicBlock* second)
677 : first_successor_(first), second_successor_(second) {
678 }
679
680 HBasicBlock* FirstSuccessor() const { return first_successor_; }
681 HBasicBlock* SecondSuccessor() const { return second_successor_; }
682
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000683 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000684
685 DECLARE_INSTRUCTION(ControlInstruction)
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000686
687 private:
688 HBasicBlock* first_successor_;
689 HBasicBlock* second_successor_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000690};
691
692
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000693template<int NumElements>
694class HOperandContainer {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000695 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000696 HOperandContainer() : elems_() { }
697
698 int length() { return NumElements; }
699 HValue*& operator[](int i) {
700 ASSERT(i < length());
701 return elems_[i];
702 }
703
704 private:
705 HValue* elems_[NumElements];
706};
707
708
709template<>
710class HOperandContainer<0> {
711 public:
712 int length() { return 0; }
713 HValue*& operator[](int i) {
714 UNREACHABLE();
715 static HValue* t = 0;
716 return t;
717 }
718};
719
720
721template<int V>
722class HTemplateInstruction : public HInstruction {
723 public:
724 int OperandCount() { return V; }
725 HValue* OperandAt(int i) { return inputs_[i]; }
726
727 protected:
728 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
729
730 private:
731 HOperandContainer<V> inputs_;
732};
733
734
735template<int V>
736class HTemplateControlInstruction : public HControlInstruction {
737 public:
738 HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
739 : HControlInstruction(first, second) { }
740 int OperandCount() { return V; }
741 HValue* OperandAt(int i) { return inputs_[i]; }
742
743 protected:
744 void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
745
746 private:
747 HOperandContainer<V> inputs_;
748};
749
750
751class HBlockEntry: public HTemplateInstruction<0> {
752 public:
753 virtual Representation RequiredInputRepresentation(int index) const {
754 return Representation::None();
755 }
756
757 DECLARE_CONCRETE_INSTRUCTION(BlockEntry, "block_entry")
758};
759
760
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761class HDeoptimize: public HControlInstruction {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000762 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000763 explicit HDeoptimize(int environment_length)
764 : HControlInstruction(NULL, NULL),
765 values_(environment_length) { }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000766
767 virtual Representation RequiredInputRepresentation(int index) const {
768 return Representation::None();
769 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000770
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 virtual int OperandCount() { return values_.length(); }
772 virtual HValue* OperandAt(int index) { return values_[index]; }
773
774 void AddEnvironmentValue(HValue* value) {
775 values_.Add(NULL);
776 SetOperandAt(values_.length() - 1, value);
777 }
778
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000779 DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000780
781 protected:
782 virtual void InternalSetOperandAt(int index, HValue* value) {
783 values_[index] = value;
784 }
785
786 private:
787 ZoneList<HValue*> values_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000788};
789
790
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000791class HGoto: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000792 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000793 explicit HGoto(HBasicBlock* target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000794 : HTemplateControlInstruction<0>(target, NULL),
795 include_stack_check_(false) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000796
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000797 void set_include_stack_check(bool include_stack_check) {
798 include_stack_check_ = include_stack_check;
799 }
800 bool include_stack_check() const { return include_stack_check_; }
801
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000802 virtual Representation RequiredInputRepresentation(int index) const {
803 return Representation::None();
804 }
805
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000806 DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
807
808 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000809 bool include_stack_check_;
810};
811
812
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000813class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000814 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000815 explicit HUnaryControlInstruction(HValue* value,
816 HBasicBlock* true_target,
817 HBasicBlock* false_target)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000818 : HTemplateControlInstruction<1>(true_target, false_target) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000819 SetOperandAt(0, value);
820 }
821
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000822 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000823
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000824 HValue* value() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000825
826 DECLARE_INSTRUCTION(UnaryControlInstruction)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000827};
828
829
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000830class HTest: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000831 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000832 HTest(HValue* value, HBasicBlock* true_target, HBasicBlock* false_target)
833 : HUnaryControlInstruction(value, true_target, false_target) {
834 ASSERT(true_target != NULL && false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000835 }
836
837 virtual Representation RequiredInputRepresentation(int index) const {
838 return Representation::None();
839 }
840
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000841 DECLARE_CONCRETE_INSTRUCTION(Test, "test")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000842};
843
844
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000845class HCompareMap: public HUnaryControlInstruction {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000846 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000847 HCompareMap(HValue* value,
848 Handle<Map> map,
849 HBasicBlock* true_target,
850 HBasicBlock* false_target)
851 : HUnaryControlInstruction(value, true_target, false_target),
852 map_(map) {
853 ASSERT(true_target != NULL);
854 ASSERT(false_target != NULL);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000855 ASSERT(!map.is_null());
856 }
857
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000858 virtual void PrintDataTo(StringStream* stream);
whesse@chromium.org023421e2010-12-21 12:19:12 +0000859
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000860 Handle<Map> map() const { return map_; }
861
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000862 virtual Representation RequiredInputRepresentation(int index) const {
863 return Representation::Tagged();
864 }
865
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000866 DECLARE_CONCRETE_INSTRUCTION(CompareMap, "compare_map")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000867
868 private:
869 Handle<Map> map_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000870};
871
872
873class HReturn: public HUnaryControlInstruction {
874 public:
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000875 explicit HReturn(HValue* value)
876 : HUnaryControlInstruction(value, NULL, NULL) {
877 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000878
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000879 virtual Representation RequiredInputRepresentation(int index) const {
880 return Representation::Tagged();
881 }
882
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000883 DECLARE_CONCRETE_INSTRUCTION(Return, "return")
884};
885
886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000887class HAbnormalExit: public HTemplateControlInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000888 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000889 HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
890
891 virtual Representation RequiredInputRepresentation(int index) const {
892 return Representation::None();
893 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000894
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000895 DECLARE_CONCRETE_INSTRUCTION(AbnormalExit, "abnormal_exit")
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000896};
897
898
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000899class HUnaryOperation: public HTemplateInstruction<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000900 public:
901 explicit HUnaryOperation(HValue* value) {
902 SetOperandAt(0, value);
903 }
904
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000905 HValue* value() { return OperandAt(0); }
906 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000907
908 DECLARE_INSTRUCTION(UnaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000909};
910
911
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000912class HThrow: public HUnaryOperation {
913 public:
914 explicit HThrow(HValue* value) : HUnaryOperation(value) {
915 SetAllSideEffects();
916 }
917
918 virtual Representation RequiredInputRepresentation(int index) const {
919 return Representation::Tagged();
920 }
921
922 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
923};
924
925
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000926class HChange: public HUnaryOperation {
927 public:
928 HChange(HValue* value,
929 Representation from,
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000930 Representation to,
931 bool is_truncating)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000932 : HUnaryOperation(value), from_(from), to_(to) {
933 ASSERT(!from.IsNone() && !to.IsNone());
934 ASSERT(!from.Equals(to));
935 set_representation(to);
936 SetFlag(kUseGVN);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000937 if (is_truncating) SetFlag(kTruncatingToInt32);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000938 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
939 value->range()->IsInSmiRange()) {
940 set_type(HType::Smi());
941 }
942 }
943
944 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
945
946 Representation from() const { return from_; }
947 Representation to() const { return to_; }
948 virtual Representation RequiredInputRepresentation(int index) const {
949 return from_;
950 }
951
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000952 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000953
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000954 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000955
956 DECLARE_CONCRETE_INSTRUCTION(Change,
957 CanTruncateToInt32() ? "truncate" : "change")
958
959 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000960 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000961 if (!other->IsChange()) return false;
962 HChange* change = HChange::cast(other);
963 return value() == change->value()
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000964 && to().Equals(change->to());
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000965 }
966
967 private:
968 Representation from_;
969 Representation to_;
970};
971
972
973class HSimulate: public HInstruction {
974 public:
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000975 HSimulate(int ast_id, int pop_count, int environment_length)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000976 : ast_id_(ast_id),
977 pop_count_(pop_count),
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000978 environment_length_(environment_length),
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000979 values_(2),
980 assigned_indexes_(2) {}
981 virtual ~HSimulate() {}
982
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000983 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000984
985 bool HasAstId() const { return ast_id_ != AstNode::kNoNumber; }
986 int ast_id() const { return ast_id_; }
987 void set_ast_id(int id) {
988 ASSERT(!HasAstId());
989 ast_id_ = id;
990 }
991
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000992 int environment_length() const { return environment_length_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000993 int pop_count() const { return pop_count_; }
994 const ZoneList<HValue*>* values() const { return &values_; }
995 int GetAssignedIndexAt(int index) const {
996 ASSERT(HasAssignedIndexAt(index));
997 return assigned_indexes_[index];
998 }
999 bool HasAssignedIndexAt(int index) const {
1000 return assigned_indexes_[index] != kNoIndex;
1001 }
1002 void AddAssignedValue(int index, HValue* value) {
1003 AddValue(index, value);
1004 }
1005 void AddPushedValue(HValue* value) {
1006 AddValue(kNoIndex, value);
1007 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001008 virtual int OperandCount() { return values_.length(); }
1009 virtual HValue* OperandAt(int index) { return values_[index]; }
1010
1011 virtual Representation RequiredInputRepresentation(int index) const {
1012 return Representation::None();
1013 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001014
1015 DECLARE_CONCRETE_INSTRUCTION(Simulate, "simulate")
1016
1017#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001018 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001019#endif
1020
1021 protected:
1022 virtual void InternalSetOperandAt(int index, HValue* value) {
1023 values_[index] = value;
1024 }
1025
1026 private:
1027 static const int kNoIndex = -1;
1028 void AddValue(int index, HValue* value) {
1029 assigned_indexes_.Add(index);
1030 // Resize the list of pushed values.
1031 values_.Add(NULL);
1032 // Set the operand through the base method in HValue to make sure that the
1033 // use lists are correctly updated.
1034 SetOperandAt(values_.length() - 1, value);
1035 }
1036 int ast_id_;
1037 int pop_count_;
lrn@chromium.org5d00b602011-01-05 09:51:43 +00001038 int environment_length_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001039 ZoneList<HValue*> values_;
1040 ZoneList<int> assigned_indexes_;
1041};
1042
1043
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001044class HStackCheck: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001045 public:
1046 HStackCheck() { }
1047
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001048 virtual Representation RequiredInputRepresentation(int index) const {
1049 return Representation::None();
1050 }
1051
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001052 DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack_check")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001053};
1054
1055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001056class HEnterInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001057 public:
1058 HEnterInlined(Handle<JSFunction> closure, FunctionLiteral* function)
1059 : closure_(closure), function_(function) {
1060 }
1061
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001062 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001063
1064 Handle<JSFunction> closure() const { return closure_; }
1065 FunctionLiteral* function() const { return function_; }
1066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001067 virtual Representation RequiredInputRepresentation(int index) const {
1068 return Representation::None();
1069 }
1070
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001071 DECLARE_CONCRETE_INSTRUCTION(EnterInlined, "enter_inlined")
1072
1073 private:
1074 Handle<JSFunction> closure_;
1075 FunctionLiteral* function_;
1076};
1077
1078
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001079class HLeaveInlined: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001080 public:
1081 HLeaveInlined() {}
1082
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001083 virtual Representation RequiredInputRepresentation(int index) const {
1084 return Representation::None();
1085 }
1086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001087 DECLARE_CONCRETE_INSTRUCTION(LeaveInlined, "leave_inlined")
1088};
1089
1090
1091class HPushArgument: public HUnaryOperation {
1092 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001093 explicit HPushArgument(HValue* value) : HUnaryOperation(value) {
1094 set_representation(Representation::Tagged());
1095 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001096
1097 virtual Representation RequiredInputRepresentation(int index) const {
1098 return Representation::Tagged();
1099 }
1100
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001101 HValue* argument() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001102
1103 DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push_argument")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001104};
1105
1106
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001107class HContext: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001108 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001109 HContext() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001110 set_representation(Representation::Tagged());
1111 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001112 }
1113
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001114 virtual Representation RequiredInputRepresentation(int index) const {
1115 return Representation::None();
1116 }
1117
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001118 DECLARE_CONCRETE_INSTRUCTION(Context, "context");
1119
1120 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001121 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001122};
1123
1124
1125class HOuterContext: public HUnaryOperation {
1126 public:
1127 explicit HOuterContext(HValue* inner) : HUnaryOperation(inner) {
1128 set_representation(Representation::Tagged());
1129 SetFlag(kUseGVN);
1130 }
1131
1132 DECLARE_CONCRETE_INSTRUCTION(OuterContext, "outer_context");
1133
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001134 virtual Representation RequiredInputRepresentation(int index) const {
1135 return Representation::Tagged();
1136 }
1137
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001138 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001139 virtual bool DataEquals(HValue* other) { return true; }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001140};
1141
1142
1143class HGlobalObject: public HUnaryOperation {
1144 public:
1145 explicit HGlobalObject(HValue* context) : HUnaryOperation(context) {
1146 set_representation(Representation::Tagged());
1147 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001148 }
1149
1150 DECLARE_CONCRETE_INSTRUCTION(GlobalObject, "global_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001151
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001152 virtual Representation RequiredInputRepresentation(int index) const {
1153 return Representation::Tagged();
1154 }
1155
ager@chromium.org378b34e2011-01-28 08:04:38 +00001156 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001157 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001158};
1159
1160
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001161class HGlobalReceiver: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001162 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00001163 explicit HGlobalReceiver(HValue* global_object)
1164 : HUnaryOperation(global_object) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001165 set_representation(Representation::Tagged());
1166 SetFlag(kUseGVN);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001167 }
1168
1169 DECLARE_CONCRETE_INSTRUCTION(GlobalReceiver, "global_receiver")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001170
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001171 virtual Representation RequiredInputRepresentation(int index) const {
1172 return Representation::Tagged();
1173 }
1174
ager@chromium.org378b34e2011-01-28 08:04:38 +00001175 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001176 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001177};
1178
1179
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001180template <int V>
1181class HCall: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001182 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001183 // The argument count includes the receiver.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001184 explicit HCall<V>(int argument_count) : argument_count_(argument_count) {
1185 this->set_representation(Representation::Tagged());
1186 this->SetAllSideEffects();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001187 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001188
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001189 virtual HType CalculateInferredType() { return HType::Tagged(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001190
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001191 virtual int argument_count() const { return argument_count_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001193 virtual bool IsCall() { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001194
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001195 private:
1196 int argument_count_;
1197};
1198
1199
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001200class HUnaryCall: public HCall<1> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001201 public:
1202 HUnaryCall(HValue* value, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001203 : HCall<1>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001204 SetOperandAt(0, value);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001205 }
1206
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001207 virtual Representation RequiredInputRepresentation(int index) const {
1208 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001209 }
1210
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001211 virtual void PrintDataTo(StringStream* stream);
1212
1213 HValue* value() { return OperandAt(0); }
1214
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001215 DECLARE_INSTRUCTION(UnaryCall)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001216};
1217
1218
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001219class HBinaryCall: public HCall<2> {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001220 public:
1221 HBinaryCall(HValue* first, HValue* second, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001222 : HCall<2>(argument_count) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001223 SetOperandAt(0, first);
1224 SetOperandAt(1, second);
1225 }
1226
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001227 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001228
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001229 virtual Representation RequiredInputRepresentation(int index) const {
1230 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001231 }
1232
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001233 HValue* first() { return OperandAt(0); }
1234 HValue* second() { return OperandAt(1); }
1235
1236 DECLARE_INSTRUCTION(BinaryCall)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001237};
1238
1239
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001240class HCallConstantFunction: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001241 public:
1242 HCallConstantFunction(Handle<JSFunction> function, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001243 : HCall<0>(argument_count), function_(function) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001244
1245 Handle<JSFunction> function() const { return function_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001246
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001247 bool IsApplyFunction() const {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001248 return function_->code() ==
1249 Isolate::Current()->builtins()->builtin(Builtins::FunctionApply);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001250 }
1251
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001252 virtual void PrintDataTo(StringStream* stream);
1253
1254 virtual Representation RequiredInputRepresentation(int index) const {
1255 return Representation::None();
1256 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001257
1258 DECLARE_CONCRETE_INSTRUCTION(CallConstantFunction, "call_constant_function")
1259
1260 private:
1261 Handle<JSFunction> function_;
1262};
1263
1264
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001265class HCallKeyed: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001266 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001267 HCallKeyed(HValue* context, HValue* key, int argument_count)
1268 : HBinaryCall(context, key, argument_count) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001269 }
1270
1271 virtual Representation RequiredInputRepresentation(int index) const {
1272 return Representation::Tagged();
1273 }
1274
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001275 HValue* context() { return first(); }
1276 HValue* key() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001277
1278 DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call_keyed")
1279};
1280
1281
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001282class HCallNamed: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001283 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001284 HCallNamed(HValue* context, Handle<String> name, int argument_count)
1285 : HUnaryCall(context, argument_count), name_(name) {
1286 }
1287
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001288 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001289
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001290 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001291 Handle<String> name() const { return name_; }
1292
1293 DECLARE_CONCRETE_INSTRUCTION(CallNamed, "call_named")
1294
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001295 virtual Representation RequiredInputRepresentation(int index) const {
1296 return Representation::Tagged();
1297 }
1298
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001299 private:
1300 Handle<String> name_;
1301};
1302
1303
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001304class HCallFunction: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001305 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001306 HCallFunction(HValue* context, int argument_count)
1307 : HUnaryCall(context, argument_count) {
1308 }
1309
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001310 HValue* context() { return value(); }
1311
1312 virtual Representation RequiredInputRepresentation(int index) const {
1313 return Representation::Tagged();
1314 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001315
1316 DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call_function")
1317};
1318
1319
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001320class HCallGlobal: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001321 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001322 HCallGlobal(HValue* context, Handle<String> name, int argument_count)
1323 : HUnaryCall(context, argument_count), name_(name) {
1324 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001325
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001326 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001327
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001328 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001329 Handle<String> name() const { return name_; }
1330
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001331 virtual Representation RequiredInputRepresentation(int index) const {
1332 return Representation::Tagged();
1333 }
1334
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001335 DECLARE_CONCRETE_INSTRUCTION(CallGlobal, "call_global")
1336
1337 private:
1338 Handle<String> name_;
1339};
1340
1341
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001342class HCallKnownGlobal: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001343 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001344 HCallKnownGlobal(Handle<JSFunction> target, int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001345 : HCall<0>(argument_count), target_(target) { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001346
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001347 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001348
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001349 Handle<JSFunction> target() const { return target_; }
1350
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001351 virtual Representation RequiredInputRepresentation(int index) const {
1352 return Representation::None();
1353 }
1354
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001355 DECLARE_CONCRETE_INSTRUCTION(CallKnownGlobal, "call_known_global")
1356
1357 private:
1358 Handle<JSFunction> target_;
1359};
1360
1361
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001362class HCallNew: public HBinaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001363 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001364 HCallNew(HValue* context, HValue* constructor, int argument_count)
1365 : HBinaryCall(context, constructor, argument_count) {
1366 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001367
1368 virtual Representation RequiredInputRepresentation(int index) const {
1369 return Representation::Tagged();
1370 }
1371
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001372 HValue* context() { return first(); }
1373 HValue* constructor() { return second(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001374
1375 DECLARE_CONCRETE_INSTRUCTION(CallNew, "call_new")
1376};
1377
1378
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001379class HCallRuntime: public HCall<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001380 public:
1381 HCallRuntime(Handle<String> name,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001382 const Runtime::Function* c_function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001383 int argument_count)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001384 : HCall<0>(argument_count), c_function_(c_function), name_(name) { }
1385 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001386
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001387 const Runtime::Function* function() const { return c_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001388 Handle<String> name() const { return name_; }
1389
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001390 virtual Representation RequiredInputRepresentation(int index) const {
1391 return Representation::None();
1392 }
1393
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001394 DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call_runtime")
1395
1396 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001397 const Runtime::Function* c_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001398 Handle<String> name_;
1399};
1400
1401
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001402class HJSArrayLength: public HUnaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001403 public:
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001404 explicit HJSArrayLength(HValue* value) : HUnaryOperation(value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001405 // The length of an array is stored as a tagged value in the array
1406 // object. It is guaranteed to be 32 bit integer, but it can be
1407 // represented as either a smi or heap number.
1408 set_representation(Representation::Tagged());
1409 SetFlag(kDependsOnArrayLengths);
1410 SetFlag(kUseGVN);
1411 }
1412
1413 virtual Representation RequiredInputRepresentation(int index) const {
1414 return Representation::Tagged();
1415 }
1416
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001417 DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001418
1419 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001420 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001421};
1422
1423
1424class HFixedArrayLength: public HUnaryOperation {
1425 public:
1426 explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
1427 set_representation(Representation::Tagged());
1428 SetFlag(kDependsOnArrayLengths);
1429 SetFlag(kUseGVN);
1430 }
1431
1432 virtual Representation RequiredInputRepresentation(int index) const {
1433 return Representation::Tagged();
1434 }
1435
1436 DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed_array_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001437
1438 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001439 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001440};
1441
1442
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001443class HExternalArrayLength: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001444 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001445 explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001446 set_representation(Representation::Integer32());
1447 // The result of this instruction is idempotent as long as its inputs don't
1448 // change. The length of a pixel array cannot change once set, so it's not
1449 // necessary to introduce a kDependsOnArrayLengths or any other dependency.
1450 SetFlag(kUseGVN);
1451 }
1452
1453 virtual Representation RequiredInputRepresentation(int index) const {
1454 return Representation::Tagged();
1455 }
1456
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001457 DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external_array_length")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001458
1459 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001460 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001461};
1462
1463
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001464class HBitNot: public HUnaryOperation {
1465 public:
1466 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1467 set_representation(Representation::Integer32());
1468 SetFlag(kUseGVN);
1469 SetFlag(kTruncatingToInt32);
1470 }
1471
1472 virtual Representation RequiredInputRepresentation(int index) const {
1473 return Representation::Integer32();
1474 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001475 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001476
1477 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001478
1479 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001480 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001481};
1482
1483
1484class HUnaryMathOperation: public HUnaryOperation {
1485 public:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001486 HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001487 : HUnaryOperation(value), op_(op) {
1488 switch (op) {
1489 case kMathFloor:
1490 case kMathRound:
1491 case kMathCeil:
1492 set_representation(Representation::Integer32());
1493 break;
1494 case kMathAbs:
1495 set_representation(Representation::Tagged());
1496 SetFlag(kFlexibleRepresentation);
1497 break;
1498 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001499 case kMathPowHalf:
1500 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001501 case kMathSin:
1502 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001503 set_representation(Representation::Double());
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001504 break;
1505 default:
1506 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001507 }
1508 SetFlag(kUseGVN);
1509 }
1510
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001511 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001512
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001513 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001514
1515 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
1516
1517 virtual Representation RequiredInputRepresentation(int index) const {
1518 switch (op_) {
1519 case kMathFloor:
1520 case kMathRound:
1521 case kMathCeil:
1522 case kMathSqrt:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001523 case kMathPowHalf:
1524 case kMathLog:
whesse@chromium.org023421e2010-12-21 12:19:12 +00001525 case kMathSin:
1526 case kMathCos:
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001527 return Representation::Double();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001528 case kMathAbs:
1529 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001530 default:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001531 UNREACHABLE();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001532 return Representation::None();
1533 }
1534 }
1535
1536 virtual HValue* Canonicalize() {
1537 // If the input is integer32 then we replace the floor instruction
1538 // with its inputs. This happens before the representation changes are
1539 // introduced.
1540 if (op() == kMathFloor) {
1541 if (value()->representation().IsInteger32()) return value();
1542 }
1543 return this;
1544 }
1545
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001546 BuiltinFunctionId op() const { return op_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001547 const char* OpName() const;
1548
1549 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1550
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001551 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001552 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001553 HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
1554 return op_ == b->op();
1555 }
1556
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001557 private:
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00001558 BuiltinFunctionId op_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001559};
1560
1561
1562class HLoadElements: public HUnaryOperation {
1563 public:
1564 explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
1565 set_representation(Representation::Tagged());
1566 SetFlag(kUseGVN);
1567 SetFlag(kDependsOnMaps);
1568 }
1569
1570 virtual Representation RequiredInputRepresentation(int index) const {
1571 return Representation::Tagged();
1572 }
1573
1574 DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001575
1576 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001577 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001578};
1579
1580
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001581class HLoadExternalArrayPointer: public HUnaryOperation {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001582 public:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001583 explicit HLoadExternalArrayPointer(HValue* value)
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001584 : HUnaryOperation(value) {
1585 set_representation(Representation::External());
1586 // The result of this instruction is idempotent as long as its inputs don't
1587 // change. The external array of a pixel array elements object cannot
1588 // change once set, so it's no necessary to introduce any additional
1589 // dependencies on top of the inputs.
1590 SetFlag(kUseGVN);
1591 }
1592
1593 virtual Representation RequiredInputRepresentation(int index) const {
1594 return Representation::Tagged();
1595 }
1596
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001597 DECLARE_CONCRETE_INSTRUCTION(LoadExternalArrayPointer,
1598 "load-external-array-pointer")
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001599
1600 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001601 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00001602};
1603
1604
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001605class HCheckMap: public HUnaryOperation {
1606 public:
1607 HCheckMap(HValue* value, Handle<Map> map)
1608 : HUnaryOperation(value), map_(map) {
1609 set_representation(Representation::Tagged());
1610 SetFlag(kUseGVN);
1611 SetFlag(kDependsOnMaps);
1612 }
1613
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001614 virtual bool IsCheckInstruction() const { return true; }
1615
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001616 virtual Representation RequiredInputRepresentation(int index) const {
1617 return Representation::Tagged();
1618 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001619 virtual void PrintDataTo(StringStream* stream);
1620 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001621
1622#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001623 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001624#endif
1625
1626 Handle<Map> map() const { return map_; }
1627
1628 DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check_map")
1629
1630 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001631 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001632 HCheckMap* b = HCheckMap::cast(other);
1633 return map_.is_identical_to(b->map());
1634 }
1635
1636 private:
1637 Handle<Map> map_;
1638};
1639
1640
1641class HCheckFunction: public HUnaryOperation {
1642 public:
1643 HCheckFunction(HValue* value, Handle<JSFunction> function)
1644 : HUnaryOperation(value), target_(function) {
1645 set_representation(Representation::Tagged());
1646 SetFlag(kUseGVN);
1647 }
1648
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001649 virtual bool IsCheckInstruction() const { return true; }
1650
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001651 virtual Representation RequiredInputRepresentation(int index) const {
1652 return Representation::Tagged();
1653 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001654 virtual void PrintDataTo(StringStream* stream);
1655 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001656
1657#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001658 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001659#endif
1660
1661 Handle<JSFunction> target() const { return target_; }
1662
1663 DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check_function")
1664
1665 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001666 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001667 HCheckFunction* b = HCheckFunction::cast(other);
1668 return target_.is_identical_to(b->target());
1669 }
1670
1671 private:
1672 Handle<JSFunction> target_;
1673};
1674
1675
1676class HCheckInstanceType: public HUnaryOperation {
1677 public:
1678 // Check that the instance type is in the range [first, last] where
1679 // both first and last are included.
1680 HCheckInstanceType(HValue* value, InstanceType first, InstanceType last)
1681 : HUnaryOperation(value), first_(first), last_(last) {
1682 ASSERT(first <= last);
1683 set_representation(Representation::Tagged());
1684 SetFlag(kUseGVN);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00001685 if ((FIRST_STRING_TYPE < first && last <= LAST_STRING_TYPE) ||
1686 (FIRST_STRING_TYPE <= first && last < LAST_STRING_TYPE)) {
1687 // A particular string instance type can change because of GC or
1688 // externalization, but the value still remains a string.
1689 SetFlag(kDependsOnMaps);
1690 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001691 }
1692
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001693 virtual bool IsCheckInstruction() const { return true; }
1694
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001695 virtual Representation RequiredInputRepresentation(int index) const {
1696 return Representation::Tagged();
1697 }
1698
1699#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001700 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001701#endif
1702
1703 static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value);
1704
1705 InstanceType first() const { return first_; }
1706 InstanceType last() const { return last_; }
1707
1708 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check_instance_type")
1709
1710 protected:
1711 // TODO(ager): It could be nice to allow the ommision of instance
1712 // type checks if we have already performed an instance type check
1713 // with a larger range.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001714 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001715 HCheckInstanceType* b = HCheckInstanceType::cast(other);
1716 return (first_ == b->first()) && (last_ == b->last());
1717 }
1718
1719 private:
1720 InstanceType first_;
1721 InstanceType last_;
1722};
1723
1724
1725class HCheckNonSmi: public HUnaryOperation {
1726 public:
1727 explicit HCheckNonSmi(HValue* value) : HUnaryOperation(value) {
1728 set_representation(Representation::Tagged());
1729 SetFlag(kUseGVN);
1730 }
1731
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001732 virtual bool IsCheckInstruction() const { return true; }
1733
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001734 virtual Representation RequiredInputRepresentation(int index) const {
1735 return Representation::Tagged();
1736 }
1737
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001738 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001739
1740#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001741 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001742#endif
1743
1744 DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check_non_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001745
1746 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001747 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001748};
1749
1750
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001751class HCheckPrototypeMaps: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001752 public:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001753 HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
1754 : prototype_(prototype), holder_(holder) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001755 SetFlag(kUseGVN);
1756 SetFlag(kDependsOnMaps);
1757 }
1758
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001759 virtual bool IsCheckInstruction() const { return true; }
1760
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001761#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001762 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001763#endif
1764
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001765 Handle<JSObject> prototype() const { return prototype_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001766 Handle<JSObject> holder() const { return holder_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001767
1768 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check_prototype_maps")
1769
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001770 virtual Representation RequiredInputRepresentation(int index) const {
1771 return Representation::None();
1772 }
1773
1774 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001775 ASSERT(!HEAP->IsAllocationAllowed());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001776 intptr_t hash = reinterpret_cast<intptr_t>(*prototype());
1777 hash = 17 * hash + reinterpret_cast<intptr_t>(*holder());
1778 return hash;
1779 }
1780
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001781 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001782 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001783 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001784 return prototype_.is_identical_to(b->prototype()) &&
1785 holder_.is_identical_to(b->holder());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001786 }
1787
1788 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00001789 Handle<JSObject> prototype_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001790 Handle<JSObject> holder_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001791};
1792
1793
1794class HCheckSmi: public HUnaryOperation {
1795 public:
1796 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) {
1797 set_representation(Representation::Tagged());
1798 SetFlag(kUseGVN);
1799 }
1800
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00001801 virtual bool IsCheckInstruction() const { return true; }
1802
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001803 virtual Representation RequiredInputRepresentation(int index) const {
1804 return Representation::Tagged();
1805 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001806 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001807
1808#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001809 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001810#endif
1811
1812 DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00001813
1814 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001815 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001816};
1817
1818
1819class HPhi: public HValue {
1820 public:
1821 explicit HPhi(int merged_index)
1822 : inputs_(2),
1823 merged_index_(merged_index),
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001824 phi_id_(-1),
1825 is_live_(false) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001826 for (int i = 0; i < Representation::kNumRepresentations; i++) {
1827 non_phi_uses_[i] = 0;
1828 indirect_uses_[i] = 0;
1829 }
1830 ASSERT(merged_index >= 0);
1831 set_representation(Representation::Tagged());
1832 SetFlag(kFlexibleRepresentation);
1833 }
1834
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001835 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001836 bool double_occurred = false;
1837 bool int32_occurred = false;
1838 for (int i = 0; i < OperandCount(); ++i) {
1839 HValue* value = OperandAt(i);
1840 if (value->representation().IsDouble()) double_occurred = true;
1841 if (value->representation().IsInteger32()) int32_occurred = true;
1842 if (value->representation().IsTagged()) return Representation::Tagged();
1843 }
1844
1845 if (double_occurred) return Representation::Double();
1846 if (int32_occurred) return Representation::Integer32();
1847 return Representation::None();
1848 }
1849
1850 virtual Range* InferRange();
1851 virtual Representation RequiredInputRepresentation(int index) const {
1852 return representation();
1853 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001854 virtual HType CalculateInferredType();
1855 virtual int OperandCount() { return inputs_.length(); }
1856 virtual HValue* OperandAt(int index) { return inputs_[index]; }
1857 HValue* GetRedundantReplacement();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001858 void AddInput(HValue* value);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001859 bool HasRealUses();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001860
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00001861 bool IsReceiver() { return merged_index_ == 0; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862
1863 int merged_index() const { return merged_index_; }
1864
1865 virtual const char* Mnemonic() const { return "phi"; }
1866
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001867 virtual void PrintTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001868
1869#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001870 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001871#endif
1872
1873 DECLARE_INSTRUCTION(Phi)
1874
1875 void InitRealUses(int id);
1876 void AddNonPhiUsesFrom(HPhi* other);
1877 void AddIndirectUsesTo(int* use_count);
1878
1879 int tagged_non_phi_uses() const {
1880 return non_phi_uses_[Representation::kTagged];
1881 }
1882 int int32_non_phi_uses() const {
1883 return non_phi_uses_[Representation::kInteger32];
1884 }
1885 int double_non_phi_uses() const {
1886 return non_phi_uses_[Representation::kDouble];
1887 }
1888 int tagged_indirect_uses() const {
1889 return indirect_uses_[Representation::kTagged];
1890 }
1891 int int32_indirect_uses() const {
1892 return indirect_uses_[Representation::kInteger32];
1893 }
1894 int double_indirect_uses() const {
1895 return indirect_uses_[Representation::kDouble];
1896 }
1897 int phi_id() { return phi_id_; }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001898 bool is_live() { return is_live_; }
1899 void set_is_live(bool b) { is_live_ = b; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001900
1901 protected:
1902 virtual void DeleteFromGraph();
1903 virtual void InternalSetOperandAt(int index, HValue* value) {
1904 inputs_[index] = value;
1905 }
1906
1907 private:
1908 ZoneList<HValue*> inputs_;
1909 int merged_index_;
1910
1911 int non_phi_uses_[Representation::kNumRepresentations];
1912 int indirect_uses_[Representation::kNumRepresentations];
1913 int phi_id_;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001914 bool is_live_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001915};
1916
1917
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001918class HArgumentsObject: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001919 public:
1920 HArgumentsObject() {
1921 set_representation(Representation::Tagged());
1922 SetFlag(kIsArguments);
1923 }
1924
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001925 virtual Representation RequiredInputRepresentation(int index) const {
1926 return Representation::None();
1927 }
1928
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001929 DECLARE_CONCRETE_INSTRUCTION(ArgumentsObject, "arguments-object")
1930};
1931
1932
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001933class HConstant: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001934 public:
1935 HConstant(Handle<Object> handle, Representation r);
1936
1937 Handle<Object> handle() const { return handle_; }
1938
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001939 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00001940
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001941 virtual Representation RequiredInputRepresentation(int index) const {
1942 return Representation::None();
1943 }
1944
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001945 virtual bool EmitAtUses() { return !representation().IsDouble(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001946 virtual void PrintDataTo(StringStream* stream);
1947 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001948 bool IsInteger() const { return handle_->IsSmi(); }
1949 HConstant* CopyToRepresentation(Representation r) const;
1950 HConstant* CopyToTruncatedInt32() const;
1951 bool HasInteger32Value() const { return has_int32_value_; }
1952 int32_t Integer32Value() const {
1953 ASSERT(HasInteger32Value());
1954 return int32_value_;
1955 }
1956 bool HasDoubleValue() const { return has_double_value_; }
1957 double DoubleValue() const {
1958 ASSERT(HasDoubleValue());
1959 return double_value_;
1960 }
1961 bool HasStringValue() const { return handle_->IsString(); }
1962
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001963 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001964 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001965 return reinterpret_cast<intptr_t>(*handle());
1966 }
1967
1968#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00001969 virtual void Verify() { }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001970#endif
1971
1972 DECLARE_CONCRETE_INSTRUCTION(Constant, "constant")
1973
1974 protected:
1975 virtual Range* InferRange();
1976
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001977 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001978 HConstant* other_constant = HConstant::cast(other);
1979 return handle().is_identical_to(other_constant->handle());
1980 }
1981
1982 private:
1983 Handle<Object> handle_;
1984 HType constant_type_;
1985
1986 // The following two values represent the int32 and the double value of the
1987 // given constant if there is a lossless conversion between the constant
1988 // and the specific representation.
1989 bool has_int32_value_;
1990 int32_t int32_value_;
1991 bool has_double_value_;
1992 double double_value_;
1993};
1994
1995
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00001996class HBinaryOperation: public HTemplateInstruction<2> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001997 public:
1998 HBinaryOperation(HValue* left, HValue* right) {
1999 ASSERT(left != NULL && right != NULL);
2000 SetOperandAt(0, left);
2001 SetOperandAt(1, right);
2002 }
2003
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002004 HValue* left() { return OperandAt(0); }
2005 HValue* right() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002006
2007 // TODO(kasperl): Move these helpers to the IA-32 Lithium
2008 // instruction sequence builder.
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002009 HValue* LeastConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002010 if (IsCommutative() && left()->IsConstant()) return right();
2011 return left();
2012 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002013 HValue* MostConstantOperand() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002014 if (IsCommutative() && left()->IsConstant()) return left();
2015 return right();
2016 }
2017
2018 virtual bool IsCommutative() const { return false; }
2019
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002020 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002021
2022 DECLARE_INSTRUCTION(BinaryOperation)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002023};
2024
2025
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002026class HApplyArguments: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002027 public:
2028 HApplyArguments(HValue* function,
2029 HValue* receiver,
2030 HValue* length,
2031 HValue* elements) {
2032 set_representation(Representation::Tagged());
2033 SetOperandAt(0, function);
2034 SetOperandAt(1, receiver);
2035 SetOperandAt(2, length);
2036 SetOperandAt(3, elements);
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00002037 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002038 }
2039
2040 virtual Representation RequiredInputRepresentation(int index) const {
2041 // The length is untagged, all other inputs are tagged.
2042 return (index == 2)
2043 ? Representation::Integer32()
2044 : Representation::Tagged();
2045 }
2046
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002047 HValue* function() { return OperandAt(0); }
2048 HValue* receiver() { return OperandAt(1); }
2049 HValue* length() { return OperandAt(2); }
2050 HValue* elements() { return OperandAt(3); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002051
2052 DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply_arguments")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002053};
2054
2055
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002056class HArgumentsElements: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002057 public:
2058 HArgumentsElements() {
2059 // The value produced by this instruction is a pointer into the stack
2060 // that looks as if it was a smi because of alignment.
2061 set_representation(Representation::Tagged());
2062 SetFlag(kUseGVN);
2063 }
2064
2065 DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments_elements")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002066
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002067 virtual Representation RequiredInputRepresentation(int index) const {
2068 return Representation::None();
2069 }
2070
ager@chromium.org378b34e2011-01-28 08:04:38 +00002071 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002072 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002073};
2074
2075
2076class HArgumentsLength: public HUnaryOperation {
2077 public:
2078 explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
2079 set_representation(Representation::Integer32());
2080 SetFlag(kUseGVN);
2081 }
2082
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002083 virtual Representation RequiredInputRepresentation(int index) const {
2084 return Representation::Tagged();
2085 }
2086
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002087 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments_length")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002088
2089 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002090 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002091};
2092
2093
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002094class HAccessArgumentsAt: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002095 public:
2096 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) {
2097 set_representation(Representation::Tagged());
2098 SetFlag(kUseGVN);
2099 SetOperandAt(0, arguments);
2100 SetOperandAt(1, length);
2101 SetOperandAt(2, index);
2102 }
2103
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002104 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002105
2106 virtual Representation RequiredInputRepresentation(int index) const {
2107 // The arguments elements is considered tagged.
2108 return index == 0
2109 ? Representation::Tagged()
2110 : Representation::Integer32();
2111 }
2112
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002113 HValue* arguments() { return OperandAt(0); }
2114 HValue* length() { return OperandAt(1); }
2115 HValue* index() { return OperandAt(2); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002116
2117 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access_arguments_at")
2118
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002119 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002120};
2121
2122
2123class HBoundsCheck: public HBinaryOperation {
2124 public:
2125 HBoundsCheck(HValue* index, HValue* length)
2126 : HBinaryOperation(index, length) {
2127 SetFlag(kUseGVN);
2128 }
2129
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002130 virtual bool IsCheckInstruction() const { return true; }
2131
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002132 virtual Representation RequiredInputRepresentation(int index) const {
2133 return Representation::Integer32();
2134 }
2135
2136#ifdef DEBUG
ager@chromium.org378b34e2011-01-28 08:04:38 +00002137 virtual void Verify();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002138#endif
2139
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002140 HValue* index() { return left(); }
2141 HValue* length() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002142
2143 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds_check")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002144
2145 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002146 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002147};
2148
2149
2150class HBitwiseBinaryOperation: public HBinaryOperation {
2151 public:
2152 HBitwiseBinaryOperation(HValue* left, HValue* right)
2153 : HBinaryOperation(left, right) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002154 set_representation(Representation::Tagged());
2155 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002156 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002157 }
2158
2159 virtual Representation RequiredInputRepresentation(int index) const {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002160 return representation();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002161 }
2162
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002163 virtual void RepresentationChanged(Representation to) {
2164 if (!to.IsTagged()) {
2165 ASSERT(to.IsInteger32());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002166 ClearAllSideEffects();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002167 SetFlag(kTruncatingToInt32);
2168 SetFlag(kUseGVN);
2169 }
2170 }
2171
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002172 virtual HType CalculateInferredType();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00002173
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002174 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2175};
2176
2177
2178class HArithmeticBinaryOperation: public HBinaryOperation {
2179 public:
2180 HArithmeticBinaryOperation(HValue* left, HValue* right)
2181 : HBinaryOperation(left, right) {
2182 set_representation(Representation::Tagged());
2183 SetFlag(kFlexibleRepresentation);
ager@chromium.org378b34e2011-01-28 08:04:38 +00002184 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002185 }
2186
2187 virtual void RepresentationChanged(Representation to) {
2188 if (!to.IsTagged()) {
ager@chromium.org378b34e2011-01-28 08:04:38 +00002189 ClearAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002190 SetFlag(kUseGVN);
2191 }
2192 }
2193
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002194 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002195 virtual Representation RequiredInputRepresentation(int index) const {
2196 return representation();
2197 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002198 virtual Representation InferredRepresentation() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002199 if (left()->representation().Equals(right()->representation())) {
2200 return left()->representation();
2201 }
2202 return HValue::InferredRepresentation();
2203 }
2204
2205 DECLARE_INSTRUCTION(ArithmeticBinaryOperation)
2206};
2207
2208
2209class HCompare: public HBinaryOperation {
2210 public:
2211 HCompare(HValue* left, HValue* right, Token::Value token)
2212 : HBinaryOperation(left, right), token_(token) {
2213 ASSERT(Token::IsCompareOp(token));
2214 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002215 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002216 }
2217
2218 void SetInputRepresentation(Representation r);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002219
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002220 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002221 return !HasSideEffects() && (uses()->length() <= 1);
2222 }
2223
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002224 virtual Representation RequiredInputRepresentation(int index) const {
2225 return input_representation_;
2226 }
2227 Representation GetInputRepresentation() const {
2228 return input_representation_;
2229 }
2230 Token::Value token() const { return token_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002231 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002232
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002233 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002234
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002235 virtual intptr_t Hashcode() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002236 return HValue::Hashcode() * 7 + token_;
2237 }
2238
2239 DECLARE_CONCRETE_INSTRUCTION(Compare, "compare")
2240
2241 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002242 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002243 HCompare* comp = HCompare::cast(other);
2244 return token_ == comp->token();
2245 }
2246
2247 private:
2248 Representation input_representation_;
2249 Token::Value token_;
2250};
2251
2252
2253class HCompareJSObjectEq: public HBinaryOperation {
2254 public:
2255 HCompareJSObjectEq(HValue* left, HValue* right)
2256 : HBinaryOperation(left, right) {
2257 set_representation(Representation::Tagged());
2258 SetFlag(kUseGVN);
2259 }
2260
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002261 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002262 return !HasSideEffects() && (uses()->length() <= 1);
2263 }
2264
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002265 virtual Representation RequiredInputRepresentation(int index) const {
2266 return Representation::Tagged();
2267 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002268 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002269
2270 DECLARE_CONCRETE_INSTRUCTION(CompareJSObjectEq, "compare-js-object-eq")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002271
2272 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002273 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002274};
2275
2276
2277class HUnaryPredicate: public HUnaryOperation {
2278 public:
2279 explicit HUnaryPredicate(HValue* value) : HUnaryOperation(value) {
2280 set_representation(Representation::Tagged());
2281 SetFlag(kUseGVN);
2282 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002283
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002284 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002285 return !HasSideEffects() && (uses()->length() <= 1);
2286 }
2287
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002288 virtual Representation RequiredInputRepresentation(int index) const {
2289 return Representation::Tagged();
2290 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002291 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002292};
2293
2294
2295class HIsNull: public HUnaryPredicate {
2296 public:
2297 HIsNull(HValue* value, bool is_strict)
2298 : HUnaryPredicate(value), is_strict_(is_strict) { }
2299
2300 bool is_strict() const { return is_strict_; }
2301
2302 DECLARE_CONCRETE_INSTRUCTION(IsNull, "is_null")
2303
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002304 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002305 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002306 HIsNull* b = HIsNull::cast(other);
2307 return is_strict_ == b->is_strict();
2308 }
2309
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002310 private:
2311 bool is_strict_;
2312};
2313
2314
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002315class HIsObject: public HUnaryPredicate {
2316 public:
2317 explicit HIsObject(HValue* value) : HUnaryPredicate(value) { }
2318
2319 DECLARE_CONCRETE_INSTRUCTION(IsObject, "is_object")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002320
2321 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002322 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002323};
2324
2325
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002326class HIsSmi: public HUnaryPredicate {
2327 public:
2328 explicit HIsSmi(HValue* value) : HUnaryPredicate(value) { }
2329
2330 DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is_smi")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002331
2332 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002333 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002334};
2335
2336
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002337class HIsConstructCall: public HTemplateInstruction<0> {
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002338 public:
2339 HIsConstructCall() {
2340 set_representation(Representation::Tagged());
2341 SetFlag(kUseGVN);
2342 }
2343
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002344 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002345 return !HasSideEffects() && (uses()->length() <= 1);
2346 }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002347
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002348 virtual Representation RequiredInputRepresentation(int index) const {
2349 return Representation::None();
2350 }
2351
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002352 DECLARE_CONCRETE_INSTRUCTION(IsConstructCall, "is_construct_call")
2353
2354 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002355 virtual bool DataEquals(HValue* other) { return true; }
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +00002356};
2357
2358
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002359class HHasInstanceType: public HUnaryPredicate {
2360 public:
2361 HHasInstanceType(HValue* value, InstanceType type)
2362 : HUnaryPredicate(value), from_(type), to_(type) { }
2363 HHasInstanceType(HValue* value, InstanceType from, InstanceType to)
2364 : HUnaryPredicate(value), from_(from), to_(to) {
2365 ASSERT(to == LAST_TYPE); // Others not implemented yet in backend.
2366 }
2367
2368 InstanceType from() { return from_; }
2369 InstanceType to() { return to_; }
2370
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002371 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002372
2373 DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has_instance_type")
2374
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002375 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002376 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002377 HHasInstanceType* b = HHasInstanceType::cast(other);
2378 return (from_ == b->from()) && (to_ == b->to());
2379 }
2380
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002381 private:
2382 InstanceType from_;
2383 InstanceType to_; // Inclusive range, not all combinations work.
2384};
2385
2386
2387class HHasCachedArrayIndex: public HUnaryPredicate {
2388 public:
2389 explicit HHasCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2390
2391 DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has_cached_array_index")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002392
2393 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002394 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002395};
2396
2397
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002398class HGetCachedArrayIndex: public HUnaryPredicate {
2399 public:
2400 explicit HGetCachedArrayIndex(HValue* value) : HUnaryPredicate(value) { }
2401
2402 DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get_cached_array_index")
2403
2404 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002405 virtual bool DataEquals(HValue* other) { return true; }
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +00002406};
2407
2408
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002409class HClassOfTest: public HUnaryPredicate {
2410 public:
2411 HClassOfTest(HValue* value, Handle<String> class_name)
2412 : HUnaryPredicate(value), class_name_(class_name) { }
2413
2414 DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class_of_test")
2415
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002416 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002417
2418 Handle<String> class_name() const { return class_name_; }
2419
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002420 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002421 virtual bool DataEquals(HValue* other) {
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002422 HClassOfTest* b = HClassOfTest::cast(other);
2423 return class_name_.is_identical_to(b->class_name_);
2424 }
2425
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002426 private:
2427 Handle<String> class_name_;
2428};
2429
2430
2431class HTypeofIs: public HUnaryPredicate {
2432 public:
2433 HTypeofIs(HValue* value, Handle<String> type_literal)
2434 : HUnaryPredicate(value), type_literal_(type_literal) { }
2435
2436 Handle<String> type_literal() { return type_literal_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002437 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002438
2439 DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof_is")
2440
2441 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002442 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002443 HTypeofIs* b = HTypeofIs::cast(other);
2444 return type_literal_.is_identical_to(b->type_literal_);
2445 }
2446
2447 private:
2448 Handle<String> type_literal_;
2449};
2450
2451
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002452class HInstanceOf: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002453 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002454 HInstanceOf(HValue* context, HValue* left, HValue* right) {
2455 SetOperandAt(0, context);
2456 SetOperandAt(1, left);
2457 SetOperandAt(2, right);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002458 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002459 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002460 }
2461
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002462 HValue* context() { return OperandAt(0); }
2463 HValue* left() { return OperandAt(1); }
2464 HValue* right() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002465
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002466 virtual bool EmitAtUses() {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002467 return !HasSideEffects() && (uses()->length() <= 1);
2468 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002469
2470 virtual Representation RequiredInputRepresentation(int index) const {
2471 return Representation::Tagged();
2472 }
2473
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002474 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002475
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002476 DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance_of")
2477};
2478
2479
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002480class HInstanceOfKnownGlobal: public HUnaryOperation {
2481 public:
2482 HInstanceOfKnownGlobal(HValue* left, Handle<JSFunction> right)
2483 : HUnaryOperation(left), function_(right) {
2484 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002485 SetAllSideEffects();
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002486 }
2487
2488 Handle<JSFunction> function() { return function_; }
2489
2490 virtual Representation RequiredInputRepresentation(int index) const {
2491 return Representation::Tagged();
2492 }
2493
2494 DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
2495 "instance_of_known_global")
2496
2497 private:
2498 Handle<JSFunction> function_;
2499};
2500
2501
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002502class HPower: public HBinaryOperation {
2503 public:
2504 HPower(HValue* left, HValue* right)
2505 : HBinaryOperation(left, right) {
2506 set_representation(Representation::Double());
2507 SetFlag(kUseGVN);
2508 }
2509
2510 virtual Representation RequiredInputRepresentation(int index) const {
2511 return (index == 1) ? Representation::None() : Representation::Double();
2512 }
2513
2514 DECLARE_CONCRETE_INSTRUCTION(Power, "power")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002515
2516 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002517 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00002518};
2519
2520
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002521class HAdd: public HArithmeticBinaryOperation {
2522 public:
2523 HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2524 SetFlag(kCanOverflow);
2525 }
2526
2527 // Add is only commutative if two integer values are added and not if two
2528 // tagged values are added (because it might be a String concatenation).
2529 virtual bool IsCommutative() const {
2530 return !representation().IsTagged();
2531 }
2532
2533 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2534
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002535 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002536
2537 DECLARE_CONCRETE_INSTRUCTION(Add, "add")
2538
2539 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002540 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002541
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002542 virtual Range* InferRange();
2543};
2544
2545
2546class HSub: public HArithmeticBinaryOperation {
2547 public:
2548 HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2549 SetFlag(kCanOverflow);
2550 }
2551
2552 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2553
2554 DECLARE_CONCRETE_INSTRUCTION(Sub, "sub")
2555
2556 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002557 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002558
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002559 virtual Range* InferRange();
2560};
2561
2562
2563class HMul: public HArithmeticBinaryOperation {
2564 public:
2565 HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2566 SetFlag(kCanOverflow);
2567 }
2568
2569 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2570
2571 // Only commutative if it is certain that not two objects are multiplicated.
2572 virtual bool IsCommutative() const {
2573 return !representation().IsTagged();
2574 }
2575
2576 DECLARE_CONCRETE_INSTRUCTION(Mul, "mul")
2577
2578 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002579 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002580
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002581 virtual Range* InferRange();
2582};
2583
2584
2585class HMod: public HArithmeticBinaryOperation {
2586 public:
2587 HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2588 SetFlag(kCanBeDivByZero);
2589 }
2590
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00002591 bool HasPowerOf2Divisor() {
2592 if (right()->IsConstant() &&
2593 HConstant::cast(right())->HasInteger32Value()) {
2594 int32_t value = HConstant::cast(right())->Integer32Value();
2595 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value));
2596 }
2597
2598 return false;
2599 }
2600
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002601 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2602
2603 DECLARE_CONCRETE_INSTRUCTION(Mod, "mod")
2604
2605 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002606 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002607
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002608 virtual Range* InferRange();
2609};
2610
2611
2612class HDiv: public HArithmeticBinaryOperation {
2613 public:
2614 HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) {
2615 SetFlag(kCanBeDivByZero);
2616 SetFlag(kCanOverflow);
2617 }
2618
2619 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
2620
2621 DECLARE_CONCRETE_INSTRUCTION(Div, "div")
2622
2623 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002624 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002625
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002626 virtual Range* InferRange();
2627};
2628
2629
2630class HBitAnd: public HBitwiseBinaryOperation {
2631 public:
2632 HBitAnd(HValue* left, HValue* right)
2633 : HBitwiseBinaryOperation(left, right) { }
2634
2635 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002636 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002637
2638 DECLARE_CONCRETE_INSTRUCTION(BitAnd, "bit_and")
2639
2640 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002641 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002642
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002643 virtual Range* InferRange();
2644};
2645
2646
2647class HBitXor: public HBitwiseBinaryOperation {
2648 public:
2649 HBitXor(HValue* left, HValue* right)
2650 : HBitwiseBinaryOperation(left, right) { }
2651
2652 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002653 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654
2655 DECLARE_CONCRETE_INSTRUCTION(BitXor, "bit_xor")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002656
2657 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002658 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659};
2660
2661
2662class HBitOr: public HBitwiseBinaryOperation {
2663 public:
2664 HBitOr(HValue* left, HValue* right)
2665 : HBitwiseBinaryOperation(left, right) { }
2666
2667 virtual bool IsCommutative() const { return true; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002668 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002669
2670 DECLARE_CONCRETE_INSTRUCTION(BitOr, "bit_or")
2671
2672 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002673 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002674
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002675 virtual Range* InferRange();
2676};
2677
2678
2679class HShl: public HBitwiseBinaryOperation {
2680 public:
2681 HShl(HValue* left, HValue* right)
2682 : HBitwiseBinaryOperation(left, right) { }
2683
2684 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002685 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002686
2687 DECLARE_CONCRETE_INSTRUCTION(Shl, "shl")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002688
2689 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002690 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691};
2692
2693
2694class HShr: public HBitwiseBinaryOperation {
2695 public:
2696 HShr(HValue* left, HValue* right)
2697 : HBitwiseBinaryOperation(left, right) { }
2698
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002699 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002700
2701 DECLARE_CONCRETE_INSTRUCTION(Shr, "shr")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002702
2703 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002704 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705};
2706
2707
2708class HSar: public HBitwiseBinaryOperation {
2709 public:
2710 HSar(HValue* left, HValue* right)
2711 : HBitwiseBinaryOperation(left, right) { }
2712
2713 virtual Range* InferRange();
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002714 virtual HType CalculateInferredType();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715
2716 DECLARE_CONCRETE_INSTRUCTION(Sar, "sar")
ager@chromium.org378b34e2011-01-28 08:04:38 +00002717
2718 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002719 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002720};
2721
2722
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002723class HOsrEntry: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724 public:
2725 explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
2726 SetFlag(kChangesOsrEntries);
2727 }
2728
2729 int ast_id() const { return ast_id_; }
2730
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002731 virtual Representation RequiredInputRepresentation(int index) const {
2732 return Representation::None();
2733 }
2734
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002735 DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr_entry")
2736
2737 private:
2738 int ast_id_;
2739};
2740
2741
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002742class HParameter: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002743 public:
2744 explicit HParameter(unsigned index) : index_(index) {
2745 set_representation(Representation::Tagged());
2746 }
2747
2748 unsigned index() const { return index_; }
2749
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002750 virtual void PrintDataTo(StringStream* stream);
2751
2752 virtual Representation RequiredInputRepresentation(int index) const {
2753 return Representation::None();
2754 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002755
2756 DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
2757
2758 private:
2759 unsigned index_;
2760};
2761
2762
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002763class HCallStub: public HUnaryCall {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002764 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002765 HCallStub(HValue* context, CodeStub::Major major_key, int argument_count)
2766 : HUnaryCall(context, argument_count),
2767 major_key_(major_key),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768 transcendental_type_(TranscendentalCache::kNumberOfCaches) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002769 }
2770
2771 CodeStub::Major major_key() { return major_key_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002772
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002773 HValue* context() { return value(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774
2775 void set_transcendental_type(TranscendentalCache::Type transcendental_type) {
2776 transcendental_type_ = transcendental_type;
2777 }
2778 TranscendentalCache::Type transcendental_type() {
2779 return transcendental_type_;
2780 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002781
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002782 virtual void PrintDataTo(StringStream* stream);
2783
2784 virtual Representation RequiredInputRepresentation(int index) const {
2785 return Representation::Tagged();
2786 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002787
2788 DECLARE_CONCRETE_INSTRUCTION(CallStub, "call_stub")
2789
2790 private:
2791 CodeStub::Major major_key_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792 TranscendentalCache::Type transcendental_type_;
2793};
2794
2795
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002796class HUnknownOSRValue: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002797 public:
2798 HUnknownOSRValue() { set_representation(Representation::Tagged()); }
2799
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002800 virtual Representation RequiredInputRepresentation(int index) const {
2801 return Representation::None();
2802 }
2803
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002804 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown_osr_value")
2805};
2806
2807
ricow@chromium.org3842d832011-03-17 14:48:24 +00002808class HLoadGlobal: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002809 public:
ricow@chromium.org3842d832011-03-17 14:48:24 +00002810 HLoadGlobal(Handle<JSGlobalPropertyCell> cell, bool check_hole_value)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002811 : cell_(cell), check_hole_value_(check_hole_value) {
2812 set_representation(Representation::Tagged());
2813 SetFlag(kUseGVN);
2814 SetFlag(kDependsOnGlobalVars);
2815 }
2816
2817 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
2818 bool check_hole_value() const { return check_hole_value_; }
2819
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002820 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002821
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002822 virtual intptr_t Hashcode() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002823 ASSERT(!HEAP->allow_allocation(false));
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002824 return reinterpret_cast<intptr_t>(*cell_);
2825 }
2826
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002827 virtual Representation RequiredInputRepresentation(int index) const {
2828 return Representation::None();
2829 }
2830
ricow@chromium.org3842d832011-03-17 14:48:24 +00002831 DECLARE_CONCRETE_INSTRUCTION(LoadGlobal, "load_global")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002832
2833 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002834 virtual bool DataEquals(HValue* other) {
ricow@chromium.org3842d832011-03-17 14:48:24 +00002835 HLoadGlobal* b = HLoadGlobal::cast(other);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002836 return cell_.is_identical_to(b->cell());
2837 }
2838
2839 private:
2840 Handle<JSGlobalPropertyCell> cell_;
2841 bool check_hole_value_;
2842};
2843
2844
2845class HStoreGlobal: public HUnaryOperation {
2846 public:
ager@chromium.org378b34e2011-01-28 08:04:38 +00002847 HStoreGlobal(HValue* value,
2848 Handle<JSGlobalPropertyCell> cell,
2849 bool check_hole_value)
2850 : HUnaryOperation(value),
2851 cell_(cell),
2852 check_hole_value_(check_hole_value) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002853 SetFlag(kChangesGlobalVars);
2854 }
2855
2856 Handle<JSGlobalPropertyCell> cell() const { return cell_; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00002857 bool check_hole_value() const { return check_hole_value_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002858
2859 virtual Representation RequiredInputRepresentation(int index) const {
2860 return Representation::Tagged();
2861 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002862 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002863
2864 DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store_global")
2865
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002866 private:
2867 Handle<JSGlobalPropertyCell> cell_;
ager@chromium.org378b34e2011-01-28 08:04:38 +00002868 bool check_hole_value_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002869};
2870
2871
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002872class HLoadContextSlot: public HUnaryOperation {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002873 public:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002874 HLoadContextSlot(HValue* context , int slot_index)
2875 : HUnaryOperation(context), slot_index_(slot_index) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002876 set_representation(Representation::Tagged());
2877 SetFlag(kUseGVN);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002878 SetFlag(kDependsOnContextSlots);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002879 }
2880
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002881 int slot_index() const { return slot_index_; }
2882
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002883 virtual Representation RequiredInputRepresentation(int index) const {
2884 return Representation::Tagged();
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002885 }
2886
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002887 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002888
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002889 DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load_context_slot")
2890
2891 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002892 virtual bool DataEquals(HValue* other) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002893 HLoadContextSlot* b = HLoadContextSlot::cast(other);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002894 return (slot_index() == b->slot_index());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002895 }
2896
2897 private:
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002898 int slot_index_;
2899};
2900
2901
2902static inline bool StoringValueNeedsWriteBarrier(HValue* value) {
2903 return !value->type().IsSmi() &&
2904 !(value->IsConstant() && HConstant::cast(value)->InOldSpace());
2905}
2906
2907
2908class HStoreContextSlot: public HBinaryOperation {
2909 public:
2910 HStoreContextSlot(HValue* context, int slot_index, HValue* value)
2911 : HBinaryOperation(context, value), slot_index_(slot_index) {
2912 SetFlag(kChangesContextSlots);
2913 }
2914
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002915 HValue* context() { return OperandAt(0); }
2916 HValue* value() { return OperandAt(1); }
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002917 int slot_index() const { return slot_index_; }
2918
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002919 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002920 return StoringValueNeedsWriteBarrier(value());
2921 }
2922
2923 virtual Representation RequiredInputRepresentation(int index) const {
2924 return Representation::Tagged();
2925 }
2926
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002927 virtual void PrintDataTo(StringStream* stream);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002928
2929 DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store_context_slot")
2930
2931 private:
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00002932 int slot_index_;
2933};
2934
2935
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002936class HLoadNamedField: public HUnaryOperation {
2937 public:
2938 HLoadNamedField(HValue* object, bool is_in_object, int offset)
2939 : HUnaryOperation(object),
2940 is_in_object_(is_in_object),
2941 offset_(offset) {
2942 set_representation(Representation::Tagged());
2943 SetFlag(kUseGVN);
2944 if (is_in_object) {
2945 SetFlag(kDependsOnInobjectFields);
2946 } else {
2947 SetFlag(kDependsOnBackingStoreFields);
2948 }
2949 }
2950
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002951 HValue* object() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002952 bool is_in_object() const { return is_in_object_; }
2953 int offset() const { return offset_; }
2954
2955 virtual Representation RequiredInputRepresentation(int index) const {
2956 return Representation::Tagged();
2957 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002958 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002959
2960 DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load_named_field")
2961
2962 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002963 virtual bool DataEquals(HValue* other) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002964 HLoadNamedField* b = HLoadNamedField::cast(other);
2965 return is_in_object_ == b->is_in_object_ && offset_ == b->offset_;
2966 }
2967
2968 private:
2969 bool is_in_object_;
2970 int offset_;
2971};
2972
2973
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002974class HLoadNamedGeneric: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002975 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002976 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
2977 : HBinaryOperation(context, object), name_(name) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002978 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00002979 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002980 }
2981
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00002982 HValue* context() { return OperandAt(0); }
2983 HValue* object() { return OperandAt(1); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002984 Handle<Object> name() const { return name_; }
2985
2986 virtual Representation RequiredInputRepresentation(int index) const {
2987 return Representation::Tagged();
2988 }
2989
2990 DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load_named_generic")
2991
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002992 private:
2993 Handle<Object> name_;
2994};
2995
2996
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00002997class HLoadFunctionPrototype: public HUnaryOperation {
2998 public:
2999 explicit HLoadFunctionPrototype(HValue* function)
3000 : HUnaryOperation(function) {
3001 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003002 SetFlag(kUseGVN);
3003 SetFlag(kDependsOnCalls);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003004 }
3005
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003006 HValue* function() { return OperandAt(0); }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003007
3008 virtual Representation RequiredInputRepresentation(int index) const {
3009 return Representation::Tagged();
3010 }
3011
3012 DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load_function_prototype")
3013
3014 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003015 virtual bool DataEquals(HValue* other) { return true; }
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +00003016};
3017
3018
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003019class HLoadKeyedFastElement: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003020 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003021 HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003022 set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023 SetFlag(kDependsOnArrayElements);
3024 SetFlag(kUseGVN);
3025 }
3026
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003027 HValue* object() { return OperandAt(0); }
3028 HValue* key() { return OperandAt(1); }
3029
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030 virtual Representation RequiredInputRepresentation(int index) const {
3031 // The key is supposed to be Integer32.
3032 return (index == 1) ? Representation::Integer32()
3033 : Representation::Tagged();
3034 }
3035
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003036 virtual void PrintDataTo(StringStream* stream);
3037
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003038 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement,
3039 "load_keyed_fast_element")
ager@chromium.org378b34e2011-01-28 08:04:38 +00003040
3041 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003042 virtual bool DataEquals(HValue* other) { return true; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003043};
3044
3045
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003046class HLoadPixelArrayElement: public HBinaryOperation {
3047 public:
3048 HLoadPixelArrayElement(HValue* external_elements, HValue* key)
3049 : HBinaryOperation(external_elements, key) {
3050 set_representation(Representation::Integer32());
3051 SetFlag(kDependsOnPixelArrayElements);
3052 // Native code could change the pixel array.
3053 SetFlag(kDependsOnCalls);
3054 SetFlag(kUseGVN);
3055 }
3056
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003057 virtual void PrintDataTo(StringStream* stream);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003058
3059 virtual Representation RequiredInputRepresentation(int index) const {
3060 // The key is supposed to be Integer32, but the base pointer
3061 // for the element load is a naked pointer.
3062 return (index == 1) ? Representation::Integer32()
3063 : Representation::External();
3064 }
3065
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003066 HValue* external_pointer() { return OperandAt(0); }
3067 HValue* key() { return OperandAt(1); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003068
3069 DECLARE_CONCRETE_INSTRUCTION(LoadPixelArrayElement,
3070 "load_pixel_array_element")
3071
3072 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003073 virtual bool DataEquals(HValue* other) { return true; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003074};
3075
3076
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003077class HLoadKeyedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003079 HLoadKeyedGeneric(HContext* context, HValue* obj, HValue* key) {
3080 set_representation(Representation::Tagged());
3081 SetOperandAt(0, obj);
3082 SetOperandAt(1, key);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003083 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003084 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 }
3086
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003087 HValue* object() { return OperandAt(0); }
3088 HValue* key() { return OperandAt(1); }
3089 HValue* context() { return OperandAt(2); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003090
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003091 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003092
3093 virtual Representation RequiredInputRepresentation(int index) const {
3094 return Representation::Tagged();
3095 }
3096
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003097 DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load_keyed_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003098};
3099
3100
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003101class HStoreNamedField: public HBinaryOperation {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003102 public:
3103 HStoreNamedField(HValue* obj,
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003104 Handle<String> name,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003105 HValue* val,
3106 bool in_object,
3107 int offset)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003108 : HBinaryOperation(obj, val),
3109 name_(name),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003110 is_in_object_(in_object),
3111 offset_(offset) {
3112 if (is_in_object_) {
3113 SetFlag(kChangesInobjectFields);
3114 } else {
3115 SetFlag(kChangesBackingStoreFields);
3116 }
3117 }
3118
3119 DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store_named_field")
3120
3121 virtual Representation RequiredInputRepresentation(int index) const {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003122 return Representation::Tagged();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003123 }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003124 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003125
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003126 HValue* object() { return OperandAt(0); }
3127 HValue* value() { return OperandAt(1); }
3128
3129 Handle<String> name() const { return name_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 bool is_in_object() const { return is_in_object_; }
3131 int offset() const { return offset_; }
3132 Handle<Map> transition() const { return transition_; }
3133 void set_transition(Handle<Map> map) { transition_ = map; }
3134
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003135 bool NeedsWriteBarrier() {
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003136 return StoringValueNeedsWriteBarrier(value());
3137 }
3138
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003139 private:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003140 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003141 bool is_in_object_;
3142 int offset_;
3143 Handle<Map> transition_;
3144};
3145
3146
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003147class HStoreNamedGeneric: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003149 HStoreNamedGeneric(HValue* context,
3150 HValue* object,
3151 Handle<String> name,
3152 HValue* value)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003153 : name_(name) {
3154 SetOperandAt(0, object);
3155 SetOperandAt(1, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003156 SetOperandAt(2, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003157 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003158 }
3159
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003160 HValue* object() { return OperandAt(0); }
3161 HValue* value() { return OperandAt(1); }
3162 HValue* context() { return OperandAt(2); }
3163 Handle<String> name() { return name_; }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003164
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003165 virtual void PrintDataTo(StringStream* stream);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003166
3167 virtual Representation RequiredInputRepresentation(int index) const {
3168 return Representation::Tagged();
3169 }
3170
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003171 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store_named_generic")
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003172
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003173 private:
3174 Handle<String> name_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003175};
3176
3177
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003178class HStoreKeyedFastElement: public HTemplateInstruction<3> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003179 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003180 HStoreKeyedFastElement(HValue* obj, HValue* key, HValue* val) {
3181 SetOperandAt(0, obj);
3182 SetOperandAt(1, key);
3183 SetOperandAt(2, val);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003184 SetFlag(kChangesArrayElements);
3185 }
3186
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003187 virtual Representation RequiredInputRepresentation(int index) const {
3188 // The key is supposed to be Integer32.
3189 return (index == 1) ? Representation::Integer32()
3190 : Representation::Tagged();
3191 }
3192
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003193 HValue* object() { return OperandAt(0); }
3194 HValue* key() { return OperandAt(1); }
3195 HValue* value() { return OperandAt(2); }
3196
3197 bool NeedsWriteBarrier() {
3198 return StoringValueNeedsWriteBarrier(value());
3199 }
3200
3201 virtual void PrintDataTo(StringStream* stream);
3202
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003203 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastElement,
3204 "store_keyed_fast_element")
3205};
3206
3207
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003208class HStorePixelArrayElement: public HTemplateInstruction<3> {
3209 public:
3210 HStorePixelArrayElement(HValue* external_elements, HValue* key, HValue* val) {
3211 SetFlag(kChangesPixelArrayElements);
3212 SetOperandAt(0, external_elements);
3213 SetOperandAt(1, key);
3214 SetOperandAt(2, val);
3215 }
3216
3217 virtual void PrintDataTo(StringStream* stream);
3218
3219 virtual Representation RequiredInputRepresentation(int index) const {
3220 if (index == 0) {
3221 return Representation::External();
3222 } else {
3223 return Representation::Integer32();
3224 }
3225 }
3226
3227 HValue* external_pointer() { return OperandAt(0); }
3228 HValue* key() { return OperandAt(1); }
3229 HValue* value() { return OperandAt(2); }
3230
3231 DECLARE_CONCRETE_INSTRUCTION(StorePixelArrayElement,
3232 "store_pixel_array_element")
3233};
3234
3235
3236class HStoreKeyedGeneric: public HTemplateInstruction<4> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003237 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003238 HStoreKeyedGeneric(HValue* context,
3239 HValue* object,
3240 HValue* key,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003241 HValue* value) {
3242 SetOperandAt(0, object);
3243 SetOperandAt(1, key);
3244 SetOperandAt(2, value);
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003245 SetOperandAt(3, context);
ager@chromium.org378b34e2011-01-28 08:04:38 +00003246 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003247 }
3248
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003249 HValue* object() { return OperandAt(0); }
3250 HValue* key() { return OperandAt(1); }
3251 HValue* value() { return OperandAt(2); }
3252 HValue* context() { return OperandAt(3); }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003253
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003254 virtual Representation RequiredInputRepresentation(int index) const {
3255 return Representation::Tagged();
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003256 }
3257
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003258 virtual void PrintDataTo(StringStream* stream);
3259
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003260 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store_keyed_generic")
3261};
3262
3263
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003264class HStringCharCodeAt: public HBinaryOperation {
3265 public:
3266 HStringCharCodeAt(HValue* string, HValue* index)
3267 : HBinaryOperation(string, index) {
3268 set_representation(Representation::Integer32());
3269 SetFlag(kUseGVN);
3270 }
3271
3272 virtual Representation RequiredInputRepresentation(int index) const {
3273 // The index is supposed to be Integer32.
3274 return (index == 1) ? Representation::Integer32()
3275 : Representation::Tagged();
3276 }
3277
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003278 HValue* string() { return OperandAt(0); }
3279 HValue* index() { return OperandAt(1); }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003280
3281 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string_char_code_at")
3282
3283 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003284 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003285
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003286 virtual Range* InferRange() {
3287 return new Range(0, String::kMaxUC16CharCode);
3288 }
3289};
3290
3291
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003292class HStringCharFromCode: public HUnaryOperation {
3293 public:
3294 explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) {
3295 set_representation(Representation::Tagged());
3296 SetFlag(kUseGVN);
3297 }
3298
3299 virtual Representation RequiredInputRepresentation(int index) const {
3300 return Representation::Integer32();
3301 }
3302
3303 virtual bool DataEquals(HValue* other) { return true; }
3304
3305 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string_char_from_code")
3306};
3307
3308
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003309class HStringLength: public HUnaryOperation {
3310 public:
3311 explicit HStringLength(HValue* string) : HUnaryOperation(string) {
3312 set_representation(Representation::Tagged());
3313 SetFlag(kUseGVN);
3314 }
3315
3316 virtual Representation RequiredInputRepresentation(int index) const {
3317 return Representation::Tagged();
3318 }
3319
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003320 virtual HType CalculateInferredType() {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003321 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
3322 return HType::Smi();
3323 }
3324
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003325 DECLARE_CONCRETE_INSTRUCTION(StringLength, "string_length")
3326
3327 protected:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003328 virtual bool DataEquals(HValue* other) { return true; }
ager@chromium.org378b34e2011-01-28 08:04:38 +00003329
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +00003330 virtual Range* InferRange() {
3331 return new Range(0, String::kMaxLength);
3332 }
3333};
3334
3335
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003336template <int V>
3337class HMaterializedLiteral: public HTemplateInstruction<V> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003338 public:
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003339 HMaterializedLiteral<V>(int index, int depth)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003340 : literal_index_(index), depth_(depth) {
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003341 this->set_representation(Representation::Tagged());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003342 }
3343
3344 int literal_index() const { return literal_index_; }
3345 int depth() const { return depth_; }
3346
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003347 private:
3348 int literal_index_;
3349 int depth_;
3350};
3351
3352
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003353class HArrayLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003354 public:
3355 HArrayLiteral(Handle<FixedArray> constant_elements,
3356 int length,
3357 int literal_index,
3358 int depth)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003359 : HMaterializedLiteral<0>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003360 length_(length),
3361 constant_elements_(constant_elements) {}
3362
3363 Handle<FixedArray> constant_elements() const { return constant_elements_; }
3364 int length() const { return length_; }
3365
3366 bool IsCopyOnWrite() const;
3367
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003368 virtual Representation RequiredInputRepresentation(int index) const {
3369 return Representation::None();
3370 }
3371
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003372 DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array_literal")
3373
3374 private:
3375 int length_;
3376 Handle<FixedArray> constant_elements_;
3377};
3378
3379
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003380class HObjectLiteral: public HMaterializedLiteral<1> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003381 public:
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003382 HObjectLiteral(HValue* context,
3383 Handle<FixedArray> constant_properties,
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003384 bool fast_elements,
3385 int literal_index,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003386 int depth,
3387 bool has_function)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003388 : HMaterializedLiteral<1>(literal_index, depth),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003389 constant_properties_(constant_properties),
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003390 fast_elements_(fast_elements),
3391 has_function_(has_function) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003392 SetOperandAt(0, context);
3393 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003394
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003395 HValue* context() { return OperandAt(0); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003396 Handle<FixedArray> constant_properties() const {
3397 return constant_properties_;
3398 }
3399 bool fast_elements() const { return fast_elements_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003400 bool has_function() const { return has_function_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003402 virtual Representation RequiredInputRepresentation(int index) const {
3403 return Representation::Tagged();
3404 }
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00003405
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003406 DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object_literal")
3407
3408 private:
3409 Handle<FixedArray> constant_properties_;
3410 bool fast_elements_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003411 bool has_function_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003412};
3413
3414
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003415class HRegExpLiteral: public HMaterializedLiteral<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003416 public:
3417 HRegExpLiteral(Handle<String> pattern,
3418 Handle<String> flags,
3419 int literal_index)
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003420 : HMaterializedLiteral<0>(literal_index, 0),
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003421 pattern_(pattern),
3422 flags_(flags) { }
3423
3424 Handle<String> pattern() { return pattern_; }
3425 Handle<String> flags() { return flags_; }
3426
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003427 virtual Representation RequiredInputRepresentation(int index) const {
3428 return Representation::None();
3429 }
3430
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003431 DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp_literal")
3432
3433 private:
3434 Handle<String> pattern_;
3435 Handle<String> flags_;
3436};
3437
3438
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003439class HFunctionLiteral: public HTemplateInstruction<0> {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003440 public:
3441 HFunctionLiteral(Handle<SharedFunctionInfo> shared, bool pretenure)
3442 : shared_info_(shared), pretenure_(pretenure) {
3443 set_representation(Representation::Tagged());
3444 }
3445
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003446 virtual Representation RequiredInputRepresentation(int index) const {
3447 return Representation::None();
3448 }
3449
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450 DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function_literal")
3451
3452 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
3453 bool pretenure() const { return pretenure_; }
3454
3455 private:
3456 Handle<SharedFunctionInfo> shared_info_;
3457 bool pretenure_;
3458};
3459
3460
3461class HTypeof: public HUnaryOperation {
3462 public:
3463 explicit HTypeof(HValue* value) : HUnaryOperation(value) {
3464 set_representation(Representation::Tagged());
3465 }
3466
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003467 virtual Representation RequiredInputRepresentation(int index) const {
3468 return Representation::Tagged();
3469 }
3470
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003471 DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
3472};
3473
3474
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003475class HToFastProperties: public HUnaryOperation {
3476 public:
3477 explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
3478 // This instruction is not marked as having side effects, but
3479 // changes the map of the input operand. Use it only when creating
3480 // object literals.
3481 ASSERT(value->IsObjectLiteral());
3482 set_representation(Representation::Tagged());
3483 }
3484
3485 virtual Representation RequiredInputRepresentation(int index) const {
3486 return Representation::Tagged();
3487 }
3488
3489 DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to_fast_properties")
3490};
3491
3492
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003493class HValueOf: public HUnaryOperation {
3494 public:
3495 explicit HValueOf(HValue* value) : HUnaryOperation(value) {
3496 set_representation(Representation::Tagged());
3497 }
3498
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003499 virtual Representation RequiredInputRepresentation(int index) const {
3500 return Representation::Tagged();
3501 }
3502
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003503 DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value_of")
3504};
3505
3506
3507class HDeleteProperty: public HBinaryOperation {
3508 public:
3509 HDeleteProperty(HValue* obj, HValue* key)
3510 : HBinaryOperation(obj, key) {
3511 set_representation(Representation::Tagged());
ager@chromium.org378b34e2011-01-28 08:04:38 +00003512 SetAllSideEffects();
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003513 }
3514
3515 virtual Representation RequiredInputRepresentation(int index) const {
3516 return Representation::Tagged();
3517 }
3518
3519 DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete_property")
3520
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +00003521 HValue* object() { return left(); }
3522 HValue* key() { return right(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003523};
3524
3525#undef DECLARE_INSTRUCTION
3526#undef DECLARE_CONCRETE_INSTRUCTION
3527
3528} } // namespace v8::internal
3529
3530#endif // V8_HYDROGEN_INSTRUCTIONS_H_