1 // Copyright 2014 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/assembler.h"
9 #include "src/base/compiler-specific.h"
10 #include "src/compiler/frame-states.h"
11 #include "src/deoptimize-reason.h"
12 #include "src/globals.h"
13 #include "src/machine-type.h"
14 #include "src/zone/zone-containers.h"
15
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19
20 // Forward declarations.
21 class CallDescriptor;
22 struct CommonOperatorGlobalCache;
23 class Operator;
24 class Type;
25
26 // Prediction hint for branches.
27 enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
28
NegateBranchHint(BranchHint hint)29 inline BranchHint NegateBranchHint(BranchHint hint) {
30 switch (hint) {
31 case BranchHint::kNone:
32 return hint;
33 case BranchHint::kTrue:
34 return BranchHint::kFalse;
35 case BranchHint::kFalse:
36 return BranchHint::kTrue;
37 }
38 UNREACHABLE();
39 return hint;
40 }
41
hash_value(BranchHint hint)42 inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
43
44 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchHint);
45
46 V8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const);
47
48 // Deoptimize reason for Deoptimize, DeoptimizeIf and DeoptimizeUnless.
49 DeoptimizeReason DeoptimizeReasonOf(Operator const* const);
50
51 // Deoptimize bailout kind.
52 enum class DeoptimizeKind : uint8_t { kEager, kSoft };
53
54 size_t hash_value(DeoptimizeKind kind);
55
56 std::ostream& operator<<(std::ostream&, DeoptimizeKind);
57
58 // Parameters for the {Deoptimize} operator.
59 class DeoptimizeParameters final {
60 public:
DeoptimizeParameters(DeoptimizeKind kind,DeoptimizeReason reason)61 DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason)
62 : kind_(kind), reason_(reason) {}
63
kind()64 DeoptimizeKind kind() const { return kind_; }
reason()65 DeoptimizeReason reason() const { return reason_; }
66
67 private:
68 DeoptimizeKind const kind_;
69 DeoptimizeReason const reason_;
70 };
71
72 bool operator==(DeoptimizeParameters, DeoptimizeParameters);
73 bool operator!=(DeoptimizeParameters, DeoptimizeParameters);
74
75 size_t hast_value(DeoptimizeParameters p);
76
77 std::ostream& operator<<(std::ostream&, DeoptimizeParameters p);
78
79 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const);
80
81
82 class SelectParameters final {
83 public:
84 explicit SelectParameters(MachineRepresentation representation,
85 BranchHint hint = BranchHint::kNone)
representation_(representation)86 : representation_(representation), hint_(hint) {}
87
representation()88 MachineRepresentation representation() const { return representation_; }
hint()89 BranchHint hint() const { return hint_; }
90
91 private:
92 const MachineRepresentation representation_;
93 const BranchHint hint_;
94 };
95
96 bool operator==(SelectParameters const&, SelectParameters const&);
97 bool operator!=(SelectParameters const&, SelectParameters const&);
98
99 size_t hash_value(SelectParameters const& p);
100
101 std::ostream& operator<<(std::ostream&, SelectParameters const& p);
102
103 V8_EXPORT_PRIVATE SelectParameters const& SelectParametersOf(
104 const Operator* const);
105
106 V8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const);
107
108 V8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const);
109
110 V8_EXPORT_PRIVATE MachineRepresentation
111 PhiRepresentationOf(const Operator* const);
112
113 // The {IrOpcode::kParameter} opcode represents an incoming parameter to the
114 // function. This class bundles the index and a debug name for such operators.
115 class ParameterInfo final {
116 public:
ParameterInfo(int index,const char * debug_name)117 ParameterInfo(int index, const char* debug_name)
118 : index_(index), debug_name_(debug_name) {}
119
index()120 int index() const { return index_; }
debug_name()121 const char* debug_name() const { return debug_name_; }
122
123 private:
124 int index_;
125 const char* debug_name_;
126 };
127
128 std::ostream& operator<<(std::ostream&, ParameterInfo const&);
129
130 V8_EXPORT_PRIVATE int ParameterIndexOf(const Operator* const);
131 const ParameterInfo& ParameterInfoOf(const Operator* const);
132
133 class RelocatablePtrConstantInfo final {
134 public:
135 enum Type { kInt32, kInt64 };
136
RelocatablePtrConstantInfo(int32_t value,RelocInfo::Mode rmode)137 RelocatablePtrConstantInfo(int32_t value, RelocInfo::Mode rmode)
138 : value_(value), rmode_(rmode), type_(kInt32) {}
RelocatablePtrConstantInfo(int64_t value,RelocInfo::Mode rmode)139 RelocatablePtrConstantInfo(int64_t value, RelocInfo::Mode rmode)
140 : value_(value), rmode_(rmode), type_(kInt64) {}
141
value()142 intptr_t value() const { return value_; }
rmode()143 RelocInfo::Mode rmode() const { return rmode_; }
type()144 Type type() const { return type_; }
145
146 private:
147 intptr_t value_;
148 RelocInfo::Mode rmode_;
149 Type type_;
150 };
151
152 bool operator==(RelocatablePtrConstantInfo const& lhs,
153 RelocatablePtrConstantInfo const& rhs);
154 bool operator!=(RelocatablePtrConstantInfo const& lhs,
155 RelocatablePtrConstantInfo const& rhs);
156
157 std::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&);
158
159 size_t hash_value(RelocatablePtrConstantInfo const& p);
160
161 // Used to mark a region (as identified by BeginRegion/FinishRegion) as either
162 // JavaScript-observable or not (i.e. allocations are not JavaScript observable
163 // themselves, but transitioning stores are).
164 enum class RegionObservability : uint8_t { kObservable, kNotObservable };
165
166 size_t hash_value(RegionObservability);
167
168 std::ostream& operator<<(std::ostream&, RegionObservability);
169
170 RegionObservability RegionObservabilityOf(Operator const*) WARN_UNUSED_RESULT;
171
172 std::ostream& operator<<(std::ostream& os,
173 const ZoneVector<MachineType>* types);
174
175 Type* TypeGuardTypeOf(Operator const*) WARN_UNUSED_RESULT;
176
177 int OsrValueIndexOf(Operator const*);
178
179 enum class OsrGuardType { kUninitialized, kSignedSmall, kAny };
180 size_t hash_value(OsrGuardType type);
181 std::ostream& operator<<(std::ostream&, OsrGuardType);
182 OsrGuardType OsrGuardTypeOf(Operator const*);
183
184 ZoneVector<MachineType> const* MachineTypesOf(Operator const*)
185 WARN_UNUSED_RESULT;
186
187 // Interface for building common operators that can be used at any level of IR,
188 // including JavaScript, mid-level, and low-level.
189 class V8_EXPORT_PRIVATE CommonOperatorBuilder final
NON_EXPORTED_BASE(ZoneObject)190 : public NON_EXPORTED_BASE(ZoneObject) {
191 public:
192 explicit CommonOperatorBuilder(Zone* zone);
193
194 const Operator* Dead();
195 const Operator* End(size_t control_input_count);
196 const Operator* Branch(BranchHint = BranchHint::kNone);
197 const Operator* IfTrue();
198 const Operator* IfFalse();
199 const Operator* IfSuccess();
200 const Operator* IfException();
201 const Operator* Switch(size_t control_output_count);
202 const Operator* IfValue(int32_t value);
203 const Operator* IfDefault();
204 const Operator* Throw();
205 const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason);
206 const Operator* DeoptimizeIf(DeoptimizeReason reason);
207 const Operator* DeoptimizeUnless(DeoptimizeReason reason);
208 const Operator* Return(int value_input_count = 1);
209 const Operator* Terminate();
210
211 const Operator* Start(int value_output_count);
212 const Operator* Loop(int control_input_count);
213 const Operator* Merge(int control_input_count);
214 const Operator* Parameter(int index, const char* debug_name = nullptr);
215
216 const Operator* OsrNormalEntry();
217 const Operator* OsrLoopEntry();
218 const Operator* OsrValue(int index);
219 const Operator* OsrGuard(OsrGuardType type);
220
221 const Operator* Int32Constant(int32_t);
222 const Operator* Int64Constant(int64_t);
223 const Operator* Float32Constant(volatile float);
224 const Operator* Float64Constant(volatile double);
225 const Operator* ExternalConstant(const ExternalReference&);
226 const Operator* NumberConstant(volatile double);
227 const Operator* PointerConstant(intptr_t);
228 const Operator* HeapConstant(const Handle<HeapObject>&);
229
230 const Operator* RelocatableInt32Constant(int32_t value,
231 RelocInfo::Mode rmode);
232 const Operator* RelocatableInt64Constant(int64_t value,
233 RelocInfo::Mode rmode);
234
235 const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
236 const Operator* Phi(MachineRepresentation representation,
237 int value_input_count);
238 const Operator* EffectPhi(int effect_input_count);
239 const Operator* InductionVariablePhi(int value_input_count);
240 const Operator* LoopExit();
241 const Operator* LoopExitValue();
242 const Operator* LoopExitEffect();
243 const Operator* Checkpoint();
244 const Operator* BeginRegion(RegionObservability);
245 const Operator* FinishRegion();
246 const Operator* StateValues(int arguments);
247 const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
248 const Operator* ObjectState(int pointer_slots);
249 const Operator* TypedObjectState(const ZoneVector<MachineType>* types);
250 const Operator* FrameState(BailoutId bailout_id,
251 OutputFrameStateCombine state_combine,
252 const FrameStateFunctionInfo* function_info);
253 const Operator* Call(const CallDescriptor* descriptor);
254 const Operator* TailCall(const CallDescriptor* descriptor);
255 const Operator* Projection(size_t index);
256 const Operator* Retain();
257 const Operator* TypeGuard(Type* type);
258
259 // Constructs a new merge or phi operator with the same opcode as {op}, but
260 // with {size} inputs.
261 const Operator* ResizeMergeOrPhi(const Operator* op, int size);
262
263 // Constructs function info for frame state construction.
264 const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
265 FrameStateType type, int parameter_count, int local_count,
266 Handle<SharedFunctionInfo> shared_info);
267
268 private:
269 Zone* zone() const { return zone_; }
270
271 const CommonOperatorGlobalCache& cache_;
272 Zone* const zone_;
273
274 DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
275 };
276
277 } // namespace compiler
278 } // namespace internal
279 } // namespace v8
280
281 #endif // V8_COMPILER_COMMON_OPERATOR_H_
282