OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compiler/pipeline.h" | 6 #include "src/compiler/pipeline.h" |
7 #include "src/compiler/raw-machine-assembler.h" | 7 #include "src/compiler/raw-machine-assembler.h" |
8 #include "src/compiler/scheduler.h" | 8 #include "src/compiler/scheduler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 namespace compiler { | 12 namespace compiler { |
13 | 13 |
14 RawMachineAssembler::RawMachineAssembler(Isolate* isolate, Graph* graph, | 14 RawMachineAssembler::RawMachineAssembler(Isolate* isolate, Graph* graph, |
15 CallDescriptor* call_descriptor, | 15 CallDescriptor* call_descriptor, |
16 MachineType word, | 16 MachineType word, |
17 MachineOperatorBuilder::Flags flags) | 17 MachineOperatorBuilder::Flags flags) |
18 : isolate_(isolate), | 18 : isolate_(isolate), |
19 graph_(graph), | 19 graph_(graph), |
20 schedule_(new (zone()) Schedule(zone())), | 20 schedule_(new (zone()) Schedule(zone())), |
21 machine_(zone(), word, flags), | 21 machine_(zone(), word, flags), |
22 common_(zone()), | 22 common_(zone()), |
23 call_descriptor_(call_descriptor), | 23 call_descriptor_(call_descriptor), |
24 parameters_(NULL), | 24 parameters_(nullptr), |
25 current_block_(schedule()->start()) { | 25 current_block_(schedule()->start()) { |
26 int param_count = static_cast<int>(parameter_count()); | 26 int param_count = static_cast<int>(parameter_count()); |
27 Node* s = graph->NewNode(common_.Start(param_count)); | 27 Node* s = graph->NewNode(common_.Start(param_count)); |
28 graph->SetStart(s); | 28 graph->SetStart(s); |
29 if (parameter_count() == 0) return; | 29 if (parameter_count() == 0) return; |
30 parameters_ = zone()->NewArray<Node*>(param_count); | 30 parameters_ = zone()->NewArray<Node*>(param_count); |
31 for (size_t i = 0; i < parameter_count(); ++i) { | 31 for (size_t i = 0; i < parameter_count(); ++i) { |
32 parameters_[i] = | 32 parameters_[i] = |
33 NewNode(common()->Parameter(static_cast<int>(i)), graph->start()); | 33 NewNode(common()->Parameter(static_cast<int>(i)), graph->start()); |
34 } | 34 } |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 Schedule* RawMachineAssembler::Export() { | 38 Schedule* RawMachineAssembler::Export() { |
39 // Compute the correct codegen order. | 39 // Compute the correct codegen order. |
40 DCHECK(schedule_->rpo_order()->empty()); | 40 DCHECK(schedule_->rpo_order()->empty()); |
41 Scheduler::ComputeSpecialRPO(zone(), schedule_); | 41 Scheduler::ComputeSpecialRPO(zone(), schedule_); |
42 // Invalidate RawMachineAssembler. | 42 // Invalidate RawMachineAssembler. |
43 Schedule* schedule = schedule_; | 43 Schedule* schedule = schedule_; |
44 schedule_ = NULL; | 44 schedule_ = nullptr; |
45 return schedule; | 45 return schedule; |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 Node* RawMachineAssembler::Parameter(size_t index) { | 49 Node* RawMachineAssembler::Parameter(size_t index) { |
50 DCHECK(index < parameter_count()); | 50 DCHECK(index < parameter_count()); |
51 return parameters_[index]; | 51 return parameters_[index]; |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 void RawMachineAssembler::Goto(Label* label) { | 55 void RawMachineAssembler::Goto(Label* label) { |
56 DCHECK(current_block_ != schedule()->end()); | 56 DCHECK(current_block_ != schedule()->end()); |
57 schedule()->AddGoto(CurrentBlock(), Use(label)); | 57 schedule()->AddGoto(CurrentBlock(), Use(label)); |
58 current_block_ = NULL; | 58 current_block_ = nullptr; |
59 } | 59 } |
60 | 60 |
61 | 61 |
62 void RawMachineAssembler::Branch(Node* condition, Label* true_val, | 62 void RawMachineAssembler::Branch(Node* condition, Label* true_val, |
63 Label* false_val) { | 63 Label* false_val) { |
64 DCHECK(current_block_ != schedule()->end()); | 64 DCHECK(current_block_ != schedule()->end()); |
65 Node* branch = NewNode(common()->Branch(), condition); | 65 Node* branch = NewNode(common()->Branch(), condition); |
66 schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val)); | 66 schedule()->AddBranch(CurrentBlock(), branch, Use(true_val), Use(false_val)); |
67 current_block_ = NULL; | 67 current_block_ = nullptr; |
68 } | 68 } |
69 | 69 |
70 | 70 |
71 void RawMachineAssembler::Switch(Node* index, Label* default_label, | 71 void RawMachineAssembler::Switch(Node* index, Label* default_label, |
72 int32_t* case_values, Label** case_labels, | 72 int32_t* case_values, Label** case_labels, |
73 size_t case_count) { | 73 size_t case_count) { |
74 DCHECK_NE(schedule()->end(), current_block_); | 74 DCHECK_NE(schedule()->end(), current_block_); |
75 size_t succ_count = case_count + 1; | 75 size_t succ_count = case_count + 1; |
76 Node* switch_node = NewNode(common()->Switch(succ_count), index); | 76 Node* switch_node = NewNode(common()->Switch(succ_count), index); |
77 BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count); | 77 BasicBlock** succ_blocks = zone()->NewArray<BasicBlock*>(succ_count); |
78 for (size_t index = 0; index < case_count; ++index) { | 78 for (size_t index = 0; index < case_count; ++index) { |
79 int32_t case_value = case_values[index]; | 79 int32_t case_value = case_values[index]; |
80 BasicBlock* case_block = Use(case_labels[index]); | 80 BasicBlock* case_block = Use(case_labels[index]); |
81 Node* case_node = | 81 Node* case_node = |
82 graph()->NewNode(common()->IfValue(case_value), switch_node); | 82 graph()->NewNode(common()->IfValue(case_value), switch_node); |
83 schedule()->AddNode(case_block, case_node); | 83 schedule()->AddNode(case_block, case_node); |
84 succ_blocks[index] = case_block; | 84 succ_blocks[index] = case_block; |
85 } | 85 } |
86 BasicBlock* default_block = Use(default_label); | 86 BasicBlock* default_block = Use(default_label); |
87 Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node); | 87 Node* default_node = graph()->NewNode(common()->IfDefault(), switch_node); |
88 schedule()->AddNode(default_block, default_node); | 88 schedule()->AddNode(default_block, default_node); |
89 succ_blocks[case_count] = default_block; | 89 succ_blocks[case_count] = default_block; |
90 schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count); | 90 schedule()->AddSwitch(CurrentBlock(), switch_node, succ_blocks, succ_count); |
91 current_block_ = nullptr; | 91 current_block_ = nullptr; |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 void RawMachineAssembler::Return(Node* value) { | 95 void RawMachineAssembler::Return(Node* value) { |
96 Node* ret = NewNode(common()->Return(), value); | 96 Node* ret = graph()->NewNode(common()->Return(), value); |
97 schedule()->AddReturn(CurrentBlock(), ret); | 97 schedule()->AddReturn(CurrentBlock(), ret); |
98 current_block_ = NULL; | 98 current_block_ = nullptr; |
99 } | 99 } |
100 | 100 |
101 | 101 |
102 Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, | 102 Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, |
103 Node* context, Node* frame_state, | 103 Node* context, Node* frame_state, |
104 CallFunctionFlags flags) { | 104 CallFunctionFlags flags) { |
105 Callable callable = CodeFactory::CallFunction(isolate(), 0, flags); | 105 Callable callable = CodeFactory::CallFunction(isolate(), 0, flags); |
106 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 106 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
107 isolate(), zone(), callable.descriptor(), 1, | 107 isolate(), zone(), callable.descriptor(), 1, |
108 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); | 108 CallDescriptor::kNeedsFrameState, Operator::kNoProperties); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build()); | 209 Linkage::GetSimplifiedCDescriptor(zone(), builder.Build()); |
210 | 210 |
211 Node* call = graph()->NewNode(common()->Call(descriptor), function, arg0, | 211 Node* call = graph()->NewNode(common()->Call(descriptor), function, arg0, |
212 arg1, arg2, arg3, arg4, arg5, arg6, arg7); | 212 arg1, arg2, arg3, arg4, arg5, arg6, arg7); |
213 schedule()->AddNode(CurrentBlock(), call); | 213 schedule()->AddNode(CurrentBlock(), call); |
214 return call; | 214 return call; |
215 } | 215 } |
216 | 216 |
217 | 217 |
218 void RawMachineAssembler::Bind(Label* label) { | 218 void RawMachineAssembler::Bind(Label* label) { |
219 DCHECK(current_block_ == NULL); | 219 DCHECK(current_block_ == nullptr); |
220 DCHECK(!label->bound_); | 220 DCHECK(!label->bound_); |
221 label->bound_ = true; | 221 label->bound_ = true; |
222 current_block_ = EnsureBlock(label); | 222 current_block_ = EnsureBlock(label); |
223 } | 223 } |
224 | 224 |
225 | 225 |
226 BasicBlock* RawMachineAssembler::Use(Label* label) { | 226 BasicBlock* RawMachineAssembler::Use(Label* label) { |
227 label->used_ = true; | 227 label->used_ = true; |
228 return EnsureBlock(label); | 228 return EnsureBlock(label); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 BasicBlock* RawMachineAssembler::EnsureBlock(Label* label) { | 232 BasicBlock* RawMachineAssembler::EnsureBlock(Label* label) { |
233 if (label->block_ == NULL) label->block_ = schedule()->NewBasicBlock(); | 233 if (label->block_ == nullptr) label->block_ = schedule()->NewBasicBlock(); |
234 return label->block_; | 234 return label->block_; |
235 } | 235 } |
236 | 236 |
237 | 237 |
238 BasicBlock* RawMachineAssembler::CurrentBlock() { | 238 BasicBlock* RawMachineAssembler::CurrentBlock() { |
239 DCHECK(current_block_); | 239 DCHECK(current_block_); |
240 return current_block_; | 240 return current_block_; |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count, | 244 Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count, |
245 Node** inputs) { | 245 Node** inputs) { |
246 DCHECK_NOT_NULL(schedule_); | 246 DCHECK_NOT_NULL(schedule_); |
247 DCHECK(current_block_ != NULL); | 247 DCHECK(current_block_ != nullptr); |
248 Node* node = graph()->NewNode(op, input_count, inputs); | 248 Node* node = graph()->NewNode(op, input_count, inputs); |
249 BasicBlock* block = op->opcode() == IrOpcode::kParameter ? schedule()->start() | 249 schedule()->AddNode(CurrentBlock(), node); |
250 : CurrentBlock(); | |
251 if (op->opcode() != IrOpcode::kReturn) { | |
252 schedule()->AddNode(block, node); | |
253 } | |
254 return node; | 250 return node; |
255 } | 251 } |
256 | 252 |
257 } // namespace compiler | 253 } // namespace compiler |
258 } // namespace internal | 254 } // namespace internal |
259 } // namespace v8 | 255 } // namespace v8 |
OLD | NEW |