9f2c5751630dbdcf00aa3926003e04dee36bdb3e
[platform/upstream/nodejs.git] / deps / v8 / src / compiler / common-operator.h
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_COMPILER_COMMON_OPERATOR_H_
6 #define V8_COMPILER_COMMON_OPERATOR_H_
7
8 #include "src/compiler/machine-type.h"
9 #include "src/unique.h"
10
11 namespace v8 {
12 namespace internal {
13
14 // Forward declarations.
15 class ExternalReference;
16
17
18 namespace compiler {
19
20 // Forward declarations.
21 class CallDescriptor;
22 struct CommonOperatorGlobalCache;
23 class Operator;
24
25
26 // Prediction hint for branches.
27 enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
28
29 inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
30
31 std::ostream& operator<<(std::ostream&, BranchHint);
32
33 BranchHint BranchHintOf(const Operator* const);
34
35
36 class SelectParameters FINAL {
37  public:
38   explicit SelectParameters(MachineType type,
39                             BranchHint hint = BranchHint::kNone)
40       : type_(type), hint_(hint) {}
41
42   MachineType type() const { return type_; }
43   BranchHint hint() const { return hint_; }
44
45  private:
46   const MachineType type_;
47   const BranchHint hint_;
48 };
49
50 bool operator==(SelectParameters const&, SelectParameters const&);
51 bool operator!=(SelectParameters const&, SelectParameters const&);
52
53 size_t hash_value(SelectParameters const& p);
54
55 std::ostream& operator<<(std::ostream&, SelectParameters const& p);
56
57 SelectParameters const& SelectParametersOf(const Operator* const);
58
59
60 // Flag that describes how to combine the current environment with
61 // the output of a node to obtain a framestate for lazy bailout.
62 class OutputFrameStateCombine {
63  public:
64   enum Kind {
65     kPushOutput,  // Push the output on the expression stack.
66     kPokeAt       // Poke at the given environment location,
67                   // counting from the top of the stack.
68   };
69
70   static OutputFrameStateCombine Ignore() {
71     return OutputFrameStateCombine(kPushOutput, 0);
72   }
73   static OutputFrameStateCombine Push(size_t count = 1) {
74     return OutputFrameStateCombine(kPushOutput, count);
75   }
76   static OutputFrameStateCombine PokeAt(size_t index) {
77     return OutputFrameStateCombine(kPokeAt, index);
78   }
79
80   Kind kind() const { return kind_; }
81   size_t GetPushCount() const {
82     DCHECK_EQ(kPushOutput, kind());
83     return parameter_;
84   }
85   size_t GetOffsetToPokeAt() const {
86     DCHECK_EQ(kPokeAt, kind());
87     return parameter_;
88   }
89
90   bool IsOutputIgnored() const {
91     return kind_ == kPushOutput && parameter_ == 0;
92   }
93
94   size_t ConsumedOutputCount() const {
95     return kind_ == kPushOutput ? GetPushCount() : 1;
96   }
97
98   bool operator==(OutputFrameStateCombine const& other) const {
99     return kind_ == other.kind_ && parameter_ == other.parameter_;
100   }
101   bool operator!=(OutputFrameStateCombine const& other) const {
102     return !(*this == other);
103   }
104
105   friend size_t hash_value(OutputFrameStateCombine const&);
106   friend std::ostream& operator<<(std::ostream&,
107                                   OutputFrameStateCombine const&);
108
109  private:
110   OutputFrameStateCombine(Kind kind, size_t parameter)
111       : kind_(kind), parameter_(parameter) {}
112
113   Kind const kind_;
114   size_t const parameter_;
115 };
116
117
118 // The type of stack frame that a FrameState node represents.
119 enum FrameStateType {
120   JS_FRAME,          // Represents an unoptimized JavaScriptFrame.
121   ARGUMENTS_ADAPTOR  // Represents an ArgumentsAdaptorFrame.
122 };
123
124
125 class FrameStateCallInfo FINAL {
126  public:
127   FrameStateCallInfo(
128       FrameStateType type, BailoutId bailout_id,
129       OutputFrameStateCombine state_combine,
130       MaybeHandle<JSFunction> jsfunction = MaybeHandle<JSFunction>())
131       : type_(type),
132         bailout_id_(bailout_id),
133         frame_state_combine_(state_combine),
134         jsfunction_(jsfunction) {}
135
136   FrameStateType type() const { return type_; }
137   BailoutId bailout_id() const { return bailout_id_; }
138   OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
139   MaybeHandle<JSFunction> jsfunction() const { return jsfunction_; }
140
141  private:
142   FrameStateType type_;
143   BailoutId bailout_id_;
144   OutputFrameStateCombine frame_state_combine_;
145   MaybeHandle<JSFunction> jsfunction_;
146 };
147
148 bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
149 bool operator!=(FrameStateCallInfo const&, FrameStateCallInfo const&);
150
151 size_t hash_value(FrameStateCallInfo const&);
152
153 std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
154
155
156 size_t ProjectionIndexOf(const Operator* const);
157
158
159 // Interface for building common operators that can be used at any level of IR,
160 // including JavaScript, mid-level, and low-level.
161 class CommonOperatorBuilder FINAL : public ZoneObject {
162  public:
163   explicit CommonOperatorBuilder(Zone* zone);
164
165   // Special operator used only in Branches to mark them as always taken, but
166   // still unfoldable. This is required to properly connect non terminating
167   // loops to end (in both the sea of nodes and the CFG).
168   const Operator* Always();
169
170   const Operator* Dead();
171   const Operator* End();
172   const Operator* Branch(BranchHint = BranchHint::kNone);
173   const Operator* IfTrue();
174   const Operator* IfFalse();
175   const Operator* Switch(size_t control_output_count);
176   const Operator* IfValue(int32_t value);
177   const Operator* IfDefault();
178   const Operator* Throw();
179   const Operator* Return();
180
181   const Operator* Start(int num_formal_parameters);
182   const Operator* Loop(int control_input_count);
183   const Operator* Merge(int control_input_count);
184   const Operator* Parameter(int index);
185
186   const Operator* OsrNormalEntry();
187   const Operator* OsrLoopEntry();
188   const Operator* OsrValue(int index);
189
190   const Operator* Int32Constant(int32_t);
191   const Operator* Int64Constant(int64_t);
192   const Operator* Float32Constant(volatile float);
193   const Operator* Float64Constant(volatile double);
194   const Operator* ExternalConstant(const ExternalReference&);
195   const Operator* NumberConstant(volatile double);
196   const Operator* HeapConstant(const Unique<HeapObject>&);
197
198   const Operator* Select(MachineType, BranchHint = BranchHint::kNone);
199   const Operator* Phi(MachineType type, int arguments);
200   const Operator* EffectPhi(int arguments);
201   const Operator* EffectSet(int arguments);
202   const Operator* ValueEffect(int arguments);
203   const Operator* Finish(int arguments);
204   const Operator* StateValues(int arguments);
205   const Operator* FrameState(
206       FrameStateType type, BailoutId bailout_id,
207       OutputFrameStateCombine state_combine,
208       MaybeHandle<JSFunction> jsfunction = MaybeHandle<JSFunction>());
209   const Operator* Call(const CallDescriptor* descriptor);
210   const Operator* Projection(size_t index);
211
212   // Constructs a new merge or phi operator with the same opcode as {op}, but
213   // with {size} inputs.
214   const Operator* ResizeMergeOrPhi(const Operator* op, int size);
215
216  private:
217   Zone* zone() const { return zone_; }
218
219   const CommonOperatorGlobalCache& cache_;
220   Zone* const zone_;
221
222   DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
223 };
224
225 }  // namespace compiler
226 }  // namespace internal
227 }  // namespace v8
228
229 #endif  // V8_COMPILER_COMMON_OPERATOR_H_