1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
4a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifndef V8_HYDROGEN_INSTRUCTIONS_H_
6a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#define V8_HYDROGEN_INSTRUCTIONS_H_
7a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
1121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/code-stubs.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/conversions.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/data-flow.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
169d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org#include "src/feedback-slots.h"
17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/hydrogen-types.h"
18196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/small-pointer-list.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/unique.h"
20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
21196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/zone.h"
22a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
23a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace v8 {
24a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgnamespace internal {
25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
26a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org// Forward declarations.
27f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgstruct ChangesOf;
28a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HBasicBlock;
29af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.orgclass HDiv;
30a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HEnvironment;
311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgclass HInferRepresentationPhase;
32a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HInstruction;
33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HLoopInformation;
34cc8e177451e2ab80cf4eacfd782d19cd05ec2070hpayer@chromium.orgclass HStoreNamedField;
35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass HValue;
36a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LInstruction;
37a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgclass LChunkBuilder;
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgclass OStream;
39a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
40e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
41e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ArithmeticBinaryOperation)                \
42e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(BinaryOperation)                          \
43e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(BitwiseBinaryOperation)                   \
44e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ControlInstruction)                       \
45e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Instruction)
46e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
47e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org
48e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
49e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(AbnormalExit)                             \
50e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(AccessArgumentsAt)                        \
51e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Add)                                      \
52e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(AllocateBlockContext)                     \
53e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Allocate)                                 \
54e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ApplyArguments)                           \
55e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ArgumentsElements)                        \
56e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ArgumentsLength)                          \
57e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ArgumentsObject)                          \
58e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Bitwise)                                  \
59e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(BlockEntry)                               \
60e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(BoundsCheck)                              \
61e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(BoundsCheckBaseIndexInformation)          \
62e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Branch)                                   \
63e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallWithDescriptor)                       \
64e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallJSFunction)                           \
65e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallFunction)                             \
66e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallNew)                                  \
67e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallNewArray)                             \
68e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallRuntime)                              \
69e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CallStub)                                 \
70e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CapturedObject)                           \
71e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Change)                                   \
72e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckHeapObject)                          \
73e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckInstanceType)                        \
74e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckMaps)                                \
75e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckMapValue)                            \
76e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckSmi)                                 \
77e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CheckValue)                               \
78e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ClampToUint8)                             \
79e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ClassOfTestAndBranch)                     \
80e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareNumericAndBranch)                  \
81e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareHoleAndBranch)                     \
82e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareGeneric)                           \
83e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareMinusZeroAndBranch)                \
84e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareObjectEqAndBranch)                 \
85e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(CompareMap)                               \
86e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Constant)                                 \
87e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ConstructDouble)                          \
88e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Context)                                  \
89e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(DateField)                                \
90e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(DebugBreak)                               \
91e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(DeclareGlobals)                           \
92e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Deoptimize)                               \
93e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Div)                                      \
94e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(DoubleBits)                               \
95e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(DummyUse)                                 \
96e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(EnterInlined)                             \
97e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(EnvironmentMarker)                        \
98e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ForceRepresentation)                      \
99e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ForInCacheArray)                          \
100e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ForInPrepareMap)                          \
101e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(FunctionLiteral)                          \
102e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(GetCachedArrayIndex)                      \
103e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Goto)                                     \
104e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(HasCachedArrayIndexAndBranch)             \
105e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(HasInstanceTypeAndBranch)                 \
106e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(InnerAllocatedObject)                     \
107e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(InstanceOf)                               \
108e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(InstanceOfKnownGlobal)                    \
109e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(InvokeFunction)                           \
110e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(IsConstructCallAndBranch)                 \
111e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(IsObjectAndBranch)                        \
112e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(IsStringAndBranch)                        \
113e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(IsSmiAndBranch)                           \
114e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(IsUndetectableAndBranch)                  \
115e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LeaveInlined)                             \
116e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadContextSlot)                          \
117e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadFieldByIndex)                         \
118e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadFunctionPrototype)                    \
119e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadGlobalCell)                           \
120e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadGlobalGeneric)                        \
121e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadKeyed)                                \
122e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadKeyedGeneric)                         \
123e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadNamedField)                           \
124e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadNamedGeneric)                         \
125e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(LoadRoot)                                 \
126e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(MapEnumLength)                            \
127e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(MathFloorOfDiv)                           \
128e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(MathMinMax)                               \
129e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Mod)                                      \
130e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Mul)                                      \
131e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(OsrEntry)                                 \
132e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Parameter)                                \
133e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Power)                                    \
134e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(PushArguments)                            \
135e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(RegExpLiteral)                            \
136e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Return)                                   \
137e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Ror)                                      \
138e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Sar)                                      \
139e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(SeqStringGetChar)                         \
140e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(SeqStringSetChar)                         \
141e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Shl)                                      \
142e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Shr)                                      \
143e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Simulate)                                 \
144e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StackCheck)                               \
145e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreCodeEntry)                           \
146e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreContextSlot)                         \
147e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreFrameContext)                        \
148e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreGlobalCell)                          \
149e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreKeyed)                               \
150e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreKeyedGeneric)                        \
151e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreNamedField)                          \
152e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StoreNamedGeneric)                        \
153e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StringAdd)                                \
154e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StringCharCodeAt)                         \
155e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StringCharFromCode)                       \
156e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(StringCompareAndBranch)                   \
157e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Sub)                                      \
158e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(TailCallThroughMegamorphicCache)          \
159e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ThisFunction)                             \
160e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(ToFastProperties)                         \
161e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(TransitionElementsKind)                   \
162e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(TrapAllocationMemento)                    \
163e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(Typeof)                                   \
164e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(TypeofIsAndBranch)                        \
165e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(UnaryMathOperation)                       \
166e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(UnknownOSRValue)                          \
167e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  V(UseConst)                                 \
168154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  V(WrapReceiver)
169a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
17028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org#define GVN_TRACKED_FLAG_LIST(V)               \
17128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  V(NewSpacePromotion)
17228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
17328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org#define GVN_UNTRACKED_FLAG_LIST(V)             \
174c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(ArrayElements)                             \
175c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(ArrayLengths)                              \
176d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  V(StringLengths)                             \
177a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  V(BackingStoreFields)                        \
178c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(Calls)                                     \
179c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(ContextSlots)                              \
180c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(DoubleArrayElements)                       \
18157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  V(DoubleFields)                              \
182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  V(ElementsKind)                              \
18378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  V(ElementsPointer)                           \
184a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  V(GlobalVars)                                \
185c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(InobjectFields)                            \
186c8e8806f9e54a027d667425f1bb1b28cf9cbb6f7machenbach@chromium.org  V(Maps)                                      \
187c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org  V(OsrEntries)                                \
188e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  V(ExternalMemory)                            \
1895c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  V(StringChars)                               \
1905c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org  V(TypedArrayElements)
191c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org
192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
19332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org#define DECLARE_ABSTRACT_INSTRUCTION(type)                              \
194ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool Is##type() const FINAL OVERRIDE { return true; }   \
19532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  static H##type* cast(HValue* value) {                                 \
196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(value->Is##type());                                          \
19732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return reinterpret_cast<H##type*>(value);                           \
198dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  }
199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
200a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
20132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org#define DECLARE_CONCRETE_INSTRUCTION(type)              \
20232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual LInstruction* CompileToLithium(               \
203ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org     LChunkBuilder* builder) FINAL OVERRIDE;      \
20432cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  static H##type* cast(HValue* value) {                 \
205e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(value->Is##type());                          \
20632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return reinterpret_cast<H##type*>(value);           \
20732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }                                                     \
208ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Opcode opcode() const FINAL OVERRIDE {  \
20932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return HValue::k##type;                             \
21032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
212a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgenum PropertyAccessType { LOAD, STORE };
214f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
215f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
216ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass Range FINAL : public ZoneObject {
217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2188f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  Range()
2198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      : lower_(kMinInt),
2208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        upper_(kMaxInt),
2218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        next_(NULL),
2228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        can_be_minus_zero_(false) { }
223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Range(int32_t lower, int32_t upper)
2258f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      : lower_(lower),
2268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        upper_(upper),
2278f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        next_(NULL),
2288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org        can_be_minus_zero_(false) { }
229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t upper() const { return upper_; }
231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t lower() const { return lower_; }
232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Range* next() const { return next_; }
233812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Range* CopyClearLower(Zone* zone) const {
234812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return new(zone) Range(kMinInt, upper_);
235812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
236812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Range* CopyClearUpper(Zone* zone) const {
237812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    return new(zone) Range(lower_, kMaxInt);
238812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
239812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Range* Copy(Zone* zone) const {
240812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    Range* result = new(zone) Range(lower_, upper_);
241ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    result->set_can_be_minus_zero(CanBeMinusZero());
242ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    return result;
243ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
244a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t Mask() const;
245a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
247a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
248a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool CanBeNegative() const { return lower_ < 0; }
249b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  bool CanBePositive() const { return upper_ > 0; }
2508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
251ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  bool IsMostGeneric() const {
252ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
253ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  }
2548f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  bool IsInSmiRange() const {
2558f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
256a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2571fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  void ClampToSmi() {
2581fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    lower_ = Max(lower_, Smi::kMinValue);
2591fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org    upper_ = Min(upper_, Smi::kMaxValue);
2601fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  }
2618f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void KeepOrder();
262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#ifdef DEBUG
2638f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void Verify() const;
264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#endif
2655f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
266a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void StackUpon(Range* other) {
267a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    Intersect(other);
268a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    next_ = other;
269a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
270a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void Intersect(Range* other);
2728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void Union(Range* other);
273471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void CombinedMax(Range* other);
274471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void CombinedMin(Range* other);
275a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2768f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void AddConstant(int32_t value);
2778f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void Sar(int32_t value);
2788f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void Shl(int32_t value);
279fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool AddAndCheckOverflow(const Representation& r, Range* other);
280fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool SubAndCheckOverflow(const Representation& r, Range* other);
281fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool MulAndCheckOverflow(const Representation& r, Range* other);
282a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
283a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t lower_;
285a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int32_t upper_;
286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Range* next_;
287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool can_be_minus_zero_;
288a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
289a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
290a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2913847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.comclass HUseListNode: public ZoneObject {
2923847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com public:
2933847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode(HValue* value, int index, HUseListNode* tail)
2943847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com      : tail_(tail), value_(value), index_(index) {
2953847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
2963847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
297ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  HUseListNode* tail();
2983847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HValue* value() const { return value_; }
2993847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  int index() const { return index_; }
3003847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3013847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  void set_tail(HUseListNode* list) { tail_ = list; }
3023847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com#ifdef DEBUG
3043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  void Zap() {
3053847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    tail_ = reinterpret_cast<HUseListNode*>(1);
3063847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    value_ = NULL;
3073847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    index_ = -1;
3083847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
3093847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com#endif
3103847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3113847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com private:
3123847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode* tail_;
3133847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HValue* value_;
3143847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  int index_;
3153847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com};
3163847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3173847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3183847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com// We reuse use list nodes behind the scenes as uses are added and deleted.
3193847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com// This class is the safe way to iterate uses while deleting them.
320ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HUseIterator FINAL BASE_EMBEDDED {
3213847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com public:
3223847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  bool Done() { return current_ == NULL; }
3233847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  void Advance();
3243847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3253847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HValue* value() {
326e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!Done());
3273847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    return value_;
3283847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
3293847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3303847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  int index() {
331e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!Done());
3323847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    return index_;
3333847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
3343847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3353847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com private:
3363847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  explicit HUseIterator(HUseListNode* head);
3373847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3383847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode* current_;
3393847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode* next_;
3403847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HValue* value_;
3413847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  int index_;
3423847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3433847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  friend class HValue;
3443847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com};
3453847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
3463847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
347f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// All tracked flags should appear before untracked ones.
34805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.orgenum GVNFlag {
34905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Declare global value numbering flags.
350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define DECLARE_FLAG(Type) k##Type,
35128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
35228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
35305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org#undef DECLARE_FLAG
354f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define COUNT_FLAG(Type) + 1
355f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG),
356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG),
35728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org#undef COUNT_FLAG
358f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
35905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org};
36005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
3617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
362f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgstatic inline GVNFlag GVNFlagFromInt(int i) {
363e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(i >= 0);
364e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(i < kNumberOfFlags);
365f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  return static_cast<GVNFlag>(i);
366f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}
367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
369ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass DecompositionResult FINAL BASE_EMBEDDED {
370876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org public:
371876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
372876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
373876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  HValue* base() { return base_; }
374876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  int offset() { return offset_; }
375876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  int scale() { return scale_; }
376876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
377876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
378876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    if (base_ == NULL) {
379876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      base_ = other_base;
380876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      offset_ = other_offset;
381876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      scale_ = other_scale;
382876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      return true;
383876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    } else {
384876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      if (scale_ == 0) {
385876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org        base_ = other_base;
386876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org        offset_ += other_offset;
387876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org        scale_ = other_scale;
388876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org        return true;
389876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      } else {
390876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org        return false;
391876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      }
392876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    }
393876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  }
394876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
395876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  void SwapValues(HValue** other_base, int* other_offset, int* other_scale) {
396876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    swap(&base_, other_base);
397876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    swap(&offset_, other_offset);
398876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    swap(&scale_, other_scale);
399876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  }
400876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
401876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org private:
402876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  template <class T> void swap(T* a, T* b) {
403876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    T c(*a);
404876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    *a = *b;
405876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    *b = c;
406876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  }
407876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
408876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  HValue* base_;
409876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  int offset_;
410876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  int scale_;
411876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org};
412876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
413876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org
414f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgtypedef EnumSet<GVNFlag, int32_t> GVNFlagSet;
415f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// This class encapsulates encoding and decoding of sources positions from
418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// which hydrogen values originated.
419f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// When FLAG_track_hydrogen_positions is set this object encodes the
420f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// identifier of the inlining and absolute offset from the start of the
421f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// inlined function.
422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// When the flag is not set we simply track absolute offset from the
423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// script start.
424f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass HSourcePosition {
425f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public:
426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition(const HSourcePosition& other) : value_(other.value_) { }
427f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
428f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  static HSourcePosition Unknown() {
429f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return HSourcePosition(RelocInfo::kNoPosition);
430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool IsUnknown() const { return value_ == RelocInfo::kNoPosition; }
433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int position() const { return PositionField::decode(value_); }
435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_position(int position) {
436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (FLAG_hydrogen_track_positions) {
437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      value_ = static_cast<int>(PositionField::update(value_, position));
438f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    } else {
439f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      value_ = position;
440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
441f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int inlining_id() const { return InliningIdField::decode(value_); }
444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_inlining_id(int inlining_id) {
445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (FLAG_hydrogen_track_positions) {
446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      value_ = static_cast<int>(InliningIdField::update(value_, inlining_id));
447f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
448f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int raw() const { return value_; }
451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private:
453f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  typedef BitField<int, 0, 9> InliningIdField;
454f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
455f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Offset from the start of the inlined function.
4569d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  typedef BitField<int, 9, 23> PositionField;
457f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  explicit HSourcePosition(int value) : value_(value) { }
459f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
460f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  friend class HPositionInfo;
46106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  friend class LCodeGenBase;
462f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
463f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField
464f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // and PositionField.
465f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Otherwise contains absolute offset from the script start.
466f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  int value_;
467f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org};
4685533f7fe6473bcffd84fdefc0b9ea9f92bdab978machenbach@chromium.org
4695533f7fe6473bcffd84fdefc0b9ea9f92bdab978machenbach@chromium.org
470f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const HSourcePosition& p);
471f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
472f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
47332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HValue : public ZoneObject {
474a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
475a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kNoNumber = -1;
476a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
477a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  enum Flag {
478a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kFlexibleRepresentation,
4791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    kCannotBeTagged,
4807b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // Participate in Global Value Numbering, i.e. elimination of
4817b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // unnecessary recomputations. If an instruction sets this flag, it must
4827b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // implement DataEquals(), which will be used to determine if other
4837b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org    // occurrences of the instruction are indeed the same.
484a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kUseGVN,
48528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // Track instructions that are dominating side effects. If an instruction
486169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org    // sets this flag, it must implement HandleSideEffectDominator() and should
48728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    // indicate which side effects to track by setting GVN flags.
48828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    kTrackSideEffectDominators,
489a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kCanOverflow,
490a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kBailoutOnMinusZero,
491a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kCanBeDivByZero,
492381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    kLeftCanBeMinInt,
493381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    kLeftCanBeNegative,
4947010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    kLeftCanBePositive,
495b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org    kAllowUndefinedAsNaN,
496a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kIsArguments,
497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kTruncatingToInt32,
498837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org    kAllUsesTruncatingToInt32,
499fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    kTruncatingToSmi,
500fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    kAllUsesTruncatingToSmi,
5014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Set after an instruction is killed.
502ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org    kIsDead,
50346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // Instructions that are allowed to produce full range unsigned integer
50446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // values are marked with kUint32 flag. If arithmetic shift or a load from
505af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    // EXTERNAL_UINT32_ELEMENTS array is not marked with this flag
50646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // it will deoptimize if result does not fit into signed integer range.
50746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // HGraph::ComputeSafeUint32Operations is responsible for setting this
50846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    // flag.
50946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    kUint32,
510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    kHasNoObservableSideEffects,
511a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // Indicates an instruction shouldn't be replaced by optimization, this flag
512a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // is useful to set in cases where recomputing a value is cheaper than
513a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    // extending the value's live range and spilling it.
514a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org    kCantBeReplaced,
5154e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    // Indicates the instruction is live during dead code elimination.
5164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    kIsLive,
517d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
518d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // HEnvironmentMarkers are deleted before dead code
519d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // elimination takes place, so they can repurpose the kIsLive flag:
520d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    kEndsLiveRange = kIsLive,
521d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
522d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    // TODO(everyone): Don't forget to update this!
523d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    kLastFlag = kIsLive
524a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
525a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
526a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  STATIC_ASSERT(kLastFlag < kBitsPerInt);
527a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
528a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static HValue* cast(HValue* value) { return value; }
529a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
530a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  enum Opcode {
531a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Declare a unique enum value for each hydrogen instruction.
532dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #define DECLARE_OPCODE(type) k##type,
533dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
534dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    kPhi
535dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #undef DECLARE_OPCODE
536a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
537dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  virtual Opcode opcode() const = 0;
538dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org
539dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  // Declare a non-virtual predicates for each concrete HInstruction or HValue.
540dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #define DECLARE_PREDICATE(type) \
541dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    bool Is##type() const { return opcode() == k##type; }
542dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
543dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #undef DECLARE_PREDICATE
544dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    bool IsPhi() const { return opcode() == kPhi; }
545dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org
546dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  // Declare virtual predicates for abstract HInstruction or HValue
547dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #define DECLARE_PREDICATE(type) \
548dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    virtual bool Is##type() const { return false; }
549dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org    HYDROGEN_ABSTRACT_INSTRUCTION_LIST(DECLARE_PREDICATE)
550dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  #undef DECLARE_PREDICATE
551a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5525924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  bool IsBitwiseBinaryShift() {
5535924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    return IsShl() || IsShr() || IsSar();
5545924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  }
5555924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
5565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  explicit HValue(HType type = HType::Tagged())
557d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      : block_(NULL),
558d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        id_(kNoNumber),
559d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        type_(type),
560d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        use_list_(NULL),
561d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        range_(NULL),
5622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#ifdef DEBUG
5632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        range_poisoned_(false),
5642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#endif
565d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        flags_(0) {}
566a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual ~HValue() {}
567a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
568f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  virtual HSourcePosition position() const {
569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return HSourcePosition::Unknown();
570f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
571f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  virtual HSourcePosition operand_position(int index) const {
572f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return position();
573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
57471f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
575a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* block() const { return block_; }
576a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SetBlock(HBasicBlock* block);
577a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
57809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  // Note: Never call this method for an unlinked value.
57909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  Isolate* isolate() const;
58009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org
581a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int id() const { return id_; }
582a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_id(int id) { id_ = id; }
583a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5843847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseIterator uses() const { return HUseIterator(use_list_); }
585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
5864d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  virtual bool EmitAtUses() { return false; }
587fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
588a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Representation representation() const { return representation_; }
589a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void ChangeRepresentation(Representation r) {
590e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(CheckFlag(kFlexibleRepresentation));
591e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!CheckFlag(kCannotBeTagged) || !r.IsTagged());
592a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    RepresentationChanged(r);
593a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    representation_ = r;
594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (r.IsTagged()) {
595fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // Tagged is the bottom of the lattice, don't go any further.
596fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ClearFlag(kFlexibleRepresentation);
597fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
598a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
599fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  virtual void AssumeRepresentation(Representation r);
600a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
601d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  virtual Representation KnownOptimalRepresentation() {
602d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    Representation r = representation();
603d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    if (r.IsTagged()) {
604d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      HType t = type();
605d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (t.IsSmi()) return Representation::Smi();
606d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (t.IsHeapNumber()) return Representation::Double();
607d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (t.IsHeapObject()) return r;
608d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      return Representation::None();
609d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
610d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return r;
611d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
612fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org
613a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HType type() const { return type_; }
614ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  void set_type(HType new_type) {
615e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(new_type.IsSubtypeOf(type_));
616ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    type_ = new_type;
617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
618a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
619068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // There are HInstructions that do not really change a value, they
620068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // only add pieces of information to it (like bounds checks, map checks,
621068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // smi checks...).
622068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // We call these instructions "informative definitions", or "iDef".
623068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // One of the iDef operands is special because it is the value that is
624068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // "transferred" to the output, we call it the "redefined operand".
625068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // If an HValue is an iDef it must override RedefinedOperandIndex() so that
626068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  // it does not return kNoRedefinedOperand;
627068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  static const int kNoRedefinedOperand = -1;
628068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
629068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  bool IsInformativeDefinition() {
630068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org    return RedefinedOperandIndex() != kNoRedefinedOperand;
631068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
632068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  HValue* RedefinedOperand() {
633594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    int index = RedefinedOperandIndex();
634594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return index == kNoRedefinedOperand ? NULL : OperandAt(index);
635068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  }
636068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org
637d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  bool CanReplaceWithDummyUses();
638d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
639d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  virtual int argument_delta() const { return 0; }
640d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
6412e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // A purely informative definition is an idef that will not emit code and
6422e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // should therefore be removed from the graph in the RestoreActualValues
6432e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  // phase (so that live ranges will be shorter).
6442e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  virtual bool IsPurelyInformativeDefinition() { return false; }
6452e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org
646528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // This method must always return the original HValue SSA definition,
647528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // regardless of any chain of iDefs of this value.
648068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org  HValue* ActualValue() {
649528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HValue* value = this;
650528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    int index;
651528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    while ((index = value->RedefinedOperandIndex()) != kNoRedefinedOperand) {
652528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      value = value->OperandAt(index);
653528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    }
654528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    return value;
65594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org  }
65694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org
6577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  bool IsInteger32Constant();
6587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  int32_t GetInteger32Constant();
659b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org  bool EqualsInteger32Constant(int32_t value);
6607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
661a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsDefinedAfter(HBasicBlock* other) const;
662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
663a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Operands.
664f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  virtual int OperandCount() const = 0;
665c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  virtual HValue* OperandAt(int index) const = 0;
666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SetOperandAt(int index, HValue* value);
667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
6683847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  void DeleteAndReplaceWith(HValue* other);
6696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  void ReplaceAllUsesWith(HValue* other);
6703847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  bool HasNoUses() const { return use_list_ == NULL; }
6714b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  bool HasOneUse() const {
6724b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    return use_list_ != NULL && use_list_->tail() == NULL;
6734b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  }
6743847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  bool HasMultipleUses() const {
6753847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com    return use_list_ != NULL && use_list_->tail() != NULL;
6763847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  }
6773847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  int UseCount() const;
678ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org
679ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  // Mark this HValue as dead and to be removed from other HValues' use lists.
680ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org  void Kill();
681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
682a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int flags() const { return flags_; }
683378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void SetFlag(Flag f) { flags_ |= (1 << f); }
684378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
685378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
68625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  void CopyFlag(Flag f, HValue* other) {
68725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org    if (other->CheckFlag(f)) SetFlag(f);
68825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org  }
689378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
690812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Returns true if the flag specified is set for all uses, false otherwise.
691c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  bool CheckUsesForFlag(Flag f) const;
692662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Same as before and the first one without the flag is returned in value.
693662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  bool CheckUsesForFlag(Flag f, HValue** value) const;
694837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  // Returns true if the flag specified is set for all uses, and this set
695837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org  // of uses is non-empty.
696c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
697812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
698f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GVNFlagSet ChangesFlags() const { return changes_flags_; }
699f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GVNFlagSet DependsOnFlags() const { return depends_on_flags_; }
700f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); }
701f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); }
702f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); }
703f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void ClearDependsOnFlag(GVNFlag f) { depends_on_flags_.Remove(f); }
704f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool CheckChangesFlag(GVNFlag f) const {
705f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return changes_flags_.Contains(f);
706f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
707f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool CheckDependsOnFlag(GVNFlag f) const {
708f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return depends_on_flags_.Contains(f);
709f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
710f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void SetAllSideEffects() { changes_flags_.Add(AllSideEffectsFlagSet()); }
71105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void ClearAllSideEffects() {
712f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    changes_flags_.Remove(AllSideEffectsFlagSet());
71305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
71405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  bool HasSideEffects() const {
715f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
71605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  }
717c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool HasObservableSideEffects() const {
718e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return !CheckFlag(kHasNoObservableSideEffects) &&
719f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
72078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
72178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
72278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  GVNFlagSet SideEffectFlags() const {
723f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    GVNFlagSet result = ChangesFlags();
72478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    result.Intersect(AllSideEffectsFlagSet());
72578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    return result;
72678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  }
72778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
72805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  GVNFlagSet ObservableChangesFlags() const {
729f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    GVNFlagSet result = ChangesFlags();
73005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    result.Intersect(AllObservableSideEffectsFlagSet());
73105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return result;
732c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
7331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
7342ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Range* range() const {
735e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!range_poisoned_);
7362ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return range_;
7372ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
7382ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  bool HasRange() const {
739e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!range_poisoned_);
7402ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    return range_ != NULL;
7412ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  }
7422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#ifdef DEBUG
7432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  void PoisonRange() { range_poisoned_ = true; }
7442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#endif
745812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  void AddNewRange(Range* r, Zone* zone);
746a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RemoveLastAddedRange();
747812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  void ComputeInitialRange(Zone* zone);
748a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
74993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  // Escape analysis helpers.
75093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  virtual bool HasEscapingOperandAt(int index) { return true; }
751639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org  virtual bool HasOutOfBoundsAccess(int size) { return false; }
75293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
753a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Representation helpers.
754fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  virtual Representation observed_input_representation(int index) {
755fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return Representation::None();
7567028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  }
757fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  virtual Representation RequiredInputRepresentation(int index) = 0;
7581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
7597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
760a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // This gives the instruction an opportunity to replace itself with an
761a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instruction that does the same in some better way.  To replace an
762a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // instruction with a new one, first add the new instruction to the graph,
763a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // then return it.  Return NULL to have the instruction deleted.
764a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual HValue* Canonicalize() { return this; }
765a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  bool Equals(HValue* other);
7673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  virtual intptr_t Hashcode();
768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7699259716434187c932704601f700375e53d865de8rossberg@chromium.org  // Compute unique ids upfront that is safe wrt GC and concurrent compilation.
7703d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org  virtual void FinalizeUniqueness() { }
771e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
772a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Printing support.
773f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  virtual OStream& PrintTo(OStream& os) const = 0;  // NOLINT
774a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
775dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  const char* Mnemonic() const;
776a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
777d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  // Type information helpers.
778d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  bool HasMonomorphicJSObjectType();
779d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org
780d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  // TODO(mstarzinger): For now instructions can override this function to
781d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  // specify statically known types, once HType can convey more information
782d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  // it should be based on the HType.
783d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org  virtual Handle<Map> GetMonomorphicJSObjectMap() { return Handle<Map>(); }
784d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org
785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Updated the inferred type of this instruction and returns true if
786a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // it has changed.
787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool UpdateInferredType();
788a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
7893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  virtual HType CalculateInferredType();
790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
79128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // This function must be overridden for instructions which have the
79228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // kTrackSideEffectDominators flag set, to track instructions that are
79328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  // dominating side effects.
7948297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  // It returns true if it removed an instruction which had side effects.
7958297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  virtual bool HandleSideEffectDominator(GVNFlag side_effect,
796169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org                                         HValue* dominator) {
79728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org    UNREACHABLE();
7988297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return false;
79928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  }
80028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org
8014e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  // Check if this instruction has some reason that prevents elimination.
8024e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  bool CannotBeEliminated() const {
8034e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    return HasObservableSideEffects() || !IsDeletable();
804c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  }
805c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org
806a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
807378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  virtual void Verify() = 0;
808a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
809a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
810876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org  virtual bool TryDecompose(DecompositionResult* decomposition) {
811876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    if (RedefinedOperand() != NULL) {
812876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      return RedefinedOperand()->TryDecompose(decomposition);
813876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org    } else {
814876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org      return false;
8157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    }
8167c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  }
8177c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
818d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Returns true conservatively if the program might be able to observe a
819d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // ToString() operation on this value.
820d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  bool ToStringCanBeObserved() const {
821eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    return ToStringOrToNumberCanBeObserved();
822d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
823d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
824d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // Returns true conservatively if the program might be able to observe a
825d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  // ToNumber() operation on this value.
826d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  bool ToNumberCanBeObserved() const {
827eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    return ToStringOrToNumberCanBeObserved();
828d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
829d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
8308fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  MinusZeroMode GetMinusZeroMode() {
8318fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org    return CheckFlag(kBailoutOnMinusZero)
8328fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org        ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO;
8338fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org  }
8348fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org
835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
836378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // This function must be overridden for instructions with flag kUseGVN, to
837378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // compare the non-Operand parts of the instruction.
8383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  virtual bool DataEquals(HValue* other) {
839378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    UNREACHABLE();
840378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    return false;
841378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
842fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
843eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  bool ToStringOrToNumberCanBeObserved() const {
844eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    if (type().IsTaggedPrimitive()) return false;
845eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    if (type().IsJSObject()) return true;
846eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org    return !representation().IsSmiOrInteger32() && !representation().IsDouble();
847eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org  }
848eac65cd57a2d5f018fc440eed1b69d0fe80fe336machenbach@chromium.org
849fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  virtual Representation RepresentationFromInputs() {
850fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return representation();
851fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
852a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  virtual Representation RepresentationFromUses();
853b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  Representation RepresentationFromUseRequirements();
854fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  bool HasNonSmiUse();
855fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  virtual void UpdateRepresentation(Representation new_rep,
8561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                                    HInferRepresentationPhase* h_infer,
857fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                    const char* reason);
8581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void AddDependantsToWorklist(HInferRepresentationPhase* h_infer);
859fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
860a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual void RepresentationChanged(Representation to) { }
861fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
862812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  virtual Range* InferRange(Zone* zone);
863a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual void DeleteFromGraph() = 0;
8643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  virtual void InternalSetOperandAt(int index, HValue* value) = 0;
865a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void clear_block() {
866e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(block_ != NULL);
867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    block_ = NULL;
868a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
869a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
870a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void set_representation(Representation r) {
871e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(representation_.IsNone() && !r.IsNone());
872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    representation_ = r;
873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
874a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
875f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  static GVNFlagSet AllFlagSet() {
876052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org    GVNFlagSet result;
877f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define ADD_FLAG(Type) result.Add(k##Type);
87828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  GVN_TRACKED_FLAG_LIST(ADD_FLAG)
87928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
8801805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org#undef ADD_FLAG
8811805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org    return result;
8821805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  }
8831805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
884378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // A flag mask to mark an instruction as having arbitrary side effects.
88505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  static GVNFlagSet AllSideEffectsFlagSet() {
886f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    GVNFlagSet result = AllFlagSet();
887f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    result.Remove(kOsrEntries);
88805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return result;
889378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
890f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  friend OStream& operator<<(OStream& os, const ChangesOf& v);
891378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
892c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // A flag mask of all side effects that can make observable changes in
893c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // an executing program (i.e. are not safe to repeat, move or remove);
89405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  static GVNFlagSet AllObservableSideEffectsFlagSet() {
895f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    GVNFlagSet result = AllFlagSet();
896f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    result.Remove(kNewSpacePromotion);
897f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    result.Remove(kElementsKind);
898f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    result.Remove(kElementsPointer);
899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    result.Remove(kMaps);
90005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org    return result;
901c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
902c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
9033847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  // Remove the matching use from the use list if present.  Returns the
9043847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  // removed list node or NULL.
9053847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode* RemoveUse(HValue* value, int index);
9063847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com
907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void RegisterUse(int index, HValue* new_value);
908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HBasicBlock* block_;
910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // The id of this instruction in the hydrogen graph, assigned when first
912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // added to the graph. Reflects creation order.
913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int id_;
914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Representation representation_;
916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HType type_;
9173847bd5ff857259e945a01d75fdb383e2351d166erik.corry@gmail.com  HUseListNode* use_list_;
918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Range* range_;
9192ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#ifdef DEBUG
9202ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  bool range_poisoned_;
9212ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org#endif
922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int flags_;
923f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GVNFlagSet changes_flags_;
924f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  GVNFlagSet depends_on_flags_;
925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
926659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org private:
927c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  virtual bool IsDeletable() const { return false; }
928c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org
929a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(HValue);
930a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
931a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
932f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org// Support for printing various aspects of an HValue.
933f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgstruct NameOf {
934f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  explicit NameOf(const HValue* const v) : value(v) {}
935f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  const HValue* value;
936f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org};
937f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
938f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
939f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgstruct TypeOf {
940f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  explicit TypeOf(const HValue* const v) : value(v) {}
941f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  const HValue* value;
942f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org};
943f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
944f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
945f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgstruct ChangesOf {
946f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  explicit ChangesOf(const HValue* const v) : value(v) {}
947f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  const HValue* value;
948f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org};
949f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org
950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
951d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.orgOStream& operator<<(OStream& os, const HValue& v);
952f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const NameOf& v);
953f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const TypeOf& v);
954f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.orgOStream& operator<<(OStream& os, const ChangesOf& v);
955d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
956d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
957d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P0(I)                                      \
958d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone, HValue* context) {                                 \
959d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I();                                                      \
960d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
961d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
962d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P1(I, P1)                                  \
963d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1) {                          \
964d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I(p1);                                                    \
965d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
966d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
967d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P2(I, P1, P2)                              \
968d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) {                   \
969d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I(p1, p2);                                                \
970d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
971d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
972d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P3(I, P1, P2, P3)                          \
973d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) {            \
974d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I(p1, p2, p3);                                            \
975d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
976d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
977d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P4(I, P1, P2, P3, P4)                      \
978d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone,                                                    \
979d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                HValue* context,                                               \
980d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P1 p1,                                                         \
981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P2 p2,                                                         \
982d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P3 p3,                                                         \
983d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P4 p4) {                                                       \
984d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I(p1, p2, p3, p4);                                        \
985d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
986d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
987d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P5(I, P1, P2, P3, P4, P5)                  \
988d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static I* New(Zone* zone,                                                    \
989d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                HValue* context,                                               \
990d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P1 p1,                                                         \
991d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P2 p2,                                                         \
992d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P3 p3,                                                         \
993d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P4 p4,                                                         \
994d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                P5 p5) {                                                       \
995d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) I(p1, p2, p3, p4, p5);                                    \
996d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
997d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
998fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org#define DECLARE_INSTRUCTION_FACTORY_P6(I, P1, P2, P3, P4, P5, P6)              \
999fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  static I* New(Zone* zone,                                                    \
1000fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                HValue* context,                                               \
1001fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P1 p1,                                                         \
1002fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P2 p2,                                                         \
1003fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P3 p3,                                                         \
1004fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P4 p4,                                                         \
1005fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P5 p5,                                                         \
1006fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                P6 p6) {                                                       \
1007fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return new(zone) I(p1, p2, p3, p4, p5, p6);                                \
1008fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
1009fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
10108e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I)                         \
10118e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone, HValue* context) {                                 \
10128e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context);                                               \
10138e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10148e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10158e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(I, P1)                     \
10168e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1) {                          \
10178e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context, p1);                                           \
10188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10198e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10208e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(I, P1, P2)                 \
10218e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2) {                   \
10228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context, p1, p2);                                       \
10238e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10248e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10258e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(I, P1, P2, P3)             \
10268e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone, HValue* context, P1 p1, P2 p2, P3 p3) {            \
10278e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context, p1, p2, p3);                                   \
10288e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10298e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10308e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(I, P1, P2, P3, P4)         \
10318e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone,                                                    \
10328e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                HValue* context,                                               \
10338e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P1 p1,                                                         \
10348e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P2 p2,                                                         \
10358e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P3 p3,                                                         \
10368e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P4 p4) {                                                       \
10378e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context, p1, p2, p3, p4);                               \
10388e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10398e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10408e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org#define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(I, P1, P2, P3, P4, P5)     \
10418e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  static I* New(Zone* zone,                                                    \
10428e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                HValue* context,                                               \
10438e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P1 p1,                                                         \
10448e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P2 p2,                                                         \
10458e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P3 p3,                                                         \
10468e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P4 p4,                                                         \
10478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org                P5 p5) {                                                       \
10488e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    return new(zone) I(context, p1, p2, p3, p4, p5);                           \
10498e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10508e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
1051d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1052af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// A helper class to represent per-operand position information attached to
1053af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// the HInstruction in the compact form. Uses tagging to distinguish between
1054af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// case when only instruction's position is available and case when operands'
1055af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// positions are also available.
1056af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// In the first case it contains intruction's position as a tagged value.
1057af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// In the second case it points to an array which contains instruction's
1058af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org// position and operands' positions.
1059af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgclass HPositionInfo {
1060af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org public:
1061af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { }
1062af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1063f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition position() const {
1064af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (has_operand_positions()) {
1065f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      return operand_positions()[kInstructionPosIndex];
1066af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
1067f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return HSourcePosition(static_cast<int>(UntagPosition(data_)));
1068af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1069af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1070f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_position(HSourcePosition pos) {
1071af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (has_operand_positions()) {
1072af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      operand_positions()[kInstructionPosIndex] = pos;
1073af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    } else {
1074f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      data_ = TagPosition(pos.raw());
1075af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
1076af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1077af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1078af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  void ensure_storage_for_operand_positions(Zone* zone, int operand_count) {
1079af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (has_operand_positions()) {
1080af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      return;
1081af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
1082af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1083af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    const int length = kFirstOperandPosIndex + operand_count;
1084f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    HSourcePosition* positions =
1085f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        zone->NewArray<HSourcePosition>(length);
1086af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    for (int i = 0; i < length; i++) {
1087f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      positions[i] = HSourcePosition::Unknown();
1088af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
1089af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1090f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    const HSourcePosition pos = position();
1091af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    data_ = reinterpret_cast<intptr_t>(positions);
1092af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    set_position(pos);
1093af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1094e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(has_operand_positions());
1095af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1096af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1097f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition operand_position(int idx) const {
1098af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    if (!has_operand_positions()) {
1099af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org      return position();
1100af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    }
1101f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return *operand_position_slot(idx);
1102af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1103af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_operand_position(int idx, HSourcePosition pos) {
1105af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    *operand_position_slot(idx) = pos;
1106af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1107af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1108af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org private:
1109af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static const intptr_t kInstructionPosIndex = 0;
1110af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static const intptr_t kFirstOperandPosIndex = 1;
1111af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1112f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition* operand_position_slot(int idx) const {
1113e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(has_operand_positions());
1114af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return &(operand_positions()[kFirstOperandPosIndex + idx]);
1115af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1116af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1117af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  bool has_operand_positions() const {
1118af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return !IsTaggedPosition(data_);
1119af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1120af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1121f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  HSourcePosition* operand_positions() const {
1122e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(has_operand_positions());
1123f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return reinterpret_cast<HSourcePosition*>(data_);
1124af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1125af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1126af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static const intptr_t kPositionTag = 1;
1127af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static const intptr_t kPositionShift = 1;
1128af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static bool IsTaggedPosition(intptr_t val) {
1129af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return (val & kPositionTag) != 0;
1130af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1131af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static intptr_t UntagPosition(intptr_t val) {
1132e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsTaggedPosition(val));
1133af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return val >> kPositionShift;
1134af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1135af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  static intptr_t TagPosition(intptr_t val) {
1136af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    const intptr_t result = (val << kPositionShift) | kPositionTag;
1137e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(UntagPosition(result) == val);
1138af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    return result;
1139af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1140af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1141af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  intptr_t data_;
1142af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org};
1143af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1144af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
114532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HInstruction : public HValue {
1146a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1147a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* next() const { return next_; }
1148a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* previous() const { return previous_; }
1149a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1150ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintTo(OStream& os) const OVERRIDE;  // NOLINT
1151f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const;          // NOLINT
1152a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1153a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool IsLinked() const { return block() != NULL; }
1154a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void Unlink();
1155af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1156a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InsertBefore(HInstruction* next);
1157af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1158af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  template<class T> T* Prepend(T* instr) {
1159af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    instr->InsertBefore(this);
1160af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    return instr;
1161af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  }
1162af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
1163a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InsertAfter(HInstruction* previous);
1164a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1165af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  template<class T> T* Append(T* instr) {
1166af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    instr->InsertAfter(this);
1167af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org    return instr;
1168af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org  }
1169af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org
117028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  // The position is a write-once variable.
1171ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HSourcePosition position() const OVERRIDE {
1172f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return HSourcePosition(position_.position());
1173af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1174af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  bool has_position() const {
1175f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return !position().IsUnknown();
1176af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_position(HSourcePosition position) {
1178e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!has_position());
1179e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!position.IsUnknown());
1180af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    position_.set_position(position);
1181af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1182af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org
1183ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HSourcePosition operand_position(int index) const OVERRIDE {
1184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    const HSourcePosition pos = position_.operand_position(index);
1185f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return pos.IsUnknown() ? position() : pos;
1186af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  }
1187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void set_operand_position(Zone* zone, int index, HSourcePosition pos) {
1188e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(0 <= index && index < OperandCount());
1189af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    position_.ensure_storage_for_operand_positions(zone, OperandCount());
1190af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org    position_.set_operand_position(index, pos);
119128583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org  }
1192a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
119338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org  bool Dominates(HInstruction* other);
1194ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org  bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); }
1195812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
1196812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1197a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
1198a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1199a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
1200ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void Verify() OVERRIDE;
1201a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
1202a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1203b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org  bool CanDeoptimize();
1204b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org
1205ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org  virtual bool HasStackCheck() { return false; }
12063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1207dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_ABSTRACT_INSTRUCTION(Instruction)
1208a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1209a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
12105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  explicit HInstruction(HType type = HType::Tagged())
1211d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      : HValue(type),
1212d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        next_(NULL),
1213a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        previous_(NULL),
1214a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        position_(RelocInfo::kNoPosition) {
1215f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    SetDependsOnFlag(kOsrEntries);
1216a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1217a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1218ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void DeleteFromGraph() OVERRIDE { Unlink(); }
1219a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
1221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void InitializeAsFirst(HBasicBlock* block) {
1222e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!IsLinked());
1223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetBlock(block);
1224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* next_;
1227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HInstruction* previous_;
1228af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  HPositionInfo position_;
1229a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1230a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  friend class HBasicBlock;
1231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1232a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1233a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgtemplate<int V>
12356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgclass HTemplateInstruction : public HInstruction {
1236a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1237ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual int OperandCount() const FINAL OVERRIDE { return V; }
1238ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HValue* OperandAt(int i) const FINAL OVERRIDE {
123932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return inputs_[i];
124032cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
1241a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
12426d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org protected:
12435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  explicit HTemplateInstruction(HType type = HType::Tagged())
12445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      : HInstruction(type) {}
1245d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1246ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void InternalSetOperandAt(int i, HValue* value) FINAL OVERRIDE {
124732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    inputs_[i] = value;
124832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
12490a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
12500a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org private:
12516d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  EmbeddedContainer<HValue*, V> inputs_;
1252a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1253a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1254a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
125532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HControlInstruction : public HInstruction {
12563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
1257f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  virtual HBasicBlock* SuccessorAt(int i) const = 0;
1258f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  virtual int SuccessorCount() const = 0;
12594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
12603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1261ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
12623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1263d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  virtual bool KnownSuccessorBlock(HBasicBlock** block) {
1264d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    *block = NULL;
1265d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return false;
1266d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1267d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
12686d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  HBasicBlock* FirstSuccessor() {
12696d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
12703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
12716d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  HBasicBlock* SecondSuccessor() {
12726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
12736d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  }
12746d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1275528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Not() {
1276528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    HBasicBlock* swap = SuccessorAt(0);
1277528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    SetSuccessorAt(0, SuccessorAt(1));
1278528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    SetSuccessorAt(1, swap);
1279528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
1280528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
12816d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
12823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
12833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
12843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1285ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HSuccessorIterator FINAL BASE_EMBEDDED {
12863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
1287f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  explicit HSuccessorIterator(const HControlInstruction* instr)
1288f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      : instr_(instr), current_(0) {}
12893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
12906d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  bool Done() { return current_ >= instr_->SuccessorCount(); }
12916d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
12926d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  void Advance() { current_++; }
12933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
12943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
1295f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  const HControlInstruction* instr_;
12966d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  int current_;
12973a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
12983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
12993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13006d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.orgtemplate<int S, int V>
130132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HTemplateControlInstruction : public HControlInstruction {
13023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
1303ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  int SuccessorCount() const OVERRIDE { return S; }
1304ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  HBasicBlock* SuccessorAt(int i) const OVERRIDE { return successors_[i]; }
1305ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  void SetSuccessorAt(int i, HBasicBlock* block) OVERRIDE {
130632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    successors_[i] = block;
130732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
13086d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1309ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  int OperandCount() const OVERRIDE { return V; }
1310ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  HValue* OperandAt(int i) const OVERRIDE { return inputs_[i]; }
13113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13124f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org
13133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org protected:
1314ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  void InternalSetOperandAt(int i, HValue* value) OVERRIDE {
131532cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    inputs_[i] = value;
131632cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
13173a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13183a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org private:
13196d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  EmbeddedContainer<HBasicBlock*, S> successors_;
13206d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  EmbeddedContainer<HValue*, V> inputs_;
13213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
13223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1324ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HBlockEntry FINAL : public HTemplateInstruction<0> {
13253a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org public:
1326ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
13273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::None();
13283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
13293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1330dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(BlockEntry)
13313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org};
13323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
13333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1334ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HDummyUse FINAL : public HTemplateInstruction<1> {
133546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org public:
1336d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  explicit HDummyUse(HValue* value)
1337d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      : HTemplateInstruction<1>(HType::Smi()) {
133846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    SetOperandAt(0, value);
133946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    // Pretend to be a Smi so that the HChange instructions inserted
134046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    // before any use generate as little code as possible.
134146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    set_representation(Representation::Tagged());
134246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
134346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
1344f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* value() const { return OperandAt(0); }
134546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
1346ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
1347ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
134846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org    return Representation::None();
134946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  }
135046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
1351ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
135246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
135346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org  DECLARE_CONCRETE_INSTRUCTION(DummyUse);
135446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org};
135546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
135646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org
13574e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org// Inserts an int3/stop break instruction for debugging purposes.
1358ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HDebugBreak FINAL : public HTemplateInstruction<0> {
13594e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org public:
1360528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
1361528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1362ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
13634e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org    return Representation::None();
13644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  }
13654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
13664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(DebugBreak)
13674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org};
13684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
13694e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
1370ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HGoto FINAL : public HTemplateControlInstruction<1, 0> {
1371a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
137204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  explicit HGoto(HBasicBlock* target) {
1373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    SetSuccessorAt(0, target);
1374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1375a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1376ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
1377d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    *block = FirstSuccessor();
1378d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return true;
1379d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1380d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1381ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
13823a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::None();
13833a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
13843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1385ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
138683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
1387dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Goto)
1388a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1389a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1390a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1391ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HDeoptimize FINAL : public HTemplateControlInstruction<1, 0> {
1392d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org public:
1393f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  static HDeoptimize* New(Zone* zone,
1394f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                          HValue* context,
1395f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                          const char* reason,
1396f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                          Deoptimizer::BailoutType type,
1397f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                          HBasicBlock* unreachable_continuation) {
1398d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return new(zone) HDeoptimize(reason, type, unreachable_continuation);
1399d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1400d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1401ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
1402d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    *block = NULL;
1403d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return true;
1404d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1405d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1406ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1407d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return Representation::None();
1408d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1409d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1410d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  const char* reason() const { return reason_; }
1411d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  Deoptimizer::BailoutType type() { return type_; }
1412d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1413d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
1414d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1415d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org private:
1416d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  explicit HDeoptimize(const char* reason,
1417d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                       Deoptimizer::BailoutType type,
1418d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                       HBasicBlock* unreachable_continuation)
1419d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : reason_(reason), type_(type) {
1420d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    SetSuccessorAt(0, unreachable_continuation);
1421d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
1422d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1423d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  const char* reason_;
1424d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  Deoptimizer::BailoutType type_;
1425d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org};
1426d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1427d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
142832cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HUnaryControlInstruction : public HTemplateControlInstruction<2, 1> {
1429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
14306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  HUnaryControlInstruction(HValue* value,
14316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                           HBasicBlock* true_target,
14326d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org                           HBasicBlock* false_target) {
1433a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetOperandAt(0, value);
14346d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    SetSuccessorAt(0, true_target);
14356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org    SetSuccessorAt(1, false_target);
1436a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1437a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1438ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1439a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1440f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* value() const { return OperandAt(0); }
1441a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1442a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1443a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1444ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HBranch FINAL : public HUnaryControlInstruction {
1445a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1446528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P1(HBranch, HValue*);
1447528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P2(HBranch, HValue*,
1448528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                 ToBooleanStub::Types);
1449528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P4(HBranch, HValue*,
1450528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                 ToBooleanStub::Types,
1451528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                 HBasicBlock*, HBasicBlock*);
1452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1453ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1454a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Representation::None();
1455a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1456ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation observed_input_representation(int index) OVERRIDE;
1457a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1458ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
1459d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
1460ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1461a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org
14622c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  ToBooleanStub::Types expected_input_types() const {
14632c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org    return expected_input_types_;
14642c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  }
14652c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
14664f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Branch)
14672c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org
14682c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org private:
1469528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HBranch(HValue* value,
1470528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(),
1471528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          HBasicBlock* true_target = NULL,
1472528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org          HBasicBlock* false_target = NULL)
1473528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      : HUnaryControlInstruction(value, true_target, false_target),
1474528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org        expected_input_types_(expected_input_types) {
1475528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    SetFlag(kAllowUndefinedAsNaN);
1476528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
1477528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
14782c99e28a7b1fcb3767dc7c0088514fe53be784c5ricow@chromium.org  ToBooleanStub::Types expected_input_types_;
1479a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1480a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1481a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1482ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HCompareMap FINAL : public HUnaryControlInstruction {
1483a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1484052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>);
1485052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org  DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
1486528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                 HBasicBlock*, HBasicBlock*);
1487a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1488ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
14898297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    if (known_successor_index() != kNoKnownSuccessorIndex) {
14908297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      *block = SuccessorAt(known_successor_index());
14918297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org      return true;
14928297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    }
14938297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    *block = NULL;
14948297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    return false;
14958297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  }
14968297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
1497ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1498023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
14998297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  static const int kNoKnownSuccessorIndex = -1;
15008297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  int known_successor_index() const { return known_successor_index_; }
15018297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  void set_known_successor_index(int known_successor_index) {
15028297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org    known_successor_index_ = known_successor_index;
15038297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org  }
15048297530cd2b71ba1a2fe6f27ba1c030a20468306machenbach@chromium.org
1505528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Unique<Map> map() const { return map_; }
1506a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  bool map_is_stable() const { return map_is_stable_; }
1507a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1508ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
15093a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::Tagged();
15103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
15113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1512dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(CompareMap)
1513a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1514ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org protected:
1515ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org  virtual int RedefinedOperandIndex() { return 0; }
1516ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org
1517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
1518528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  HCompareMap(HValue* value,
1519528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org              Handle<Map> map,
1520528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org              HBasicBlock* true_target = NULL,
1521528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org              HBasicBlock* false_target = NULL)
1522528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      : HUnaryControlInstruction(value, true_target, false_target),
1523a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org        known_successor_index_(kNoKnownSuccessorIndex),
1524a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org        map_is_stable_(map->is_stable()),
1525a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org        map_(Unique<Map>::CreateImmovable(map)) {
1526f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    set_representation(Representation::Tagged());
1527528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
1528528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
1529a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  int known_successor_index_ : 31;
1530a3b66334e4dd35d9d4874d275ef9c4a756f0225cmachenbach@chromium.org  bool map_is_stable_ : 1;
1531528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Unique<Map> map_;
1532a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1533a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1534a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1535ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HContext FINAL : public HTemplateInstruction<0> {
1536d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org public:
1537d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  static HContext* New(Zone* zone) {
1538d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return new(zone) HContext();
1539d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1540d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1541ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1542d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    return Representation::None();
1543d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1544d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1545d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Context)
1546d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1547d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org protected:
1548ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
1549d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1550d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org private:
1551d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HContext() {
1552d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    set_representation(Representation::Tagged());
1553d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetFlag(kUseGVN);
1554d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1555d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1556ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsDeletable() const OVERRIDE { return true; }
1557d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org};
1558d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1559d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1560ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HReturn FINAL : public HTemplateControlInstruction<0, 3> {
1561a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
15628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
15638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
1564a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1565ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1566c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org    // TODO(titzer): require an Int32 input for faster returns.
1567c8cbc43a1fd5fda5d6a1e172f720cbd1215157c8machenbach@chromium.org    if (index == 2) return Representation::Smi();
15683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::Tagged();
15693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
15703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1571ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
15726d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1573f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* value() const { return OperandAt(0); }
1574f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* context() const { return OperandAt(1); }
1575f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* parameter_count() const { return OperandAt(2); }
15766d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
1577dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Return)
1578d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1579d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org private:
15808e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  HReturn(HValue* context, HValue* value, HValue* parameter_count = 0) {
1581d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetOperandAt(0, value);
1582d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetOperandAt(1, context);
1583d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetOperandAt(2, parameter_count);
1584d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1585a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1588ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HAbnormalExit FINAL : public HTemplateControlInstruction<0, 0> {
1589c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org public:
1590db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit);
1591db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org
1592ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1593c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org    return Representation::None();
1594c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  }
1595c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1596c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
1597db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org private:
1598db783297aea0c1b0faf438598202d2abe10da70ebmeurer@chromium.org  HAbnormalExit() {}
1599c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org};
1600c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
1601c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
160232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass HUnaryOperation : public HTemplateInstruction<1> {
1603a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
16045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  explicit HUnaryOperation(HValue* value, HType type = HType::Tagged())
1605d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      : HTemplateInstruction<1>(type) {
1606a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetOperandAt(0, value);
1607a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1608a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1609c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  static HUnaryOperation* cast(HValue* value) {
1610c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org    return reinterpret_cast<HUnaryOperation*>(value);
1611c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org  }
1612c54d36599f1e72bddd09d5b7a980304c7b638048ricow@chromium.org
1613c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  HValue* value() const { return OperandAt(0); }
1614ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1615a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1616a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1618ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HUseConst FINAL : public HUnaryOperation {
1619d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org public:
1620d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
1621d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
1622ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1623d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org    return Representation::None();
1624d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  }
1625d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
1626d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(UseConst)
1627d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1628d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org private:
1629d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    explicit HUseConst(HValue* old_value) : HUnaryOperation(old_value) { }
1630d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org};
1631d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
1632d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org
1633ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HForceRepresentation FINAL : public HTemplateInstruction<1> {
1634c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org public:
16359af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  static HInstruction* New(Zone* zone, HValue* context, HValue* value,
16369af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                           Representation required_representation);
1637c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1638f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  HValue* value() const { return OperandAt(0); }
1639c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1640ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1641c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    return representation();  // Same as the output representation.
1642c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
1643c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1644ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
16454cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org
1646c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
1647d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1648d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org private:
1649d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HForceRepresentation(HValue* value, Representation required_representation) {
1650d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetOperandAt(0, value);
1651d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    set_representation(required_representation);
1652d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1653c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org};
1654c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1655c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1656ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HChange FINAL : public HUnaryOperation {
1657a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1658a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  HChange(HValue* value,
16598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org          Representation to,
1660fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org          bool is_truncating_to_smi,
1661c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org          bool is_truncating_to_int32)
1662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : HUnaryOperation(value) {
1663e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!value->representation().IsNone());
1664e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!to.IsNone());
1665e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!value->representation().Equals(to));
1666a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    set_representation(to);
1667a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetFlag(kUseGVN);
1668381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org    SetFlag(kCanOverflow);
1669ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    if (is_truncating_to_smi && to.IsSmi()) {
1670662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      SetFlag(kTruncatingToSmi);
1671662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      SetFlag(kTruncatingToInt32);
1672662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    }
1673fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org    if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
1674a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    if (value->representation().IsSmi() || value->type().IsSmi()) {
167532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      set_type(HType::Smi());
167632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    } else {
167732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      set_type(HType::TaggedNumber());
1678f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
167932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    }
1680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1682c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  bool can_convert_undefined_to_nan() {
1683c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org    return CheckUsesForFlag(kAllowUndefinedAsNaN);
1684c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org  }
1685c00ec2b94bc5505fa81f81daefd956f5a8776a09danno@chromium.org
1686ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HType CalculateInferredType() OVERRIDE;
1687ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HValue* Canonicalize() OVERRIDE;
1688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1689c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  Representation from() const { return value()->representation(); }
1690c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  Representation to() const { return representation(); }
1691f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  bool deoptimize_on_minus_zero() const {
1692f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    return CheckFlag(kBailoutOnMinusZero);
1693f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
1694ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return from();
1696a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1697a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1698ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Range* InferRange(Zone* zone) OVERRIDE;
1699ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org
1700ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1702dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Change)
1703a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1704a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
1705ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
1706c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org
1707c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org private:
1708ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsDeletable() const OVERRIDE {
1709c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org    return !from().IsTagged() || value()->type().IsSmi();
1710c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org  }
1711a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1712a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1713a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1714ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HClampToUint8 FINAL : public HUnaryOperation {
1715c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org public:
1716d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
1717c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1718ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
171984bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org    return Representation::None();
1720c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
1721c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1722c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
1723c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1724c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org protected:
1725ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
1726c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org
1727c1956679bbba3170352a8cc735e8218f9dbe6867jkummerow@chromium.org private:
1728d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  explicit HClampToUint8(HValue* value)
1729d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org      : HUnaryOperation(value) {
1730d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    set_representation(Representation::Integer32());
1731d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetFlag(kAllowUndefinedAsNaN);
1732d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetFlag(kUseGVN);
1733d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1734d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
1735ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsDeletable() const OVERRIDE { return true; }
1736c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org};
1737c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1738c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1739ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HDoubleBits FINAL : public HUnaryOperation {
1740ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org public:
1741ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  enum Bits { HIGH, LOW };
1742ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P2(HDoubleBits, HValue*, Bits);
1743ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1744ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1745ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return Representation::Double();
1746ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
1747ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1748ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  DECLARE_CONCRETE_INSTRUCTION(DoubleBits)
1749ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1750ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  Bits bits() { return bits_; }
1751ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1752ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org protected:
1753ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool DataEquals(HValue* other) OVERRIDE {
1754ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return other->IsDoubleBits() && HDoubleBits::cast(other)->bits() == bits();
1755ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
1756ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1757ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org private:
1758ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HDoubleBits(HValue* value, Bits bits)
1759ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org      : HUnaryOperation(value), bits_(bits) {
1760ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    set_representation(Representation::Integer32());
1761ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    SetFlag(kUseGVN);
1762ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
1763ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1764ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsDeletable() const OVERRIDE { return true; }
1765ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1766ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  Bits bits_;
1767ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org};
1768ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1769ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1770ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HConstructDouble FINAL : public HTemplateInstruction<2> {
1771ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org public:
1772ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  DECLARE_INSTRUCTION_FACTORY_P2(HConstructDouble, HValue*, HValue*);
1773ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1774ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1775ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    return Representation::Integer32();
1776ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
1777ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1778ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  DECLARE_CONCRETE_INSTRUCTION(ConstructDouble)
1779ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1780ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* hi() { return OperandAt(0); }
1781ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  HValue* lo() { return OperandAt(1); }
1782ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1783ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org protected:
1784ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
1785ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1786ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org private:
1787ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  explicit HConstructDouble(HValue* hi, HValue* lo) {
1788ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    set_representation(Representation::Double());
1789ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    SetFlag(kUseGVN);
1790ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    SetOperandAt(0, hi);
1791ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org    SetOperandAt(1, lo);
1792ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org  }
1793ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1794ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool IsDeletable() const OVERRIDE { return true; }
1795ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org};
1796ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1797ca2f2040e0e1a10df95bec18e69499f85f4c1316machenbach@chromium.org
1798fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgenum RemovableSimulate {
1799fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  REMOVABLE_SIMULATE,
1800fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  FIXED_SIMULATE
1801fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org};
1802fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1803fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1804ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HSimulate FINAL : public HInstruction {
1805a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
1806fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  HSimulate(BailoutId ast_id,
1807fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            int pop_count,
1808fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            Zone* zone,
1809fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org            RemovableSimulate removable)
1810a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org      : ast_id_(ast_id),
1811a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org        pop_count_(pop_count),
18127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        values_(2, zone),
18137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        assigned_indexes_(2, zone),
1814fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        zone_(zone),
1815486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        removable_(removable),
1816486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        done_with_replay_(false) {}
181732cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  ~HSimulate() {}
1818a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1819ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1820a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1821471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  bool HasAstId() const { return !ast_id_.IsNone(); }
1822471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId ast_id() const { return ast_id_; }
1823471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void set_ast_id(BailoutId id) {
1824e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!HasAstId());
1825a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    ast_id_ = id;
1826a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1827a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1828a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int pop_count() const { return pop_count_; }
1829a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  const ZoneList<HValue*>* values() const { return &values_; }
1830a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int GetAssignedIndexAt(int index) const {
1831e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(HasAssignedIndexAt(index));
1832a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return assigned_indexes_[index];
1833a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1834a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  bool HasAssignedIndexAt(int index) const {
1835a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return assigned_indexes_[index] != kNoIndex;
1836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddAssignedValue(int index, HValue* value) {
1838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    AddValue(index, value);
1839a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1840a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddPushedValue(HValue* value) {
1841a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    AddValue(kNoIndex, value);
1842a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1843d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int ToOperandIndex(int environment_index) {
1844d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    for (int i = 0; i < assigned_indexes_.length(); ++i) {
1845d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      if (assigned_indexes_[i] == environment_index) return i;
1846d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    }
1847d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return -1;
1848d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
1849ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual int OperandCount() const OVERRIDE { return values_.length(); }
1850ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual HValue* OperandAt(int index) const OVERRIDE {
185132cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org    return values_[index];
185232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  }
18533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1854ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
1855ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
18563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::None();
18573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
1858a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1859e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void MergeWith(ZoneList<HSimulate*>* list);
1860fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
1861fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1862662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Replay effects of this instruction on the given environment.
1863662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void ReplayEnvironment(HEnvironment* env);
1864662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
1865dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(Simulate)
1866a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1867a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#ifdef DEBUG
1868ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void Verify() OVERRIDE;
1869d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
1870d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<JSFunction> closure() const { return closure_; }
1871a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#endif
1872a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1873a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org protected:
1874ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual void InternalSetOperandAt(int index, HValue* value) OVERRIDE {
1875a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    values_[index] = value;
1876a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1877a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1878a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
1879a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  static const int kNoIndex = -1;
1880a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void AddValue(int index, HValue* value) {
18817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    assigned_indexes_.Add(index, zone_);
1882a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Resize the list of pushed values.
18837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org    values_.Add(NULL, zone_);
1884a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // Set the operand through the base method in HValue to make sure that the
1885a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    // use lists are correctly updated.
1886a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    SetOperandAt(values_.length() - 1, value);
1887a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1888a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  bool HasValueForIndex(int index) {
1889a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    for (int i = 0; i < assigned_indexes_.length(); ++i) {
1890a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org      if (assigned_indexes_[i] == index) return true;
1891a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    }
1892a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org    return false;
1893a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  }
1894471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  BailoutId ast_id_;
1895a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  int pop_count_;
1896a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<HValue*> values_;
1897a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  ZoneList<int> assigned_indexes_;
18987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone_;
1899486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  RemovableSimulate removable_ : 2;
1900486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  bool done_with_replay_ : 1;
1901d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1902d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
1903d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<JSFunction> closure_;
1904d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
1905d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org};
1906d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1907d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1908ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HEnvironmentMarker FINAL : public HTemplateInstruction<1> {
1909d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org public:
1910d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  enum Kind { BIND, LOOKUP };
1911d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
191271f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  DECLARE_INSTRUCTION_FACTORY_P2(HEnvironmentMarker, Kind, int);
1913d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1914f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  Kind kind() const { return kind_; }
1915f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org  int index() const { return index_; }
1916d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HSimulate* next_simulate() { return next_simulate_; }
1917d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void set_next_simulate(HSimulate* simulate) {
1918d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    next_simulate_ = simulate;
1919d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
1920d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1921ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1922d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    return Representation::None();
1923d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
1924d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1925ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
1926d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1927d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
1928d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void set_closure(Handle<JSFunction> closure) {
1929e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(closure_.is_null());
1930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!closure.is_null());
1931d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    closure_ = closure;
1932d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  }
1933d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<JSFunction> closure() const { return closure_; }
1934d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
1935d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1936d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  DECLARE_CONCRETE_INSTRUCTION(EnvironmentMarker);
1937d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1938d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org private:
193971f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  HEnvironmentMarker(Kind kind, int index)
194071f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org      : kind_(kind), index_(index), next_simulate_(NULL) { }
194171f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
1942d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Kind kind_;
1943d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  int index_;
1944d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  HSimulate* next_simulate_;
1945d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1946d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#ifdef DEBUG
1947d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Handle<JSFunction> closure_;
1948d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org#endif
1949a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1950a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1951a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1952ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HStackCheck FINAL : public HTemplateInstruction<1> {
1953a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
195404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  enum Type {
195504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    kFunctionEntry,
195604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    kBackwardsBranch
195704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  };
195804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
19598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HStackCheck, Type);
1960ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org
1961ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org  HValue* context() { return OperandAt(0); }
1962a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1963ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
1964ddda9e81d3175130f2029c0e1205d265a00c32edjkummerow@chromium.org    return Representation::Tagged();
19653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
19663a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
196704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  void Eliminate() {
196804921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    // The stack check eliminator might try to eliminate the same stack
196904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    // check instruction multiple times.
197004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    if (IsLinked()) {
19717c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org      DeleteAndReplaceWith(NULL);
197204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    }
197304921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  }
197404921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
197504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  bool is_function_entry() { return type_ == kFunctionEntry; }
197604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  bool is_backwards_branch() { return type_ == kBackwardsBranch; }
197704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
1978dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(StackCheck)
197904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org
198004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org private:
1981d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  HStackCheck(HValue* context, Type type) : type_(type) {
1982d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org    SetOperandAt(0, context);
1983f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    SetChangesFlag(kNewSpacePromotion);
1984d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  }
1985d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
198604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  Type type_;
1987a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
1988a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1989a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1990471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgenum InliningKind {
1991a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org  NORMAL_RETURN,          // Drop the function from the environment on return.
1992471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  CONSTRUCT_CALL_RETURN,  // Either use allocated receiver or return value.
1993de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org  GETTER_CALL_RETURN,     // Returning from a getter, need to restore context.
1994471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  SETTER_CALL_RETURN      // Use the RHS of the assignment as the return value.
1995471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org};
1996471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1997471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org
1998b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgclass HArgumentsObject;
1999ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HConstant;
2000b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2001b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
2002ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HEnterInlined FINAL : public HTemplateInstruction<0> {
2003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2004ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  static HEnterInlined* New(Zone* zone, HValue* context, BailoutId return_id,
2005d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                            Handle<JSFunction> closure,
2006ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                            HConstant* closure_context, int arguments_count,
2007d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                            FunctionLiteral* function,
2008ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                            InliningKind inlining_kind, Variable* arguments_var,
2009e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                            HArgumentsObject* arguments_object) {
2010ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    return new (zone) HEnterInlined(return_id, closure, closure_context,
2011ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                    arguments_count, function, inlining_kind,
2012ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                    arguments_var, arguments_object, zone);
2013a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2014a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2015d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
2016d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
2017d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
2018ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
2019a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2020a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<JSFunction> closure() const { return closure_; }
2021ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  HConstant* closure_context() const { return closure_context_; }
2022659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int arguments_count() const { return arguments_count_; }
202356c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool arguments_pushed() const { return arguments_pushed_; }
202456c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  void set_arguments_pushed() { arguments_pushed_ = true; }
2025a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  FunctionLiteral* function() const { return function_; }
2026471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  InliningKind inlining_kind() const { return inlining_kind_; }
2027f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  BailoutId ReturnId() const { return return_id_; }
2028a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2029ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
20303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::None();
20313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
20323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
203328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  Variable* arguments_var() { return arguments_var_; }
2034b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object() { return arguments_object_; }
20358c0a43f09f145d9fc6f969d559873018176eeb6adanno@chromium.org
2036dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(EnterInlined)
2037a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2038a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org private:
2039ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  HEnterInlined(BailoutId return_id, Handle<JSFunction> closure,
2040ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                HConstant* closure_context, int arguments_count,
2041ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                FunctionLiteral* function, InliningKind inlining_kind,
2042ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                Variable* arguments_var, HArgumentsObject* arguments_object,
2043d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org                Zone* zone)
2044f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      : return_id_(return_id),
2045f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org        closure_(closure),
2046ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        closure_context_(closure_context),
2047d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        arguments_count_(arguments_count),
2048d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        arguments_pushed_(false),
2049d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        function_(function),
2050d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        inlining_kind_(inlining_kind),
2051d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        arguments_var_(arguments_var),
2052d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org        arguments_object_(arguments_object),
2053ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        return_targets_(2, zone) {}
2054d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
2055f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  BailoutId return_id_;
2056a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  Handle<JSFunction> closure_;
2057ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  HConstant* closure_context_;
2058659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org  int arguments_count_;
205956c14afabc547f0a8ab2e24d789c00030f8df892ulan@chromium.org  bool arguments_pushed_;
2060a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  FunctionLiteral* function_;
2061471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  InliningKind inlining_kind_;
206228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org  Variable* arguments_var_;
2063b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  HArgumentsObject* arguments_object_;
2064d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  ZoneList<HBasicBlock*> return_targets_;
2065a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2066a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2067a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2068ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HLeaveInlined FINAL : public HTemplateInstruction<0> {
2069a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
2070d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  HLeaveInlined(HEnterInlined* entry,
2071d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org                int drop_count)
2072d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : entry_(entry),
2073d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org        drop_count_(drop_count) { }
2074a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2075ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
20763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return Representation::None();
20773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
20783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
2079ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual int argument_delta() const OVERRIDE {
2080d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org    return entry_->arguments_pushed() ? -drop_count_ : 0;
2081d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  }
2082d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
2083dcebac0f4c6c0da579b7cc91a0cbba8f3c820c8dricow@chromium.org  DECLARE_CONCRETE_INSTRUCTION(LeaveInlined)
2084d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
2085d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org private:
2086d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  HEnterInlined* entry_;
2087d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  int drop_count_;
2088a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org};
2089a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2090a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2091ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass HPushArguments FINAL : public HInstruction {
2092a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org public:
20938d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  static HPushArguments* New(Zone* zone, HValue* context) {
20948d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return new(zone) HPushArguments(zone);
20958d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
20968d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  static HPushArguments* New(Zone* zone, HValue* context, HValue* arg1) {
20978d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    HPushArguments* instr = new(zone) HPushArguments(zone);
20988d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg1);
20998d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return instr;
21008d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
21018d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  static HPushArguments* New(Zone* zone, HValue* context, HValue* arg1,
21028d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                             HValue* arg2) {
21038d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    HPushArguments* instr = new(zone) HPushArguments(zone);
21048d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg1);
21058d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg2);
21068d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return instr;
21078d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
21088d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  static HPushArguments* New(Zone* zone, HValue* context, HValue* arg1,
21098d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                             HValue* arg2, HValue* arg3) {
21108d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    HPushArguments* instr = new(zone) HPushArguments(zone);
21118d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg1);
21128d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg2);
21138d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg3);
21148d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return instr;
21158d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
21168d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  static HPushArguments* New(Zone* zone, HValue* context, HValue* arg1,
21178d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org                             HValue* arg2, HValue* arg3, HValue* arg4) {
21188d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    HPushArguments* instr = new(zone) HPushArguments(zone);
21198d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg1);
21208d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg2);
21218d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg3);
21228d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    instr->AddInput(arg4);
21238d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    return instr;
21248d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org  }
2125a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
2126ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
2127a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    return Representation::Tagged();
2128a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
2129a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org