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