• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #include "src/compiler/graph-assembler.h"
6 
7 #include "src/code-factory.h"
8 #include "src/compiler/linkage.h"
9 #include "src/objects-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
GraphAssembler(JSGraph * jsgraph,Node * effect,Node * control,Zone * zone)15 GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
16                                Zone* zone)
17     : temp_zone_(zone),
18       jsgraph_(jsgraph),
19       current_effect_(effect),
20       current_control_(control) {}
21 
IntPtrConstant(intptr_t value)22 Node* GraphAssembler::IntPtrConstant(intptr_t value) {
23   return jsgraph()->IntPtrConstant(value);
24 }
25 
Int32Constant(int32_t value)26 Node* GraphAssembler::Int32Constant(int32_t value) {
27   return jsgraph()->Int32Constant(value);
28 }
29 
UniqueInt32Constant(int32_t value)30 Node* GraphAssembler::UniqueInt32Constant(int32_t value) {
31   return graph()->NewNode(common()->Int32Constant(value));
32 }
33 
SmiConstant(int32_t value)34 Node* GraphAssembler::SmiConstant(int32_t value) {
35   return jsgraph()->SmiConstant(value);
36 }
37 
Uint32Constant(int32_t value)38 Node* GraphAssembler::Uint32Constant(int32_t value) {
39   return jsgraph()->Uint32Constant(value);
40 }
41 
Float64Constant(double value)42 Node* GraphAssembler::Float64Constant(double value) {
43   return jsgraph()->Float64Constant(value);
44 }
45 
HeapConstant(Handle<HeapObject> object)46 Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
47   return jsgraph()->HeapConstant(object);
48 }
49 
50 
ExternalConstant(ExternalReference ref)51 Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
52   return jsgraph()->ExternalConstant(ref);
53 }
54 
CEntryStubConstant(int result_size)55 Node* GraphAssembler::CEntryStubConstant(int result_size) {
56   return jsgraph()->CEntryStubConstant(result_size);
57 }
58 
59 #define SINGLETON_CONST_DEF(Name) \
60   Node* GraphAssembler::Name() { return jsgraph()->Name(); }
61 JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
62 #undef SINGLETON_CONST_DEF
63 
64 #define PURE_UNOP_DEF(Name)                            \
65   Node* GraphAssembler::Name(Node* input) {            \
66     return graph()->NewNode(machine()->Name(), input); \
67   }
PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)68 PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
69 #undef PURE_UNOP_DEF
70 
71 #define PURE_BINOP_DEF(Name)                                 \
72   Node* GraphAssembler::Name(Node* left, Node* right) {      \
73     return graph()->NewNode(machine()->Name(), left, right); \
74   }
75 PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
76 #undef PURE_BINOP_DEF
77 
78 #define CHECKED_BINOP_DEF(Name)                                                \
79   Node* GraphAssembler::Name(Node* left, Node* right) {                        \
80     return graph()->NewNode(machine()->Name(), left, right, current_control_); \
81   }
82 CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
83 #undef CHECKED_BINOP_DEF
84 
85 Node* GraphAssembler::Float64RoundDown(Node* value) {
86   if (machine()->Float64RoundDown().IsSupported()) {
87     return graph()->NewNode(machine()->Float64RoundDown().op(), value);
88   }
89   return nullptr;
90 }
91 
Projection(int index,Node * value)92 Node* GraphAssembler::Projection(int index, Node* value) {
93   return graph()->NewNode(common()->Projection(index), value, current_control_);
94 }
95 
Allocate(PretenureFlag pretenure,Node * size)96 Node* GraphAssembler::Allocate(PretenureFlag pretenure, Node* size) {
97   return current_effect_ =
98              graph()->NewNode(simplified()->Allocate(NOT_TENURED), size,
99                               current_effect_, current_control_);
100 }
101 
LoadField(FieldAccess const & access,Node * object)102 Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
103   return current_effect_ =
104              graph()->NewNode(simplified()->LoadField(access), object,
105                               current_effect_, current_control_);
106 }
107 
LoadElement(ElementAccess const & access,Node * object,Node * index)108 Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
109                                   Node* index) {
110   return current_effect_ =
111              graph()->NewNode(simplified()->LoadElement(access), object, index,
112                               current_effect_, current_control_);
113 }
114 
StoreField(FieldAccess const & access,Node * object,Node * value)115 Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
116                                  Node* value) {
117   return current_effect_ =
118              graph()->NewNode(simplified()->StoreField(access), object, value,
119                               current_effect_, current_control_);
120 }
121 
StoreElement(ElementAccess const & access,Node * object,Node * index,Node * value)122 Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
123                                    Node* index, Node* value) {
124   return current_effect_ =
125              graph()->NewNode(simplified()->StoreElement(access), object, index,
126                               value, current_effect_, current_control_);
127 }
128 
Store(StoreRepresentation rep,Node * object,Node * offset,Node * value)129 Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
130                             Node* value) {
131   return current_effect_ =
132              graph()->NewNode(machine()->Store(rep), object, offset, value,
133                               current_effect_, current_control_);
134 }
135 
Load(MachineType rep,Node * object,Node * offset)136 Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
137   return current_effect_ =
138              graph()->NewNode(machine()->Load(rep), object, offset,
139                               current_effect_, current_control_);
140 }
141 
Retain(Node * buffer)142 Node* GraphAssembler::Retain(Node* buffer) {
143   return current_effect_ =
144              graph()->NewNode(common()->Retain(), buffer, current_effect_);
145 }
146 
UnsafePointerAdd(Node * base,Node * external)147 Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
148   return current_effect_ =
149              graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
150                               current_effect_, current_control_);
151 }
152 
ToNumber(Node * value)153 Node* GraphAssembler::ToNumber(Node* value) {
154   return current_effect_ =
155              graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
156                               value, NoContextConstant(), current_effect_);
157 }
158 
DeoptimizeIf(DeoptimizeReason reason,Node * condition,Node * frame_state)159 Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason, Node* condition,
160                                    Node* frame_state) {
161   return current_control_ = current_effect_ = graph()->NewNode(
162              common()->DeoptimizeIf(DeoptimizeKind::kEager, reason), condition,
163              frame_state, current_effect_, current_control_);
164 }
165 
DeoptimizeUnless(DeoptimizeKind kind,DeoptimizeReason reason,Node * condition,Node * frame_state)166 Node* GraphAssembler::DeoptimizeUnless(DeoptimizeKind kind,
167                                        DeoptimizeReason reason, Node* condition,
168                                        Node* frame_state) {
169   return current_control_ = current_effect_ = graph()->NewNode(
170              common()->DeoptimizeUnless(kind, reason), condition, frame_state,
171              current_effect_, current_control_);
172 }
173 
DeoptimizeUnless(DeoptimizeReason reason,Node * condition,Node * frame_state)174 Node* GraphAssembler::DeoptimizeUnless(DeoptimizeReason reason, Node* condition,
175                                        Node* frame_state) {
176   return DeoptimizeUnless(DeoptimizeKind::kEager, reason, condition,
177                           frame_state);
178 }
179 
Branch(Node * condition,GraphAssemblerStaticLabel<1> * if_true,GraphAssemblerStaticLabel<1> * if_false)180 void GraphAssembler::Branch(Node* condition,
181                             GraphAssemblerStaticLabel<1>* if_true,
182                             GraphAssemblerStaticLabel<1>* if_false) {
183   DCHECK_NOT_NULL(current_control_);
184 
185   BranchHint hint = BranchHint::kNone;
186   if (if_true->IsDeferred() != if_false->IsDeferred()) {
187     hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
188   }
189 
190   Node* branch =
191       graph()->NewNode(common()->Branch(hint), condition, current_control_);
192 
193   current_control_ = graph()->NewNode(common()->IfTrue(), branch);
194   MergeState(if_true);
195 
196   current_control_ = graph()->NewNode(common()->IfFalse(), branch);
197   MergeState(if_false);
198 
199   current_control_ = nullptr;
200   current_effect_ = nullptr;
201 }
202 
203 // Extractors (should be only used when destructing the assembler.
ExtractCurrentControl()204 Node* GraphAssembler::ExtractCurrentControl() {
205   Node* result = current_control_;
206   current_control_ = nullptr;
207   return result;
208 }
209 
ExtractCurrentEffect()210 Node* GraphAssembler::ExtractCurrentEffect() {
211   Node* result = current_effect_;
212   current_effect_ = nullptr;
213   return result;
214 }
215 
Reset(Node * effect,Node * control)216 void GraphAssembler::Reset(Node* effect, Node* control) {
217   current_effect_ = effect;
218   current_control_ = control;
219 }
220 
ToNumberOperator()221 Operator const* GraphAssembler::ToNumberOperator() {
222   if (!to_number_operator_.is_set()) {
223     Callable callable = CodeFactory::ToNumber(jsgraph()->isolate());
224     CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
225     CallDescriptor* desc = Linkage::GetStubCallDescriptor(
226         jsgraph()->isolate(), graph()->zone(), callable.descriptor(), 0, flags,
227         Operator::kEliminatable);
228     to_number_operator_.set(common()->Call(desc));
229   }
230   return to_number_operator_.get();
231 }
232 
PhiAt(size_t index)233 Node* GraphAssemblerLabel::PhiAt(size_t index) {
234   DCHECK(IsBound());
235   return GetBindingsPtrFor(index)[0];
236 }
237 
GraphAssemblerLabel(GraphAssemblerLabelType is_deferred,size_t merge_count,size_t var_count,MachineRepresentation * representations,Zone * zone)238 GraphAssemblerLabel::GraphAssemblerLabel(GraphAssemblerLabelType is_deferred,
239                                          size_t merge_count, size_t var_count,
240                                          MachineRepresentation* representations,
241                                          Zone* zone)
242     : is_deferred_(is_deferred == GraphAssemblerLabelType::kDeferred),
243       max_merge_count_(merge_count),
244       var_count_(var_count) {
245   effects_ = zone->NewArray<Node*>(MaxMergeCount() + 1);
246   for (size_t i = 0; i < MaxMergeCount() + 1; i++) {
247     effects_[i] = nullptr;
248   }
249 
250   controls_ = zone->NewArray<Node*>(MaxMergeCount());
251   for (size_t i = 0; i < MaxMergeCount(); i++) {
252     controls_[i] = nullptr;
253   }
254 
255   size_t num_bindings = (MaxMergeCount() + 1) * PhiCount() + 1;
256   bindings_ = zone->NewArray<Node*>(num_bindings);
257   for (size_t i = 0; i < num_bindings; i++) {
258     bindings_[i] = nullptr;
259   }
260 
261   representations_ = zone->NewArray<MachineRepresentation>(PhiCount() + 1);
262   for (size_t i = 0; i < PhiCount(); i++) {
263     representations_[i] = representations[i];
264   }
265 }
266 
~GraphAssemblerLabel()267 GraphAssemblerLabel::~GraphAssemblerLabel() {
268   DCHECK(IsBound() || MergedCount() == 0);
269 }
270 
GetBindingsPtrFor(size_t phi_index)271 Node** GraphAssemblerLabel::GetBindingsPtrFor(size_t phi_index) {
272   DCHECK_LT(phi_index, PhiCount());
273   return &bindings_[phi_index * (MaxMergeCount() + 1)];
274 }
275 
SetBinding(size_t phi_index,size_t merge_index,Node * binding)276 void GraphAssemblerLabel::SetBinding(size_t phi_index, size_t merge_index,
277                                      Node* binding) {
278   DCHECK_LT(phi_index, PhiCount());
279   DCHECK_LT(merge_index, MaxMergeCount());
280   bindings_[phi_index * (MaxMergeCount() + 1) + merge_index] = binding;
281 }
282 
GetRepresentationFor(size_t phi_index)283 MachineRepresentation GraphAssemblerLabel::GetRepresentationFor(
284     size_t phi_index) {
285   DCHECK_LT(phi_index, PhiCount());
286   return representations_[phi_index];
287 }
288 
GetControlsPtr()289 Node** GraphAssemblerLabel::GetControlsPtr() { return controls_; }
290 
GetEffectsPtr()291 Node** GraphAssemblerLabel::GetEffectsPtr() { return effects_; }
292 
293 }  // namespace compiler
294 }  // namespace internal
295 }  // namespace v8
296