Line data Source code
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 :
10 : namespace v8 {
11 : namespace internal {
12 : namespace compiler {
13 :
14 995428 : GraphAssembler::GraphAssembler(JSGraph* jsgraph, Node* effect, Node* control,
15 : Zone* zone)
16 : : temp_zone_(zone),
17 : jsgraph_(jsgraph),
18 : current_effect_(effect),
19 995428 : current_control_(control) {}
20 :
21 2195768 : Node* GraphAssembler::IntPtrConstant(intptr_t value) {
22 2195768 : return jsgraph()->IntPtrConstant(value);
23 : }
24 :
25 556666 : Node* GraphAssembler::Int32Constant(int32_t value) {
26 556666 : return jsgraph()->Int32Constant(value);
27 : }
28 :
29 174 : Node* GraphAssembler::Int64Constant(int64_t value) {
30 174 : return jsgraph()->Int64Constant(value);
31 : }
32 :
33 177216 : Node* GraphAssembler::UniqueIntPtrConstant(intptr_t value) {
34 177216 : return graph()->NewNode(
35 : machine()->Is64() ? common()->Int64Constant(value)
36 177219 : : common()->Int32Constant(static_cast<int32_t>(value)));
37 : }
38 :
39 34026 : Node* GraphAssembler::SmiConstant(int32_t value) {
40 34026 : return jsgraph()->SmiConstant(value);
41 : }
42 :
43 37379 : Node* GraphAssembler::Uint32Constant(int32_t value) {
44 74758 : return jsgraph()->Uint32Constant(value);
45 : }
46 :
47 48173 : Node* GraphAssembler::Float64Constant(double value) {
48 48173 : return jsgraph()->Float64Constant(value);
49 : }
50 :
51 128591 : Node* GraphAssembler::HeapConstant(Handle<HeapObject> object) {
52 128591 : return jsgraph()->HeapConstant(object);
53 : }
54 :
55 :
56 475190 : Node* GraphAssembler::ExternalConstant(ExternalReference ref) {
57 475190 : return jsgraph()->ExternalConstant(ref);
58 : }
59 :
60 5526 : Node* GraphAssembler::CEntryStubConstant(int result_size) {
61 5526 : return jsgraph()->CEntryStubConstant(result_size);
62 : }
63 :
64 33815 : Node* GraphAssembler::LoadFramePointer() {
65 67630 : return graph()->NewNode(machine()->LoadFramePointer());
66 : }
67 :
68 : #define SINGLETON_CONST_DEF(Name) \
69 : Node* GraphAssembler::Name() { return jsgraph()->Name(); }
70 838044 : JSGRAPH_SINGLETON_CONSTANT_LIST(SINGLETON_CONST_DEF)
71 : #undef SINGLETON_CONST_DEF
72 :
73 : #define PURE_UNOP_DEF(Name) \
74 : Node* GraphAssembler::Name(Node* input) { \
75 : return graph()->NewNode(machine()->Name(), input); \
76 : }
77 1119272 : PURE_ASSEMBLER_MACH_UNOP_LIST(PURE_UNOP_DEF)
78 : #undef PURE_UNOP_DEF
79 :
80 : #define PURE_BINOP_DEF(Name) \
81 : Node* GraphAssembler::Name(Node* left, Node* right) { \
82 : return graph()->NewNode(machine()->Name(), left, right); \
83 : }
84 6232278 : PURE_ASSEMBLER_MACH_BINOP_LIST(PURE_BINOP_DEF)
85 : #undef PURE_BINOP_DEF
86 :
87 : #define CHECKED_BINOP_DEF(Name) \
88 : Node* GraphAssembler::Name(Node* left, Node* right) { \
89 : return graph()->NewNode(machine()->Name(), left, right, current_control_); \
90 : }
91 143033 : CHECKED_ASSEMBLER_MACH_BINOP_LIST(CHECKED_BINOP_DEF)
92 : #undef CHECKED_BINOP_DEF
93 :
94 0 : Node* GraphAssembler::Float64RoundDown(Node* value) {
95 0 : CHECK(machine()->Float64RoundDown().IsSupported());
96 0 : return graph()->NewNode(machine()->Float64RoundDown().op(), value);
97 : }
98 :
99 140 : Node* GraphAssembler::Float64RoundTruncate(Node* value) {
100 140 : CHECK(machine()->Float64RoundTruncate().IsSupported());
101 280 : return graph()->NewNode(machine()->Float64RoundTruncate().op(), value);
102 : }
103 :
104 138407 : Node* GraphAssembler::Projection(int index, Node* value) {
105 276822 : return graph()->NewNode(common()->Projection(index), value, current_control_);
106 : }
107 :
108 175619 : Node* GraphAssembler::Allocate(AllocationType allocation, Node* size) {
109 175619 : return current_control_ = current_effect_ = graph()->NewNode(
110 : simplified()->AllocateRaw(Type::Any(), allocation), size,
111 175617 : current_effect_, current_control_);
112 : }
113 :
114 601932 : Node* GraphAssembler::LoadField(FieldAccess const& access, Node* object) {
115 : return current_effect_ =
116 601932 : graph()->NewNode(simplified()->LoadField(access), object,
117 601932 : current_effect_, current_control_);
118 : }
119 :
120 10752 : Node* GraphAssembler::LoadElement(ElementAccess const& access, Node* object,
121 : Node* index) {
122 : return current_effect_ =
123 10752 : graph()->NewNode(simplified()->LoadElement(access), object, index,
124 10752 : current_effect_, current_control_);
125 : }
126 :
127 172961 : Node* GraphAssembler::StoreField(FieldAccess const& access, Node* object,
128 : Node* value) {
129 : return current_effect_ =
130 172961 : graph()->NewNode(simplified()->StoreField(access), object, value,
131 172967 : current_effect_, current_control_);
132 : }
133 :
134 6457 : Node* GraphAssembler::StoreElement(ElementAccess const& access, Node* object,
135 : Node* index, Node* value) {
136 : return current_effect_ =
137 6457 : graph()->NewNode(simplified()->StoreElement(access), object, index,
138 6457 : value, current_effect_, current_control_);
139 : }
140 :
141 28 : Node* GraphAssembler::DebugBreak() {
142 28 : return current_effect_ = graph()->NewNode(machine()->DebugBreak(),
143 28 : current_effect_, current_control_);
144 : }
145 :
146 5621 : Node* GraphAssembler::Unreachable() {
147 5621 : return current_effect_ = graph()->NewNode(common()->Unreachable(),
148 5621 : current_effect_, current_control_);
149 : }
150 :
151 237282 : Node* GraphAssembler::Store(StoreRepresentation rep, Node* object, Node* offset,
152 : Node* value) {
153 : return current_effect_ =
154 237282 : graph()->NewNode(machine()->Store(rep), object, offset, value,
155 237286 : current_effect_, current_control_);
156 : }
157 :
158 440044 : Node* GraphAssembler::Load(MachineType rep, Node* object, Node* offset) {
159 : return current_effect_ =
160 440044 : graph()->NewNode(machine()->Load(rep), object, offset,
161 440047 : current_effect_, current_control_);
162 : }
163 :
164 196 : Node* GraphAssembler::StoreUnaligned(MachineRepresentation rep, Node* object,
165 : Node* offset, Node* value) {
166 : Operator const* const op =
167 144 : (rep == MachineRepresentation::kWord8 ||
168 : machine()->UnalignedStoreSupported(rep))
169 : ? machine()->Store(StoreRepresentation(rep, kNoWriteBarrier))
170 392 : : machine()->UnalignedStore(rep);
171 196 : return current_effect_ = graph()->NewNode(op, object, offset, value,
172 196 : current_effect_, current_control_);
173 : }
174 :
175 268 : Node* GraphAssembler::LoadUnaligned(MachineType rep, Node* object,
176 : Node* offset) {
177 : Operator const* const op =
178 174 : (rep.representation() == MachineRepresentation::kWord8 ||
179 : machine()->UnalignedLoadSupported(rep.representation()))
180 : ? machine()->Load(rep)
181 536 : : machine()->UnalignedLoad(rep);
182 268 : return current_effect_ = graph()->NewNode(op, object, offset, current_effect_,
183 268 : current_control_);
184 : }
185 :
186 9316 : Node* GraphAssembler::Retain(Node* buffer) {
187 : return current_effect_ =
188 18632 : graph()->NewNode(common()->Retain(), buffer, current_effect_);
189 : }
190 :
191 6757 : Node* GraphAssembler::UnsafePointerAdd(Node* base, Node* external) {
192 : return current_effect_ =
193 6757 : graph()->NewNode(machine()->UnsafePointerAdd(), base, external,
194 6757 : current_effect_, current_control_);
195 : }
196 :
197 29 : Node* GraphAssembler::ToNumber(Node* value) {
198 : return current_effect_ =
199 58 : graph()->NewNode(ToNumberOperator(), ToNumberBuiltinConstant(),
200 29 : value, NoContextConstant(), current_effect_);
201 : }
202 :
203 242509 : Node* GraphAssembler::BitcastWordToTagged(Node* value) {
204 : return current_effect_ =
205 242509 : graph()->NewNode(machine()->BitcastWordToTagged(), value,
206 242513 : current_effect_, current_control_);
207 : }
208 :
209 206917 : Node* GraphAssembler::BitcastTaggedToWord(Node* value) {
210 : return current_effect_ =
211 206917 : graph()->NewNode(machine()->BitcastTaggedToWord(), value,
212 206921 : current_effect_, current_control_);
213 : }
214 :
215 0 : Node* GraphAssembler::Word32PoisonOnSpeculation(Node* value) {
216 : return current_effect_ =
217 0 : graph()->NewNode(machine()->Word32PoisonOnSpeculation(), value,
218 0 : current_effect_, current_control_);
219 : }
220 :
221 117014 : Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason,
222 : VectorSlotPair const& feedback,
223 : Node* condition, Node* frame_state,
224 : IsSafetyCheck is_safety_check) {
225 117014 : return current_control_ = current_effect_ = graph()->NewNode(
226 : common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback,
227 : is_safety_check),
228 117014 : condition, frame_state, current_effect_, current_control_);
229 : }
230 :
231 229438 : Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
232 : VectorSlotPair const& feedback,
233 : Node* condition, Node* frame_state,
234 : IsSafetyCheck is_safety_check) {
235 229438 : return current_control_ = current_effect_ = graph()->NewNode(
236 : common()->DeoptimizeUnless(DeoptimizeKind::kEager, reason,
237 : feedback, is_safety_check),
238 229440 : condition, frame_state, current_effect_, current_control_);
239 : }
240 :
241 24530 : void GraphAssembler::Branch(Node* condition, GraphAssemblerLabel<0u>* if_true,
242 : GraphAssemblerLabel<0u>* if_false,
243 : IsSafetyCheck is_safety_check) {
244 : DCHECK_NOT_NULL(current_control_);
245 :
246 : BranchHint hint = BranchHint::kNone;
247 24530 : if (if_true->IsDeferred() != if_false->IsDeferred()) {
248 7681 : hint = if_false->IsDeferred() ? BranchHint::kTrue : BranchHint::kFalse;
249 : }
250 :
251 24530 : Node* branch = graph()->NewNode(common()->Branch(hint, is_safety_check),
252 : condition, current_control_);
253 :
254 49060 : current_control_ = graph()->NewNode(common()->IfTrue(), branch);
255 24530 : MergeState(if_true);
256 :
257 49060 : current_control_ = graph()->NewNode(common()->IfFalse(), branch);
258 24530 : MergeState(if_false);
259 :
260 24530 : current_control_ = nullptr;
261 24530 : current_effect_ = nullptr;
262 24530 : }
263 :
264 : // Extractors (should be only used when destructing the assembler.
265 1343312 : Node* GraphAssembler::ExtractCurrentControl() {
266 1343312 : Node* result = current_control_;
267 1343312 : current_control_ = nullptr;
268 1343312 : return result;
269 : }
270 :
271 1343311 : Node* GraphAssembler::ExtractCurrentEffect() {
272 1343311 : Node* result = current_effect_;
273 1343311 : current_effect_ = nullptr;
274 1343311 : return result;
275 : }
276 :
277 35904991 : void GraphAssembler::Reset(Node* effect, Node* control) {
278 35904991 : current_effect_ = effect;
279 35904991 : current_control_ = control;
280 35904991 : }
281 :
282 29 : Operator const* GraphAssembler::ToNumberOperator() {
283 29 : if (!to_number_operator_.is_set()) {
284 : Callable callable =
285 29 : Builtins::CallableFor(jsgraph()->isolate(), Builtins::kToNumber);
286 : CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
287 29 : auto call_descriptor = Linkage::GetStubCallDescriptor(
288 29 : graph()->zone(), callable.descriptor(),
289 : callable.descriptor().GetStackParameterCount(), flags,
290 29 : Operator::kEliminatable);
291 29 : to_number_operator_.set(common()->Call(call_descriptor));
292 : }
293 29 : return to_number_operator_.get();
294 : }
295 :
296 : } // namespace compiler
297 : } // namespace internal
298 121996 : } // namespace v8
|