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/compiler/frame-states.h"
9 #include "src/machine-type.h"
10 #include "src/zone-containers.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // Forward declarations.
16 class ExternalReference;
17 template <class>
18 class TypeImpl;
19 struct ZoneTypeConfig;
20 typedef TypeImpl<ZoneTypeConfig> Type;
21 
22 
23 namespace compiler {
24 
25 // Forward declarations.
26 class CallDescriptor;
27 struct CommonOperatorGlobalCache;
28 class Operator;
29 
30 
31 // Prediction hint for branches.
32 enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
33 
NegateBranchHint(BranchHint hint)34 inline BranchHint NegateBranchHint(BranchHint hint) {
35   switch (hint) {
36     case BranchHint::kNone:
37       return hint;
38     case BranchHint::kTrue:
39       return BranchHint::kFalse;
40     case BranchHint::kFalse:
41       return BranchHint::kTrue;
42   }
43   UNREACHABLE();
44   return hint;
45 }
46 
hash_value(BranchHint hint)47 inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
48 
49 std::ostream& operator<<(std::ostream&, BranchHint);
50 
51 BranchHint BranchHintOf(const Operator* const);
52 
53 
54 // Deoptimize bailout kind.
55 enum class DeoptimizeKind : uint8_t { kEager, kSoft };
56 
57 size_t hash_value(DeoptimizeKind kind);
58 
59 std::ostream& operator<<(std::ostream&, DeoptimizeKind);
60 
61 DeoptimizeKind DeoptimizeKindOf(const Operator* const);
62 
63 
64 // Prediction whether throw-site is surrounded by any local catch-scope.
65 enum class IfExceptionHint { kLocallyUncaught, kLocallyCaught };
66 
67 size_t hash_value(IfExceptionHint hint);
68 
69 std::ostream& operator<<(std::ostream&, IfExceptionHint);
70 
71 
72 class SelectParameters final {
73  public:
74   explicit SelectParameters(MachineRepresentation representation,
75                             BranchHint hint = BranchHint::kNone)
representation_(representation)76       : representation_(representation), hint_(hint) {}
77 
representation()78   MachineRepresentation representation() const { return representation_; }
hint()79   BranchHint hint() const { return hint_; }
80 
81  private:
82   const MachineRepresentation representation_;
83   const BranchHint hint_;
84 };
85 
86 bool operator==(SelectParameters const&, SelectParameters const&);
87 bool operator!=(SelectParameters const&, SelectParameters const&);
88 
89 size_t hash_value(SelectParameters const& p);
90 
91 std::ostream& operator<<(std::ostream&, SelectParameters const& p);
92 
93 SelectParameters const& SelectParametersOf(const Operator* const);
94 
95 
96 size_t ProjectionIndexOf(const Operator* const);
97 
98 MachineRepresentation PhiRepresentationOf(const Operator* const);
99 
100 
101 // The {IrOpcode::kParameter} opcode represents an incoming parameter to the
102 // function. This class bundles the index and a debug name for such operators.
103 class ParameterInfo final {
104  public:
ParameterInfo(int index,const char * debug_name)105   ParameterInfo(int index, const char* debug_name)
106       : index_(index), debug_name_(debug_name) {}
107 
index()108   int index() const { return index_; }
debug_name()109   const char* debug_name() const { return debug_name_; }
110 
111  private:
112   int index_;
113   const char* debug_name_;
114 };
115 
116 std::ostream& operator<<(std::ostream&, ParameterInfo const&);
117 
118 int ParameterIndexOf(const Operator* const);
119 const ParameterInfo& ParameterInfoOf(const Operator* const);
120 
121 
122 // Interface for building common operators that can be used at any level of IR,
123 // including JavaScript, mid-level, and low-level.
124 class CommonOperatorBuilder final : public ZoneObject {
125  public:
126   explicit CommonOperatorBuilder(Zone* zone);
127 
128   const Operator* Dead();
129   const Operator* End(size_t control_input_count);
130   const Operator* Branch(BranchHint = BranchHint::kNone);
131   const Operator* IfTrue();
132   const Operator* IfFalse();
133   const Operator* IfSuccess();
134   const Operator* IfException(IfExceptionHint hint);
135   const Operator* Switch(size_t control_output_count);
136   const Operator* IfValue(int32_t value);
137   const Operator* IfDefault();
138   const Operator* Throw();
139   const Operator* Deoptimize(DeoptimizeKind kind);
140   const Operator* Return(int value_input_count = 1);
141   const Operator* Terminate();
142 
143   const Operator* Start(int value_output_count);
144   const Operator* Loop(int control_input_count);
145   const Operator* Merge(int control_input_count);
146   const Operator* Parameter(int index, const char* debug_name = nullptr);
147 
148   const Operator* OsrNormalEntry();
149   const Operator* OsrLoopEntry();
150   const Operator* OsrValue(int index);
151 
152   const Operator* Int32Constant(int32_t);
153   const Operator* Int64Constant(int64_t);
154   const Operator* Float32Constant(volatile float);
155   const Operator* Float64Constant(volatile double);
156   const Operator* ExternalConstant(const ExternalReference&);
157   const Operator* NumberConstant(volatile double);
158   const Operator* HeapConstant(const Handle<HeapObject>&);
159 
160   const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
161   const Operator* Phi(MachineRepresentation representation,
162                       int value_input_count);
163   const Operator* EffectPhi(int effect_input_count);
164   const Operator* EffectSet(int arguments);
165   const Operator* Guard(Type* type);
166   const Operator* BeginRegion();
167   const Operator* FinishRegion();
168   const Operator* StateValues(int arguments);
169   const Operator* ObjectState(int pointer_slots, int id);
170   const Operator* TypedStateValues(const ZoneVector<MachineType>* types);
171   const Operator* FrameState(BailoutId bailout_id,
172                              OutputFrameStateCombine state_combine,
173                              const FrameStateFunctionInfo* function_info);
174   const Operator* Call(const CallDescriptor* descriptor);
175   const Operator* TailCall(const CallDescriptor* descriptor);
176   const Operator* Projection(size_t index);
177   const Operator* LazyBailout();
178 
179   // Constructs a new merge or phi operator with the same opcode as {op}, but
180   // with {size} inputs.
181   const Operator* ResizeMergeOrPhi(const Operator* op, int size);
182 
183   // Constructs function info for frame state construction.
184   const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
185       FrameStateType type, int parameter_count, int local_count,
186       Handle<SharedFunctionInfo> shared_info,
187       ContextCallingMode context_calling_mode);
188 
189  private:
zone()190   Zone* zone() const { return zone_; }
191 
192   const CommonOperatorGlobalCache& cache_;
193   Zone* const zone_;
194 
195   DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
196 };
197 
198 }  // namespace compiler
199 }  // namespace internal
200 }  // namespace v8
201 
202 #endif  // V8_COMPILER_COMMON_OPERATOR_H_
203