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/compiler/pipeline.h" | 5 #include "src/compiler/pipeline.h" |
6 #include "src/compiler/scheduler.h" | 6 #include "src/compiler/scheduler.h" |
7 #include "src/compiler/structured-machine-assembler.h" | 7 #include "src/compiler/structured-machine-assembler.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 20 matching lines...) Expand all Loading... |
31 if (parameter_count() == 0) return; | 31 if (parameter_count() == 0) return; |
32 parameters_ = zone()->NewArray<Node*>(parameter_count()); | 32 parameters_ = zone()->NewArray<Node*>(parameter_count()); |
33 for (int i = 0; i < parameter_count(); ++i) { | 33 for (int i = 0; i < parameter_count(); ++i) { |
34 parameters_[i] = NewNode(common()->Parameter(i)); | 34 parameters_[i] = NewNode(common()->Parameter(i)); |
35 } | 35 } |
36 } | 36 } |
37 | 37 |
38 | 38 |
39 Schedule* StructuredMachineAssembler::Export() { | 39 Schedule* StructuredMachineAssembler::Export() { |
40 // Compute the correct codegen order. | 40 // Compute the correct codegen order. |
41 ASSERT(schedule_->rpo_order()->empty()); | 41 DCHECK(schedule_->rpo_order()->empty()); |
42 Scheduler scheduler(zone(), graph(), schedule_); | 42 Scheduler scheduler(zone(), graph(), schedule_); |
43 scheduler.ComputeSpecialRPO(); | 43 scheduler.ComputeSpecialRPO(); |
44 // Invalidate MachineAssembler. | 44 // Invalidate MachineAssembler. |
45 Schedule* schedule = schedule_; | 45 Schedule* schedule = schedule_; |
46 schedule_ = NULL; | 46 schedule_ = NULL; |
47 return schedule; | 47 return schedule; |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 Node* StructuredMachineAssembler::Parameter(int index) { | 51 Node* StructuredMachineAssembler::Parameter(int index) { |
52 ASSERT(0 <= index && index < parameter_count()); | 52 DCHECK(0 <= index && index < parameter_count()); |
53 return parameters_[index]; | 53 return parameters_[index]; |
54 } | 54 } |
55 | 55 |
56 | 56 |
57 Node* StructuredMachineAssembler::MakeNode(Operator* op, int input_count, | 57 Node* StructuredMachineAssembler::MakeNode(Operator* op, int input_count, |
58 Node** inputs) { | 58 Node** inputs) { |
59 ASSERT(ScheduleValid()); | 59 DCHECK(ScheduleValid()); |
60 ASSERT(current_environment_ != NULL); | 60 DCHECK(current_environment_ != NULL); |
61 Node* node = graph()->NewNode(op, input_count, inputs); | 61 Node* node = graph()->NewNode(op, input_count, inputs); |
62 BasicBlock* block = NULL; | 62 BasicBlock* block = NULL; |
63 switch (op->opcode()) { | 63 switch (op->opcode()) { |
64 case IrOpcode::kParameter: | 64 case IrOpcode::kParameter: |
65 case IrOpcode::kInt32Constant: | 65 case IrOpcode::kInt32Constant: |
66 case IrOpcode::kInt64Constant: | 66 case IrOpcode::kInt64Constant: |
67 case IrOpcode::kFloat64Constant: | 67 case IrOpcode::kFloat64Constant: |
68 case IrOpcode::kExternalConstant: | 68 case IrOpcode::kExternalConstant: |
69 case IrOpcode::kNumberConstant: | 69 case IrOpcode::kNumberConstant: |
70 case IrOpcode::kHeapConstant: | 70 case IrOpcode::kHeapConstant: |
71 // Parameters and constants must be in start. | 71 // Parameters and constants must be in start. |
72 block = schedule()->start(); | 72 block = schedule()->start(); |
73 break; | 73 break; |
74 default: | 74 default: |
75 // Verify all leaf nodes handled above. | 75 // Verify all leaf nodes handled above. |
76 ASSERT((op->OutputCount() == 0) == (op->opcode() == IrOpcode::kStore)); | 76 DCHECK((op->OutputCount() == 0) == (op->opcode() == IrOpcode::kStore)); |
77 block = current_environment_->block_; | 77 block = current_environment_->block_; |
78 break; | 78 break; |
79 } | 79 } |
80 if (block != NULL) { | 80 if (block != NULL) { |
81 schedule()->AddNode(block, node); | 81 schedule()->AddNode(block, node); |
82 } | 82 } |
83 return node; | 83 return node; |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 Variable StructuredMachineAssembler::NewVariable(Node* initial_value) { | 87 Variable StructuredMachineAssembler::NewVariable(Node* initial_value) { |
88 CHECK(initial_value != NULL); | 88 CHECK(initial_value != NULL); |
89 int offset = number_of_variables_++; | 89 int offset = number_of_variables_++; |
90 // Extend current environment to correct number of values. | 90 // Extend current environment to correct number of values. |
91 NodeVector* variables = CurrentVars(); | 91 NodeVector* variables = CurrentVars(); |
92 size_t to_add = number_of_variables_ - variables->size(); | 92 size_t to_add = number_of_variables_ - variables->size(); |
93 if (to_add != 0) { | 93 if (to_add != 0) { |
94 variables->reserve(number_of_variables_); | 94 variables->reserve(number_of_variables_); |
95 variables->insert(variables->end(), to_add, NULL); | 95 variables->insert(variables->end(), to_add, NULL); |
96 } | 96 } |
97 variables->at(offset) = initial_value; | 97 variables->at(offset) = initial_value; |
98 return Variable(this, offset); | 98 return Variable(this, offset); |
99 } | 99 } |
100 | 100 |
101 | 101 |
102 Node* StructuredMachineAssembler::GetVariable(int offset) { | 102 Node* StructuredMachineAssembler::GetVariable(int offset) { |
103 ASSERT(ScheduleValid()); | 103 DCHECK(ScheduleValid()); |
104 return VariableAt(current_environment_, offset); | 104 return VariableAt(current_environment_, offset); |
105 } | 105 } |
106 | 106 |
107 | 107 |
108 void StructuredMachineAssembler::SetVariable(int offset, Node* value) { | 108 void StructuredMachineAssembler::SetVariable(int offset, Node* value) { |
109 ASSERT(ScheduleValid()); | 109 DCHECK(ScheduleValid()); |
110 Node*& ref = VariableAt(current_environment_, offset); | 110 Node*& ref = VariableAt(current_environment_, offset); |
111 ref = value; | 111 ref = value; |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 Node*& StructuredMachineAssembler::VariableAt(Environment* environment, | 115 Node*& StructuredMachineAssembler::VariableAt(Environment* environment, |
116 int32_t offset) { | 116 int32_t offset) { |
117 // Variable used out of scope. | 117 // Variable used out of scope. |
118 CHECK(static_cast<size_t>(offset) < environment->variables_.size()); | 118 CHECK(static_cast<size_t>(offset) < environment->variables_.size()); |
119 Node*& value = environment->variables_.at(offset); | 119 Node*& value = environment->variables_.at(offset); |
120 CHECK(value != NULL); // Variable used out of scope. | 120 CHECK(value != NULL); // Variable used out of scope. |
121 return value; | 121 return value; |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 void StructuredMachineAssembler::Return(Node* value) { | 125 void StructuredMachineAssembler::Return(Node* value) { |
126 BasicBlock* block = current_environment_->block_; | 126 BasicBlock* block = current_environment_->block_; |
127 if (block != NULL) { | 127 if (block != NULL) { |
128 schedule()->AddReturn(block, value); | 128 schedule()->AddReturn(block, value); |
129 } | 129 } |
130 CopyCurrentAsDead(); | 130 CopyCurrentAsDead(); |
131 } | 131 } |
132 | 132 |
133 | 133 |
134 void StructuredMachineAssembler::CopyCurrentAsDead() { | 134 void StructuredMachineAssembler::CopyCurrentAsDead() { |
135 ASSERT(current_environment_ != NULL); | 135 DCHECK(current_environment_ != NULL); |
136 bool is_dead = current_environment_->is_dead_; | 136 bool is_dead = current_environment_->is_dead_; |
137 current_environment_->is_dead_ = true; | 137 current_environment_->is_dead_ = true; |
138 Environment* next = Copy(current_environment_); | 138 Environment* next = Copy(current_environment_); |
139 current_environment_->is_dead_ = is_dead; | 139 current_environment_->is_dead_ = is_dead; |
140 current_environment_ = next; | 140 current_environment_ = next; |
141 } | 141 } |
142 | 142 |
143 | 143 |
144 StructuredMachineAssembler::Environment* StructuredMachineAssembler::Copy( | 144 StructuredMachineAssembler::Environment* StructuredMachineAssembler::Copy( |
145 Environment* env, int truncate_at) { | 145 Environment* env, int truncate_at) { |
146 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_); | 146 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_); |
147 if (!new_env->is_dead_) { | 147 if (!new_env->is_dead_) { |
148 new_env->block_ = schedule()->NewBasicBlock(); | 148 new_env->block_ = schedule()->NewBasicBlock(); |
149 } | 149 } |
150 new_env->variables_.reserve(truncate_at); | 150 new_env->variables_.reserve(truncate_at); |
151 NodeVectorIter end = env->variables_.end(); | 151 NodeVectorIter end = env->variables_.end(); |
152 ASSERT(truncate_at <= static_cast<int>(env->variables_.size())); | 152 DCHECK(truncate_at <= static_cast<int>(env->variables_.size())); |
153 end -= static_cast<int>(env->variables_.size()) - truncate_at; | 153 end -= static_cast<int>(env->variables_.size()) - truncate_at; |
154 new_env->variables_.insert(new_env->variables_.begin(), | 154 new_env->variables_.insert(new_env->variables_.begin(), |
155 env->variables_.begin(), end); | 155 env->variables_.begin(), end); |
156 return new_env; | 156 return new_env; |
157 } | 157 } |
158 | 158 |
159 | 159 |
160 StructuredMachineAssembler::Environment* | 160 StructuredMachineAssembler::Environment* |
161 StructuredMachineAssembler::CopyForLoopHeader(Environment* env) { | 161 StructuredMachineAssembler::CopyForLoopHeader(Environment* env) { |
162 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_); | 162 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 if (phi == NULL) continue; | 194 if (phi == NULL) continue; |
195 phi->set_op(common()->Phi(phi->InputCount() + 1)); | 195 phi->set_op(common()->Phi(phi->InputCount() + 1)); |
196 phi->AppendInput(zone(), VariableAt(from, i)); | 196 phi->AppendInput(zone(), VariableAt(from, i)); |
197 } | 197 } |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 | 201 |
202 void StructuredMachineAssembler::Merge(EnvironmentVector* environments, | 202 void StructuredMachineAssembler::Merge(EnvironmentVector* environments, |
203 int truncate_at) { | 203 int truncate_at) { |
204 ASSERT(current_environment_ == NULL || current_environment_->is_dead_); | 204 DCHECK(current_environment_ == NULL || current_environment_->is_dead_); |
205 Environment* next = new (zone()) Environment(zone(), NULL, false); | 205 Environment* next = new (zone()) Environment(zone(), NULL, false); |
206 current_environment_ = next; | 206 current_environment_ = next; |
207 size_t n_vars = number_of_variables_; | 207 size_t n_vars = number_of_variables_; |
208 NodeVector& vars = next->variables_; | 208 NodeVector& vars = next->variables_; |
209 vars.reserve(n_vars); | 209 vars.reserve(n_vars); |
210 Node** scratch = NULL; | 210 Node** scratch = NULL; |
211 size_t n_envs = environments->size(); | 211 size_t n_envs = environments->size(); |
212 Environment** live_environments = reinterpret_cast<Environment**>( | 212 Environment** live_environments = reinterpret_cast<Environment**>( |
213 alloca(sizeof(environments->at(0)) * n_envs)); | 213 alloca(sizeof(environments->at(0)) * n_envs)); |
214 size_t n_live = 0; | 214 size_t n_live = 0; |
215 for (size_t i = 0; i < n_envs; i++) { | 215 for (size_t i = 0; i < n_envs; i++) { |
216 if (environments->at(i)->is_dead_) continue; | 216 if (environments->at(i)->is_dead_) continue; |
217 live_environments[n_live++] = environments->at(i); | 217 live_environments[n_live++] = environments->at(i); |
218 } | 218 } |
219 n_envs = n_live; | 219 n_envs = n_live; |
220 if (n_live == 0) next->is_dead_ = true; | 220 if (n_live == 0) next->is_dead_ = true; |
221 if (!next->is_dead_) { | 221 if (!next->is_dead_) { |
222 next->block_ = schedule()->NewBasicBlock(); | 222 next->block_ = schedule()->NewBasicBlock(); |
223 } | 223 } |
224 for (size_t j = 0; j < n_vars; ++j) { | 224 for (size_t j = 0; j < n_vars; ++j) { |
225 Node* resolved = NULL; | 225 Node* resolved = NULL; |
226 // Find first non equal variable. | 226 // Find first non equal variable. |
227 size_t i = 0; | 227 size_t i = 0; |
228 for (; i < n_envs; i++) { | 228 for (; i < n_envs; i++) { |
229 ASSERT(live_environments[i]->variables_.size() <= n_vars); | 229 DCHECK(live_environments[i]->variables_.size() <= n_vars); |
230 Node* val = NULL; | 230 Node* val = NULL; |
231 if (j < static_cast<size_t>(truncate_at)) { | 231 if (j < static_cast<size_t>(truncate_at)) { |
232 val = live_environments[i]->variables_.at(j); | 232 val = live_environments[i]->variables_.at(j); |
233 // TODO(dcarney): record start position at time of split. | 233 // TODO(dcarney): record start position at time of split. |
234 // all variables after this should not be NULL. | 234 // all variables after this should not be NULL. |
235 if (val != NULL) { | 235 if (val != NULL) { |
236 val = VariableAt(live_environments[i], static_cast<int>(j)); | 236 val = VariableAt(live_environments[i], static_cast<int>(j)); |
237 } | 237 } |
238 } | 238 } |
239 if (val == resolved) continue; | 239 if (val == resolved) continue; |
(...skipping 20 matching lines...) Expand all Loading... |
260 schedule()->AddNode(next->block_, resolved); | 260 schedule()->AddNode(next->block_, resolved); |
261 } | 261 } |
262 } | 262 } |
263 vars.push_back(resolved); | 263 vars.push_back(resolved); |
264 } | 264 } |
265 } | 265 } |
266 | 266 |
267 | 267 |
268 void StructuredMachineAssembler::AddGoto(Environment* from, Environment* to) { | 268 void StructuredMachineAssembler::AddGoto(Environment* from, Environment* to) { |
269 if (to->is_dead_) { | 269 if (to->is_dead_) { |
270 ASSERT(from->is_dead_); | 270 DCHECK(from->is_dead_); |
271 return; | 271 return; |
272 } | 272 } |
273 ASSERT(!from->is_dead_); | 273 DCHECK(!from->is_dead_); |
274 schedule()->AddGoto(from->block_, to->block_); | 274 schedule()->AddGoto(from->block_, to->block_); |
275 } | 275 } |
276 | 276 |
277 | 277 |
278 // TODO(dcarney): add pass before rpo to schedule to compute these. | 278 // TODO(dcarney): add pass before rpo to schedule to compute these. |
279 BasicBlock* StructuredMachineAssembler::TrampolineFor(BasicBlock* block) { | 279 BasicBlock* StructuredMachineAssembler::TrampolineFor(BasicBlock* block) { |
280 BasicBlock* trampoline = schedule()->NewBasicBlock(); | 280 BasicBlock* trampoline = schedule()->NewBasicBlock(); |
281 schedule()->AddGoto(trampoline, block); | 281 schedule()->AddGoto(trampoline, block); |
282 return trampoline; | 282 return trampoline; |
283 } | 283 } |
284 | 284 |
285 | 285 |
286 void StructuredMachineAssembler::AddBranch(Environment* environment, | 286 void StructuredMachineAssembler::AddBranch(Environment* environment, |
287 Node* condition, | 287 Node* condition, |
288 Environment* true_val, | 288 Environment* true_val, |
289 Environment* false_val) { | 289 Environment* false_val) { |
290 ASSERT(environment->is_dead_ == true_val->is_dead_); | 290 DCHECK(environment->is_dead_ == true_val->is_dead_); |
291 ASSERT(environment->is_dead_ == false_val->is_dead_); | 291 DCHECK(environment->is_dead_ == false_val->is_dead_); |
292 if (true_val->block_ == false_val->block_) { | 292 if (true_val->block_ == false_val->block_) { |
293 if (environment->is_dead_) return; | 293 if (environment->is_dead_) return; |
294 AddGoto(environment, true_val); | 294 AddGoto(environment, true_val); |
295 return; | 295 return; |
296 } | 296 } |
297 Node* branch = graph()->NewNode(common()->Branch(), condition); | 297 Node* branch = graph()->NewNode(common()->Branch(), condition); |
298 if (environment->is_dead_) return; | 298 if (environment->is_dead_) return; |
299 BasicBlock* true_block = TrampolineFor(true_val->block_); | 299 BasicBlock* true_block = TrampolineFor(true_val->block_); |
300 BasicBlock* false_block = TrampolineFor(false_val->block_); | 300 BasicBlock* false_block = TrampolineFor(false_val->block_); |
301 schedule()->AddBranch(environment->block_, branch, true_block, false_block); | 301 schedule()->AddBranch(environment->block_, branch, true_block, false_block); |
302 } | 302 } |
303 | 303 |
304 | 304 |
305 StructuredMachineAssembler::Environment::Environment(Zone* zone, | 305 StructuredMachineAssembler::Environment::Environment(Zone* zone, |
306 BasicBlock* block, | 306 BasicBlock* block, |
307 bool is_dead) | 307 bool is_dead) |
308 : block_(block), | 308 : block_(block), |
309 variables_(NodeVector::allocator_type(zone)), | 309 variables_(NodeVector::allocator_type(zone)), |
310 is_dead_(is_dead) {} | 310 is_dead_(is_dead) {} |
311 | 311 |
312 | 312 |
313 StructuredMachineAssembler::IfBuilder::IfBuilder( | 313 StructuredMachineAssembler::IfBuilder::IfBuilder( |
314 StructuredMachineAssembler* smasm) | 314 StructuredMachineAssembler* smasm) |
315 : smasm_(smasm), | 315 : smasm_(smasm), |
316 if_clauses_(IfClauses::allocator_type(smasm_->zone())), | 316 if_clauses_(IfClauses::allocator_type(smasm_->zone())), |
317 pending_exit_merges_(EnvironmentVector::allocator_type(smasm_->zone())) { | 317 pending_exit_merges_(EnvironmentVector::allocator_type(smasm_->zone())) { |
318 ASSERT(smasm_->current_environment_ != NULL); | 318 DCHECK(smasm_->current_environment_ != NULL); |
319 PushNewIfClause(); | 319 PushNewIfClause(); |
320 ASSERT(!IsDone()); | 320 DCHECK(!IsDone()); |
321 } | 321 } |
322 | 322 |
323 | 323 |
324 StructuredMachineAssembler::IfBuilder& | 324 StructuredMachineAssembler::IfBuilder& |
325 StructuredMachineAssembler::IfBuilder::If() { | 325 StructuredMachineAssembler::IfBuilder::If() { |
326 ASSERT(smasm_->current_environment_ != NULL); | 326 DCHECK(smasm_->current_environment_ != NULL); |
327 IfClause* clause = CurrentClause(); | 327 IfClause* clause = CurrentClause(); |
328 if (clause->then_environment_ != NULL || clause->else_environment_ != NULL) { | 328 if (clause->then_environment_ != NULL || clause->else_environment_ != NULL) { |
329 PushNewIfClause(); | 329 PushNewIfClause(); |
330 } | 330 } |
331 return *this; | 331 return *this; |
332 } | 332 } |
333 | 333 |
334 | 334 |
335 StructuredMachineAssembler::IfBuilder& | 335 StructuredMachineAssembler::IfBuilder& |
336 StructuredMachineAssembler::IfBuilder::If(Node* condition) { | 336 StructuredMachineAssembler::IfBuilder::If(Node* condition) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 pending_else_merges_(PendingMergeStack::allocator_type(zone)), | 398 pending_else_merges_(PendingMergeStack::allocator_type(zone)), |
399 then_environment_(NULL), | 399 then_environment_(NULL), |
400 else_environment_(NULL) { | 400 else_environment_(NULL) { |
401 PushNewExpressionState(); | 401 PushNewExpressionState(); |
402 } | 402 } |
403 | 403 |
404 | 404 |
405 StructuredMachineAssembler::IfBuilder::PendingMergeStackRange | 405 StructuredMachineAssembler::IfBuilder::PendingMergeStackRange |
406 StructuredMachineAssembler::IfBuilder::IfClause::ComputeRelevantMerges( | 406 StructuredMachineAssembler::IfBuilder::IfClause::ComputeRelevantMerges( |
407 CombineType combine_type) { | 407 CombineType combine_type) { |
408 ASSERT(!expression_states_.empty()); | 408 DCHECK(!expression_states_.empty()); |
409 PendingMergeStack* stack; | 409 PendingMergeStack* stack; |
410 int start; | 410 int start; |
411 if (combine_type == kCombineThen) { | 411 if (combine_type == kCombineThen) { |
412 stack = &pending_then_merges_; | 412 stack = &pending_then_merges_; |
413 start = expression_states_.back().pending_then_size_; | 413 start = expression_states_.back().pending_then_size_; |
414 } else { | 414 } else { |
415 ASSERT(combine_type == kCombineElse); | 415 DCHECK(combine_type == kCombineElse); |
416 stack = &pending_else_merges_; | 416 stack = &pending_else_merges_; |
417 start = expression_states_.back().pending_else_size_; | 417 start = expression_states_.back().pending_else_size_; |
418 } | 418 } |
419 PendingMergeStackRange data; | 419 PendingMergeStackRange data; |
420 data.merge_stack_ = stack; | 420 data.merge_stack_ = stack; |
421 data.start_ = start; | 421 data.start_ = start; |
422 data.size_ = static_cast<int>(stack->size()) - start; | 422 data.size_ = static_cast<int>(stack->size()) - start; |
423 return data; | 423 return data; |
424 } | 424 } |
425 | 425 |
426 | 426 |
427 void StructuredMachineAssembler::IfBuilder::IfClause::ResolvePendingMerges( | 427 void StructuredMachineAssembler::IfBuilder::IfClause::ResolvePendingMerges( |
428 StructuredMachineAssembler* smasm, CombineType combine_type, | 428 StructuredMachineAssembler* smasm, CombineType combine_type, |
429 ResolutionType resolution_type) { | 429 ResolutionType resolution_type) { |
430 ASSERT(smasm->current_environment_ == NULL); | 430 DCHECK(smasm->current_environment_ == NULL); |
431 PendingMergeStackRange data = ComputeRelevantMerges(combine_type); | 431 PendingMergeStackRange data = ComputeRelevantMerges(combine_type); |
432 ASSERT_EQ(data.merge_stack_->back(), unresolved_list_tail_); | 432 DCHECK_EQ(data.merge_stack_->back(), unresolved_list_tail_); |
433 ASSERT(data.size_ > 0); | 433 DCHECK(data.size_ > 0); |
434 // TODO(dcarney): assert no new variables created during expression building. | 434 // TODO(dcarney): assert no new variables created during expression building. |
435 int truncate_at = initial_environment_size_; | 435 int truncate_at = initial_environment_size_; |
436 if (data.size_ == 1) { | 436 if (data.size_ == 1) { |
437 // Just copy environment in common case. | 437 // Just copy environment in common case. |
438 smasm->current_environment_ = | 438 smasm->current_environment_ = |
439 smasm->Copy(unresolved_list_tail_->environment_, truncate_at); | 439 smasm->Copy(unresolved_list_tail_->environment_, truncate_at); |
440 } else { | 440 } else { |
441 EnvironmentVector environments( | 441 EnvironmentVector environments( |
442 EnvironmentVector::allocator_type(smasm->zone())); | 442 EnvironmentVector::allocator_type(smasm->zone())); |
443 environments.reserve(data.size_); | 443 environments.reserve(data.size_); |
444 CopyEnvironments(data, &environments); | 444 CopyEnvironments(data, &environments); |
445 ASSERT(static_cast<int>(environments.size()) == data.size_); | 445 DCHECK(static_cast<int>(environments.size()) == data.size_); |
446 smasm->Merge(&environments, truncate_at); | 446 smasm->Merge(&environments, truncate_at); |
447 } | 447 } |
448 Environment* then_environment = then_environment_; | 448 Environment* then_environment = then_environment_; |
449 Environment* else_environment = NULL; | 449 Environment* else_environment = NULL; |
450 if (resolution_type == kExpressionDone) { | 450 if (resolution_type == kExpressionDone) { |
451 ASSERT(expression_states_.size() == 1); | 451 DCHECK(expression_states_.size() == 1); |
452 // Set the current then_ or else_environment_ to the new merged environment. | 452 // Set the current then_ or else_environment_ to the new merged environment. |
453 if (combine_type == kCombineThen) { | 453 if (combine_type == kCombineThen) { |
454 ASSERT(then_environment_ == NULL && else_environment_ == NULL); | 454 DCHECK(then_environment_ == NULL && else_environment_ == NULL); |
455 this->then_environment_ = smasm->current_environment_; | 455 this->then_environment_ = smasm->current_environment_; |
456 } else { | 456 } else { |
457 ASSERT(else_environment_ == NULL); | 457 DCHECK(else_environment_ == NULL); |
458 this->else_environment_ = smasm->current_environment_; | 458 this->else_environment_ = smasm->current_environment_; |
459 } | 459 } |
460 } else { | 460 } else { |
461 ASSERT(resolution_type == kExpressionTerm); | 461 DCHECK(resolution_type == kExpressionTerm); |
462 ASSERT(then_environment_ == NULL && else_environment_ == NULL); | 462 DCHECK(then_environment_ == NULL && else_environment_ == NULL); |
463 } | 463 } |
464 if (combine_type == kCombineThen) { | 464 if (combine_type == kCombineThen) { |
465 then_environment = smasm->current_environment_; | 465 then_environment = smasm->current_environment_; |
466 } else { | 466 } else { |
467 ASSERT(combine_type == kCombineElse); | 467 DCHECK(combine_type == kCombineElse); |
468 else_environment = smasm->current_environment_; | 468 else_environment = smasm->current_environment_; |
469 } | 469 } |
470 // Finalize branches and clear the pending stack. | 470 // Finalize branches and clear the pending stack. |
471 FinalizeBranches(smasm, data, combine_type, then_environment, | 471 FinalizeBranches(smasm, data, combine_type, then_environment, |
472 else_environment); | 472 else_environment); |
473 } | 473 } |
474 | 474 |
475 | 475 |
476 void StructuredMachineAssembler::IfBuilder::IfClause::CopyEnvironments( | 476 void StructuredMachineAssembler::IfBuilder::IfClause::CopyEnvironments( |
477 const PendingMergeStackRange& data, EnvironmentVector* environments) { | 477 const PendingMergeStackRange& data, EnvironmentVector* environments) { |
478 PendingMergeStack::iterator i = data.merge_stack_->begin(); | 478 PendingMergeStack::iterator i = data.merge_stack_->begin(); |
479 PendingMergeStack::iterator end = data.merge_stack_->end(); | 479 PendingMergeStack::iterator end = data.merge_stack_->end(); |
480 for (i += data.start_; i != end; ++i) { | 480 for (i += data.start_; i != end; ++i) { |
481 environments->push_back((*i)->environment_); | 481 environments->push_back((*i)->environment_); |
482 } | 482 } |
483 } | 483 } |
484 | 484 |
485 | 485 |
486 void StructuredMachineAssembler::IfBuilder::IfClause::PushNewExpressionState() { | 486 void StructuredMachineAssembler::IfBuilder::IfClause::PushNewExpressionState() { |
487 ExpressionState next; | 487 ExpressionState next; |
488 next.pending_then_size_ = static_cast<int>(pending_then_merges_.size()); | 488 next.pending_then_size_ = static_cast<int>(pending_then_merges_.size()); |
489 next.pending_else_size_ = static_cast<int>(pending_else_merges_.size()); | 489 next.pending_else_size_ = static_cast<int>(pending_else_merges_.size()); |
490 expression_states_.push_back(next); | 490 expression_states_.push_back(next); |
491 } | 491 } |
492 | 492 |
493 | 493 |
494 void StructuredMachineAssembler::IfBuilder::IfClause::PopExpressionState() { | 494 void StructuredMachineAssembler::IfBuilder::IfClause::PopExpressionState() { |
495 expression_states_.pop_back(); | 495 expression_states_.pop_back(); |
496 ASSERT(!expression_states_.empty()); | 496 DCHECK(!expression_states_.empty()); |
497 } | 497 } |
498 | 498 |
499 | 499 |
500 void StructuredMachineAssembler::IfBuilder::IfClause::FinalizeBranches( | 500 void StructuredMachineAssembler::IfBuilder::IfClause::FinalizeBranches( |
501 StructuredMachineAssembler* smasm, const PendingMergeStackRange& data, | 501 StructuredMachineAssembler* smasm, const PendingMergeStackRange& data, |
502 CombineType combine_type, Environment* const then_environment, | 502 CombineType combine_type, Environment* const then_environment, |
503 Environment* const else_environment) { | 503 Environment* const else_environment) { |
504 ASSERT(unresolved_list_tail_ != NULL); | 504 DCHECK(unresolved_list_tail_ != NULL); |
505 ASSERT(smasm->current_environment_ != NULL); | 505 DCHECK(smasm->current_environment_ != NULL); |
506 if (data.size_ == 0) return; | 506 if (data.size_ == 0) return; |
507 PendingMergeStack::iterator curr = data.merge_stack_->begin(); | 507 PendingMergeStack::iterator curr = data.merge_stack_->begin(); |
508 PendingMergeStack::iterator end = data.merge_stack_->end(); | 508 PendingMergeStack::iterator end = data.merge_stack_->end(); |
509 // Finalize everything but the head first, | 509 // Finalize everything but the head first, |
510 // in the order the branches enter the merge block. | 510 // in the order the branches enter the merge block. |
511 end -= 1; | 511 end -= 1; |
512 Environment* true_val = then_environment; | 512 Environment* true_val = then_environment; |
513 Environment* false_val = else_environment; | 513 Environment* false_val = else_environment; |
514 Environment** next; | 514 Environment** next; |
515 if (combine_type == kCombineThen) { | 515 if (combine_type == kCombineThen) { |
516 next = &false_val; | 516 next = &false_val; |
517 } else { | 517 } else { |
518 ASSERT(combine_type == kCombineElse); | 518 DCHECK(combine_type == kCombineElse); |
519 next = &true_val; | 519 next = &true_val; |
520 } | 520 } |
521 for (curr += data.start_; curr != end; ++curr) { | 521 for (curr += data.start_; curr != end; ++curr) { |
522 UnresolvedBranch* branch = *curr; | 522 UnresolvedBranch* branch = *curr; |
523 *next = branch->next_->environment_; | 523 *next = branch->next_->environment_; |
524 smasm->AddBranch(branch->environment_, branch->condition_, true_val, | 524 smasm->AddBranch(branch->environment_, branch->condition_, true_val, |
525 false_val); | 525 false_val); |
526 } | 526 } |
527 ASSERT(curr + 1 == data.merge_stack_->end()); | 527 DCHECK(curr + 1 == data.merge_stack_->end()); |
528 // Now finalize the tail if possible. | 528 // Now finalize the tail if possible. |
529 if (then_environment != NULL && else_environment != NULL) { | 529 if (then_environment != NULL && else_environment != NULL) { |
530 UnresolvedBranch* branch = *curr; | 530 UnresolvedBranch* branch = *curr; |
531 smasm->AddBranch(branch->environment_, branch->condition_, then_environment, | 531 smasm->AddBranch(branch->environment_, branch->condition_, then_environment, |
532 else_environment); | 532 else_environment); |
533 } | 533 } |
534 // Clear the merge stack. | 534 // Clear the merge stack. |
535 PendingMergeStack::iterator begin = data.merge_stack_->begin(); | 535 PendingMergeStack::iterator begin = data.merge_stack_->begin(); |
536 begin += data.start_; | 536 begin += data.start_; |
537 data.merge_stack_->erase(begin, data.merge_stack_->end()); | 537 data.merge_stack_->erase(begin, data.merge_stack_->end()); |
538 ASSERT_EQ(static_cast<int>(data.merge_stack_->size()), data.start_); | 538 DCHECK_EQ(static_cast<int>(data.merge_stack_->size()), data.start_); |
539 } | 539 } |
540 | 540 |
541 | 541 |
542 void StructuredMachineAssembler::IfBuilder::End() { | 542 void StructuredMachineAssembler::IfBuilder::End() { |
543 ASSERT(!IsDone()); | 543 DCHECK(!IsDone()); |
544 AddCurrentToPending(); | 544 AddCurrentToPending(); |
545 size_t current_pending = pending_exit_merges_.size(); | 545 size_t current_pending = pending_exit_merges_.size(); |
546 // All unresolved branch edges are now set to pending. | 546 // All unresolved branch edges are now set to pending. |
547 for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end(); | 547 for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end(); |
548 ++i) { | 548 ++i) { |
549 IfClause* clause = *i; | 549 IfClause* clause = *i; |
550 ASSERT(clause->expression_states_.size() == 1); | 550 DCHECK(clause->expression_states_.size() == 1); |
551 PendingMergeStackRange data; | 551 PendingMergeStackRange data; |
552 // Copy then environments. | 552 // Copy then environments. |
553 data = clause->ComputeRelevantMerges(kCombineThen); | 553 data = clause->ComputeRelevantMerges(kCombineThen); |
554 clause->CopyEnvironments(data, &pending_exit_merges_); | 554 clause->CopyEnvironments(data, &pending_exit_merges_); |
555 Environment* head = NULL; | 555 Environment* head = NULL; |
556 // Will resolve the head node in the else_merge | 556 // Will resolve the head node in the else_merge |
557 if (data.size_ > 0 && clause->then_environment_ == NULL && | 557 if (data.size_ > 0 && clause->then_environment_ == NULL && |
558 clause->else_environment_ == NULL) { | 558 clause->else_environment_ == NULL) { |
559 head = pending_exit_merges_.back(); | 559 head = pending_exit_merges_.back(); |
560 pending_exit_merges_.pop_back(); | 560 pending_exit_merges_.pop_back(); |
561 } | 561 } |
562 // Copy else environments. | 562 // Copy else environments. |
563 data = clause->ComputeRelevantMerges(kCombineElse); | 563 data = clause->ComputeRelevantMerges(kCombineElse); |
564 clause->CopyEnvironments(data, &pending_exit_merges_); | 564 clause->CopyEnvironments(data, &pending_exit_merges_); |
565 if (head != NULL) { | 565 if (head != NULL) { |
566 // Must have data to merge, or else head will never get a branch. | 566 // Must have data to merge, or else head will never get a branch. |
567 ASSERT(data.size_ != 0); | 567 DCHECK(data.size_ != 0); |
568 pending_exit_merges_.push_back(head); | 568 pending_exit_merges_.push_back(head); |
569 } | 569 } |
570 } | 570 } |
571 smasm_->Merge(&pending_exit_merges_, | 571 smasm_->Merge(&pending_exit_merges_, |
572 if_clauses_[0]->initial_environment_size_); | 572 if_clauses_[0]->initial_environment_size_); |
573 // Anything initally pending jumps into the new environment. | 573 // Anything initally pending jumps into the new environment. |
574 for (size_t i = 0; i < current_pending; ++i) { | 574 for (size_t i = 0; i < current_pending; ++i) { |
575 smasm_->AddGoto(pending_exit_merges_[i], smasm_->current_environment_); | 575 smasm_->AddGoto(pending_exit_merges_[i], smasm_->current_environment_); |
576 } | 576 } |
577 // Resolve all branches. | 577 // Resolve all branches. |
(...skipping 16 matching lines...) Expand all Loading... |
594 if (else_environment == NULL) { | 594 if (else_environment == NULL) { |
595 else_environment = smasm_->current_environment_; | 595 else_environment = smasm_->current_environment_; |
596 } | 596 } |
597 data = clause->ComputeRelevantMerges(kCombineElse); | 597 data = clause->ComputeRelevantMerges(kCombineElse); |
598 clause->FinalizeBranches(smasm_, data, kCombineElse, then_environment, | 598 clause->FinalizeBranches(smasm_, data, kCombineElse, then_environment, |
599 else_environment); | 599 else_environment); |
600 } | 600 } |
601 // Future accesses to this builder should crash immediately. | 601 // Future accesses to this builder should crash immediately. |
602 pending_exit_merges_.clear(); | 602 pending_exit_merges_.clear(); |
603 if_clauses_.clear(); | 603 if_clauses_.clear(); |
604 ASSERT(IsDone()); | 604 DCHECK(IsDone()); |
605 } | 605 } |
606 | 606 |
607 | 607 |
608 StructuredMachineAssembler::LoopBuilder::LoopBuilder( | 608 StructuredMachineAssembler::LoopBuilder::LoopBuilder( |
609 StructuredMachineAssembler* smasm) | 609 StructuredMachineAssembler* smasm) |
610 : smasm_(smasm), | 610 : smasm_(smasm), |
611 header_environment_(NULL), | 611 header_environment_(NULL), |
612 pending_header_merges_(EnvironmentVector::allocator_type(smasm_->zone())), | 612 pending_header_merges_(EnvironmentVector::allocator_type(smasm_->zone())), |
613 pending_exit_merges_(EnvironmentVector::allocator_type(smasm_->zone())) { | 613 pending_exit_merges_(EnvironmentVector::allocator_type(smasm_->zone())) { |
614 ASSERT(smasm_->current_environment_ != NULL); | 614 DCHECK(smasm_->current_environment_ != NULL); |
615 // Create header environment. | 615 // Create header environment. |
616 header_environment_ = smasm_->CopyForLoopHeader(smasm_->current_environment_); | 616 header_environment_ = smasm_->CopyForLoopHeader(smasm_->current_environment_); |
617 smasm_->AddGoto(smasm_->current_environment_, header_environment_); | 617 smasm_->AddGoto(smasm_->current_environment_, header_environment_); |
618 // Create body environment. | 618 // Create body environment. |
619 Environment* body = smasm_->Copy(header_environment_); | 619 Environment* body = smasm_->Copy(header_environment_); |
620 smasm_->AddGoto(header_environment_, body); | 620 smasm_->AddGoto(header_environment_, body); |
621 smasm_->current_environment_ = body; | 621 smasm_->current_environment_ = body; |
622 ASSERT(!IsDone()); | 622 DCHECK(!IsDone()); |
623 } | 623 } |
624 | 624 |
625 | 625 |
626 void StructuredMachineAssembler::LoopBuilder::Continue() { | 626 void StructuredMachineAssembler::LoopBuilder::Continue() { |
627 ASSERT(!IsDone()); | 627 DCHECK(!IsDone()); |
628 pending_header_merges_.push_back(smasm_->current_environment_); | 628 pending_header_merges_.push_back(smasm_->current_environment_); |
629 smasm_->CopyCurrentAsDead(); | 629 smasm_->CopyCurrentAsDead(); |
630 } | 630 } |
631 | 631 |
632 | 632 |
633 void StructuredMachineAssembler::LoopBuilder::Break() { | 633 void StructuredMachineAssembler::LoopBuilder::Break() { |
634 ASSERT(!IsDone()); | 634 DCHECK(!IsDone()); |
635 pending_exit_merges_.push_back(smasm_->current_environment_); | 635 pending_exit_merges_.push_back(smasm_->current_environment_); |
636 smasm_->CopyCurrentAsDead(); | 636 smasm_->CopyCurrentAsDead(); |
637 } | 637 } |
638 | 638 |
639 | 639 |
640 void StructuredMachineAssembler::LoopBuilder::End() { | 640 void StructuredMachineAssembler::LoopBuilder::End() { |
641 ASSERT(!IsDone()); | 641 DCHECK(!IsDone()); |
642 if (smasm_->current_environment_ != NULL) { | 642 if (smasm_->current_environment_ != NULL) { |
643 Continue(); | 643 Continue(); |
644 } | 644 } |
645 // Do loop header merges. | 645 // Do loop header merges. |
646 smasm_->MergeBackEdgesToLoopHeader(header_environment_, | 646 smasm_->MergeBackEdgesToLoopHeader(header_environment_, |
647 &pending_header_merges_); | 647 &pending_header_merges_); |
648 int initial_size = static_cast<int>(header_environment_->variables_.size()); | 648 int initial_size = static_cast<int>(header_environment_->variables_.size()); |
649 // Do loop exit merges, truncating loop variables away. | 649 // Do loop exit merges, truncating loop variables away. |
650 smasm_->Merge(&pending_exit_merges_, initial_size); | 650 smasm_->Merge(&pending_exit_merges_, initial_size); |
651 for (EnvironmentVector::iterator i = pending_exit_merges_.begin(); | 651 for (EnvironmentVector::iterator i = pending_exit_merges_.begin(); |
652 i != pending_exit_merges_.end(); ++i) { | 652 i != pending_exit_merges_.end(); ++i) { |
653 smasm_->AddGoto(*i, smasm_->current_environment_); | 653 smasm_->AddGoto(*i, smasm_->current_environment_); |
654 } | 654 } |
655 pending_header_merges_.clear(); | 655 pending_header_merges_.clear(); |
656 pending_exit_merges_.clear(); | 656 pending_exit_merges_.clear(); |
657 header_environment_ = NULL; | 657 header_environment_ = NULL; |
658 ASSERT(IsDone()); | 658 DCHECK(IsDone()); |
659 } | 659 } |
660 | 660 |
661 } // namespace compiler | 661 } // namespace compiler |
662 } // namespace internal | 662 } // namespace internal |
663 } // namespace v8 | 663 } // namespace v8 |
OLD | NEW |