Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/structured-machine-assembler.cc

Issue 539903002: Move StructuredMachineAssembler into cctest suite. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add a TODO. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/structured-machine-assembler.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "src/compiler/pipeline.h"
6 #include "src/compiler/scheduler.h"
7 #include "src/compiler/structured-machine-assembler.h"
8
9 namespace v8 {
10 namespace internal {
11 namespace compiler {
12
13 Node* Variable::Get() const { return smasm_->GetVariable(offset_); }
14
15
16 void Variable::Set(Node* value) const { smasm_->SetVariable(offset_, value); }
17
18
19 StructuredMachineAssembler::StructuredMachineAssembler(
20 Graph* graph, MachineSignature* machine_sig, MachineType word)
21 : GraphBuilder(graph),
22 schedule_(new (zone()) Schedule(zone())),
23 machine_(zone(), word),
24 common_(zone()),
25 machine_sig_(machine_sig),
26 call_descriptor_(
27 Linkage::GetSimplifiedCDescriptor(graph->zone(), machine_sig)),
28 parameters_(NULL),
29 current_environment_(new (zone())
30 Environment(zone(), schedule()->start(), false)),
31 number_of_variables_(0) {
32 int param_count = static_cast<int>(parameter_count());
33 Node* s = graph->NewNode(common_.Start(param_count));
34 graph->SetStart(s);
35 if (parameter_count() == 0) return;
36 parameters_ = zone()->NewArray<Node*>(param_count);
37 for (size_t i = 0; i < parameter_count(); ++i) {
38 parameters_[i] =
39 NewNode(common()->Parameter(static_cast<int>(i)), graph->start());
40 }
41 }
42
43
44 Schedule* StructuredMachineAssembler::Export() {
45 // Compute the correct codegen order.
46 DCHECK(schedule_->rpo_order()->empty());
47 Scheduler::ComputeSpecialRPO(schedule_);
48 // Invalidate MachineAssembler.
49 Schedule* schedule = schedule_;
50 schedule_ = NULL;
51 return schedule;
52 }
53
54
55 Node* StructuredMachineAssembler::Parameter(size_t index) {
56 DCHECK(index < parameter_count());
57 return parameters_[index];
58 }
59
60
61 Node* StructuredMachineAssembler::MakeNode(Operator* op, int input_count,
62 Node** inputs) {
63 DCHECK(ScheduleValid());
64 DCHECK(current_environment_ != NULL);
65 Node* node = graph()->NewNode(op, input_count, inputs);
66 BasicBlock* block = NULL;
67 switch (op->opcode()) {
68 case IrOpcode::kParameter:
69 case IrOpcode::kInt32Constant:
70 case IrOpcode::kInt64Constant:
71 case IrOpcode::kFloat64Constant:
72 case IrOpcode::kExternalConstant:
73 case IrOpcode::kNumberConstant:
74 case IrOpcode::kHeapConstant:
75 // Parameters and constants must be in start.
76 block = schedule()->start();
77 break;
78 default:
79 // Verify all leaf nodes handled above.
80 DCHECK((op->OutputCount() == 0) == (op->opcode() == IrOpcode::kStore));
81 block = current_environment_->block_;
82 break;
83 }
84 if (block != NULL) {
85 schedule()->AddNode(block, node);
86 }
87 return node;
88 }
89
90
91 Variable StructuredMachineAssembler::NewVariable(Node* initial_value) {
92 CHECK(initial_value != NULL);
93 int offset = number_of_variables_++;
94 // Extend current environment to correct number of values.
95 NodeVector* variables = CurrentVars();
96 size_t to_add = number_of_variables_ - variables->size();
97 if (to_add != 0) {
98 variables->reserve(number_of_variables_);
99 variables->insert(variables->end(), to_add, NULL);
100 }
101 variables->at(offset) = initial_value;
102 return Variable(this, offset);
103 }
104
105
106 Node* StructuredMachineAssembler::GetVariable(int offset) {
107 DCHECK(ScheduleValid());
108 return VariableAt(current_environment_, offset);
109 }
110
111
112 void StructuredMachineAssembler::SetVariable(int offset, Node* value) {
113 DCHECK(ScheduleValid());
114 Node*& ref = VariableAt(current_environment_, offset);
115 ref = value;
116 }
117
118
119 Node*& StructuredMachineAssembler::VariableAt(Environment* environment,
120 int32_t offset) {
121 // Variable used out of scope.
122 CHECK(static_cast<size_t>(offset) < environment->variables_.size());
123 Node*& value = environment->variables_.at(offset);
124 CHECK(value != NULL); // Variable used out of scope.
125 return value;
126 }
127
128
129 void StructuredMachineAssembler::Return(Node* value) {
130 BasicBlock* block = current_environment_->block_;
131 if (block != NULL) {
132 schedule()->AddReturn(block, value);
133 }
134 CopyCurrentAsDead();
135 }
136
137
138 void StructuredMachineAssembler::CopyCurrentAsDead() {
139 DCHECK(current_environment_ != NULL);
140 bool is_dead = current_environment_->is_dead_;
141 current_environment_->is_dead_ = true;
142 Environment* next = Copy(current_environment_);
143 current_environment_->is_dead_ = is_dead;
144 current_environment_ = next;
145 }
146
147
148 StructuredMachineAssembler::Environment* StructuredMachineAssembler::Copy(
149 Environment* env, int truncate_at) {
150 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_);
151 if (!new_env->is_dead_) {
152 new_env->block_ = schedule()->NewBasicBlock();
153 }
154 new_env->variables_.reserve(truncate_at);
155 NodeVectorIter end = env->variables_.end();
156 DCHECK(truncate_at <= static_cast<int>(env->variables_.size()));
157 end -= static_cast<int>(env->variables_.size()) - truncate_at;
158 new_env->variables_.insert(new_env->variables_.begin(),
159 env->variables_.begin(), end);
160 return new_env;
161 }
162
163
164 StructuredMachineAssembler::Environment*
165 StructuredMachineAssembler::CopyForLoopHeader(Environment* env) {
166 Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_);
167 if (!new_env->is_dead_) {
168 new_env->block_ = schedule()->NewBasicBlock();
169 }
170 new_env->variables_.reserve(env->variables_.size());
171 for (NodeVectorIter i = env->variables_.begin(); i != env->variables_.end();
172 ++i) {
173 Node* phi = NULL;
174 if (*i != NULL) {
175 phi = graph()->NewNode(common()->Phi(1), *i);
176 if (new_env->block_ != NULL) {
177 schedule()->AddNode(new_env->block_, phi);
178 }
179 }
180 new_env->variables_.push_back(phi);
181 }
182 return new_env;
183 }
184
185
186 void StructuredMachineAssembler::MergeBackEdgesToLoopHeader(
187 Environment* header, EnvironmentVector* environments) {
188 // Only merge as many variables are were declared before this loop.
189 int n = static_cast<int>(header->variables_.size());
190 // TODO(dcarney): invert loop order and extend phis once.
191 for (EnvironmentVector::iterator i = environments->begin();
192 i != environments->end(); ++i) {
193 Environment* from = *i;
194 if (from->is_dead_) continue;
195 AddGoto(from, header);
196 for (int i = 0; i < n; ++i) {
197 Node* phi = header->variables_[i];
198 if (phi == NULL) continue;
199 phi->set_op(common()->Phi(phi->InputCount() + 1));
200 phi->AppendInput(zone(), VariableAt(from, i));
201 }
202 }
203 }
204
205
206 void StructuredMachineAssembler::Merge(EnvironmentVector* environments,
207 int truncate_at) {
208 DCHECK(current_environment_ == NULL || current_environment_->is_dead_);
209 Environment* next = new (zone()) Environment(zone(), NULL, false);
210 current_environment_ = next;
211 size_t n_vars = number_of_variables_;
212 NodeVector& vars = next->variables_;
213 vars.reserve(n_vars);
214 Node** scratch = NULL;
215 size_t n_envs = environments->size();
216 Environment** live_environments =
217 zone()->NewArray<Environment*>(static_cast<int>(n_envs));
218 size_t n_live = 0;
219 for (size_t i = 0; i < n_envs; i++) {
220 if (environments->at(i)->is_dead_) continue;
221 live_environments[n_live++] = environments->at(i);
222 }
223 n_envs = n_live;
224 if (n_live == 0) next->is_dead_ = true;
225 if (!next->is_dead_) {
226 next->block_ = schedule()->NewBasicBlock();
227 }
228 for (size_t j = 0; j < n_vars; ++j) {
229 Node* resolved = NULL;
230 // Find first non equal variable.
231 size_t i = 0;
232 for (; i < n_envs; i++) {
233 DCHECK(live_environments[i]->variables_.size() <= n_vars);
234 Node* val = NULL;
235 if (j < static_cast<size_t>(truncate_at)) {
236 val = live_environments[i]->variables_.at(j);
237 // TODO(dcarney): record start position at time of split.
238 // all variables after this should not be NULL.
239 if (val != NULL) {
240 val = VariableAt(live_environments[i], static_cast<int>(j));
241 }
242 }
243 if (val == resolved) continue;
244 if (i != 0) break;
245 resolved = val;
246 }
247 // Have to generate a phi.
248 if (i < n_envs) {
249 // All values thus far uninitialized, variable used out of scope.
250 CHECK(resolved != NULL);
251 // Init scratch buffer.
252 if (scratch == NULL) {
253 scratch = zone()->NewArray<Node*>(static_cast<int>(n_envs));
254 }
255 for (size_t k = 0; k < i; k++) {
256 scratch[k] = resolved;
257 }
258 for (; i < n_envs; i++) {
259 scratch[i] = live_environments[i]->variables_[j];
260 }
261 resolved = graph()->NewNode(common()->Phi(static_cast<int>(n_envs)),
262 static_cast<int>(n_envs), scratch);
263 if (next->block_ != NULL) {
264 schedule()->AddNode(next->block_, resolved);
265 }
266 }
267 vars.push_back(resolved);
268 }
269 }
270
271
272 void StructuredMachineAssembler::AddGoto(Environment* from, Environment* to) {
273 if (to->is_dead_) {
274 DCHECK(from->is_dead_);
275 return;
276 }
277 DCHECK(!from->is_dead_);
278 schedule()->AddGoto(from->block_, to->block_);
279 }
280
281
282 // TODO(dcarney): add pass before rpo to schedule to compute these.
283 BasicBlock* StructuredMachineAssembler::TrampolineFor(BasicBlock* block) {
284 BasicBlock* trampoline = schedule()->NewBasicBlock();
285 schedule()->AddGoto(trampoline, block);
286 return trampoline;
287 }
288
289
290 void StructuredMachineAssembler::AddBranch(Environment* environment,
291 Node* condition,
292 Environment* true_val,
293 Environment* false_val) {
294 DCHECK(environment->is_dead_ == true_val->is_dead_);
295 DCHECK(environment->is_dead_ == false_val->is_dead_);
296 if (true_val->block_ == false_val->block_) {
297 if (environment->is_dead_) return;
298 AddGoto(environment, true_val);
299 return;
300 }
301 Node* branch = graph()->NewNode(common()->Branch(), condition);
302 if (environment->is_dead_) return;
303 BasicBlock* true_block = TrampolineFor(true_val->block_);
304 BasicBlock* false_block = TrampolineFor(false_val->block_);
305 schedule()->AddBranch(environment->block_, branch, true_block, false_block);
306 }
307
308
309 StructuredMachineAssembler::Environment::Environment(Zone* zone,
310 BasicBlock* block,
311 bool is_dead)
312 : block_(block), variables_(zone), is_dead_(is_dead) {}
313
314
315 StructuredMachineAssembler::IfBuilder::IfBuilder(
316 StructuredMachineAssembler* smasm)
317 : smasm_(smasm),
318 if_clauses_(smasm_->zone()),
319 pending_exit_merges_(smasm_->zone()) {
320 DCHECK(smasm_->current_environment_ != NULL);
321 PushNewIfClause();
322 DCHECK(!IsDone());
323 }
324
325
326 StructuredMachineAssembler::IfBuilder&
327 StructuredMachineAssembler::IfBuilder::If() {
328 DCHECK(smasm_->current_environment_ != NULL);
329 IfClause* clause = CurrentClause();
330 if (clause->then_environment_ != NULL || clause->else_environment_ != NULL) {
331 PushNewIfClause();
332 }
333 return *this;
334 }
335
336
337 StructuredMachineAssembler::IfBuilder&
338 StructuredMachineAssembler::IfBuilder::If(Node* condition) {
339 If();
340 IfClause* clause = CurrentClause();
341 // Store branch for future resolution.
342 UnresolvedBranch* next = new (smasm_->zone())
343 UnresolvedBranch(smasm_->current_environment_, condition, NULL);
344 if (clause->unresolved_list_tail_ != NULL) {
345 clause->unresolved_list_tail_->next_ = next;
346 }
347 clause->unresolved_list_tail_ = next;
348 // Push onto merge queues.
349 clause->pending_else_merges_.push_back(next);
350 clause->pending_then_merges_.push_back(next);
351 smasm_->current_environment_ = NULL;
352 return *this;
353 }
354
355
356 void StructuredMachineAssembler::IfBuilder::And() {
357 CurrentClause()->ResolvePendingMerges(smasm_, kCombineThen, kExpressionTerm);
358 }
359
360
361 void StructuredMachineAssembler::IfBuilder::Or() {
362 CurrentClause()->ResolvePendingMerges(smasm_, kCombineElse, kExpressionTerm);
363 }
364
365
366 void StructuredMachineAssembler::IfBuilder::Then() {
367 CurrentClause()->ResolvePendingMerges(smasm_, kCombineThen, kExpressionDone);
368 }
369
370
371 void StructuredMachineAssembler::IfBuilder::Else() {
372 AddCurrentToPending();
373 CurrentClause()->ResolvePendingMerges(smasm_, kCombineElse, kExpressionDone);
374 }
375
376
377 void StructuredMachineAssembler::IfBuilder::AddCurrentToPending() {
378 if (smasm_->current_environment_ != NULL &&
379 !smasm_->current_environment_->is_dead_) {
380 pending_exit_merges_.push_back(smasm_->current_environment_);
381 }
382 smasm_->current_environment_ = NULL;
383 }
384
385
386 void StructuredMachineAssembler::IfBuilder::PushNewIfClause() {
387 int curr_size =
388 static_cast<int>(smasm_->current_environment_->variables_.size());
389 IfClause* clause = new (smasm_->zone()) IfClause(smasm_->zone(), curr_size);
390 if_clauses_.push_back(clause);
391 }
392
393
394 StructuredMachineAssembler::IfBuilder::IfClause::IfClause(
395 Zone* zone, int initial_environment_size)
396 : unresolved_list_tail_(NULL),
397 initial_environment_size_(initial_environment_size),
398 expression_states_(zone),
399 pending_then_merges_(zone),
400 pending_else_merges_(zone),
401 then_environment_(NULL),
402 else_environment_(NULL) {
403 PushNewExpressionState();
404 }
405
406
407 StructuredMachineAssembler::IfBuilder::PendingMergeStackRange
408 StructuredMachineAssembler::IfBuilder::IfClause::ComputeRelevantMerges(
409 CombineType combine_type) {
410 DCHECK(!expression_states_.empty());
411 PendingMergeStack* stack;
412 int start;
413 if (combine_type == kCombineThen) {
414 stack = &pending_then_merges_;
415 start = expression_states_.back().pending_then_size_;
416 } else {
417 DCHECK(combine_type == kCombineElse);
418 stack = &pending_else_merges_;
419 start = expression_states_.back().pending_else_size_;
420 }
421 PendingMergeStackRange data;
422 data.merge_stack_ = stack;
423 data.start_ = start;
424 data.size_ = static_cast<int>(stack->size()) - start;
425 return data;
426 }
427
428
429 void StructuredMachineAssembler::IfBuilder::IfClause::ResolvePendingMerges(
430 StructuredMachineAssembler* smasm, CombineType combine_type,
431 ResolutionType resolution_type) {
432 DCHECK(smasm->current_environment_ == NULL);
433 PendingMergeStackRange data = ComputeRelevantMerges(combine_type);
434 DCHECK_EQ(data.merge_stack_->back(), unresolved_list_tail_);
435 DCHECK(data.size_ > 0);
436 // TODO(dcarney): assert no new variables created during expression building.
437 int truncate_at = initial_environment_size_;
438 if (data.size_ == 1) {
439 // Just copy environment in common case.
440 smasm->current_environment_ =
441 smasm->Copy(unresolved_list_tail_->environment_, truncate_at);
442 } else {
443 EnvironmentVector environments(smasm->zone());
444 environments.reserve(data.size_);
445 CopyEnvironments(data, &environments);
446 DCHECK(static_cast<int>(environments.size()) == data.size_);
447 smasm->Merge(&environments, truncate_at);
448 }
449 Environment* then_environment = then_environment_;
450 Environment* else_environment = NULL;
451 if (resolution_type == kExpressionDone) {
452 DCHECK(expression_states_.size() == 1);
453 // Set the current then_ or else_environment_ to the new merged environment.
454 if (combine_type == kCombineThen) {
455 DCHECK(then_environment_ == NULL && else_environment_ == NULL);
456 this->then_environment_ = smasm->current_environment_;
457 } else {
458 DCHECK(else_environment_ == NULL);
459 this->else_environment_ = smasm->current_environment_;
460 }
461 } else {
462 DCHECK(resolution_type == kExpressionTerm);
463 DCHECK(then_environment_ == NULL && else_environment_ == NULL);
464 }
465 if (combine_type == kCombineThen) {
466 then_environment = smasm->current_environment_;
467 } else {
468 DCHECK(combine_type == kCombineElse);
469 else_environment = smasm->current_environment_;
470 }
471 // Finalize branches and clear the pending stack.
472 FinalizeBranches(smasm, data, combine_type, then_environment,
473 else_environment);
474 }
475
476
477 void StructuredMachineAssembler::IfBuilder::IfClause::CopyEnvironments(
478 const PendingMergeStackRange& data, EnvironmentVector* environments) {
479 PendingMergeStack::iterator i = data.merge_stack_->begin();
480 PendingMergeStack::iterator end = data.merge_stack_->end();
481 for (i += data.start_; i != end; ++i) {
482 environments->push_back((*i)->environment_);
483 }
484 }
485
486
487 void StructuredMachineAssembler::IfBuilder::IfClause::PushNewExpressionState() {
488 ExpressionState next;
489 next.pending_then_size_ = static_cast<int>(pending_then_merges_.size());
490 next.pending_else_size_ = static_cast<int>(pending_else_merges_.size());
491 expression_states_.push_back(next);
492 }
493
494
495 void StructuredMachineAssembler::IfBuilder::IfClause::PopExpressionState() {
496 expression_states_.pop_back();
497 DCHECK(!expression_states_.empty());
498 }
499
500
501 void StructuredMachineAssembler::IfBuilder::IfClause::FinalizeBranches(
502 StructuredMachineAssembler* smasm, const PendingMergeStackRange& data,
503 CombineType combine_type, Environment* const then_environment,
504 Environment* const else_environment) {
505 DCHECK(unresolved_list_tail_ != NULL);
506 DCHECK(smasm->current_environment_ != NULL);
507 if (data.size_ == 0) return;
508 PendingMergeStack::iterator curr = data.merge_stack_->begin();
509 PendingMergeStack::iterator end = data.merge_stack_->end();
510 // Finalize everything but the head first,
511 // in the order the branches enter the merge block.
512 end -= 1;
513 Environment* true_val = then_environment;
514 Environment* false_val = else_environment;
515 Environment** next;
516 if (combine_type == kCombineThen) {
517 next = &false_val;
518 } else {
519 DCHECK(combine_type == kCombineElse);
520 next = &true_val;
521 }
522 for (curr += data.start_; curr != end; ++curr) {
523 UnresolvedBranch* branch = *curr;
524 *next = branch->next_->environment_;
525 smasm->AddBranch(branch->environment_, branch->condition_, true_val,
526 false_val);
527 }
528 DCHECK(curr + 1 == data.merge_stack_->end());
529 // Now finalize the tail if possible.
530 if (then_environment != NULL && else_environment != NULL) {
531 UnresolvedBranch* branch = *curr;
532 smasm->AddBranch(branch->environment_, branch->condition_, then_environment,
533 else_environment);
534 }
535 // Clear the merge stack.
536 PendingMergeStack::iterator begin = data.merge_stack_->begin();
537 begin += data.start_;
538 data.merge_stack_->erase(begin, data.merge_stack_->end());
539 DCHECK_EQ(static_cast<int>(data.merge_stack_->size()), data.start_);
540 }
541
542
543 void StructuredMachineAssembler::IfBuilder::End() {
544 DCHECK(!IsDone());
545 AddCurrentToPending();
546 size_t current_pending = pending_exit_merges_.size();
547 // All unresolved branch edges are now set to pending.
548 for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end();
549 ++i) {
550 IfClause* clause = *i;
551 DCHECK(clause->expression_states_.size() == 1);
552 PendingMergeStackRange data;
553 // Copy then environments.
554 data = clause->ComputeRelevantMerges(kCombineThen);
555 clause->CopyEnvironments(data, &pending_exit_merges_);
556 Environment* head = NULL;
557 // Will resolve the head node in the else_merge
558 if (data.size_ > 0 && clause->then_environment_ == NULL &&
559 clause->else_environment_ == NULL) {
560 head = pending_exit_merges_.back();
561 pending_exit_merges_.pop_back();
562 }
563 // Copy else environments.
564 data = clause->ComputeRelevantMerges(kCombineElse);
565 clause->CopyEnvironments(data, &pending_exit_merges_);
566 if (head != NULL) {
567 // Must have data to merge, or else head will never get a branch.
568 DCHECK(data.size_ != 0);
569 pending_exit_merges_.push_back(head);
570 }
571 }
572 smasm_->Merge(&pending_exit_merges_,
573 if_clauses_[0]->initial_environment_size_);
574 // Anything initally pending jumps into the new environment.
575 for (size_t i = 0; i < current_pending; ++i) {
576 smasm_->AddGoto(pending_exit_merges_[i], smasm_->current_environment_);
577 }
578 // Resolve all branches.
579 for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end();
580 ++i) {
581 IfClause* clause = *i;
582 // Must finalize all environments, so ensure they are set correctly.
583 Environment* then_environment = clause->then_environment_;
584 if (then_environment == NULL) {
585 then_environment = smasm_->current_environment_;
586 }
587 Environment* else_environment = clause->else_environment_;
588 PendingMergeStackRange data;
589 // Finalize then environments.
590 data = clause->ComputeRelevantMerges(kCombineThen);
591 clause->FinalizeBranches(smasm_, data, kCombineThen, then_environment,
592 else_environment);
593 // Finalize else environments.
594 // Now set the else environment so head is finalized for edge case above.
595 if (else_environment == NULL) {
596 else_environment = smasm_->current_environment_;
597 }
598 data = clause->ComputeRelevantMerges(kCombineElse);
599 clause->FinalizeBranches(smasm_, data, kCombineElse, then_environment,
600 else_environment);
601 }
602 // Future accesses to this builder should crash immediately.
603 pending_exit_merges_.clear();
604 if_clauses_.clear();
605 DCHECK(IsDone());
606 }
607
608
609 StructuredMachineAssembler::LoopBuilder::LoopBuilder(
610 StructuredMachineAssembler* smasm)
611 : smasm_(smasm),
612 header_environment_(NULL),
613 pending_header_merges_(smasm_->zone()),
614 pending_exit_merges_(smasm_->zone()) {
615 DCHECK(smasm_->current_environment_ != NULL);
616 // Create header environment.
617 header_environment_ = smasm_->CopyForLoopHeader(smasm_->current_environment_);
618 smasm_->AddGoto(smasm_->current_environment_, header_environment_);
619 // Create body environment.
620 Environment* body = smasm_->Copy(header_environment_);
621 smasm_->AddGoto(header_environment_, body);
622 smasm_->current_environment_ = body;
623 DCHECK(!IsDone());
624 }
625
626
627 void StructuredMachineAssembler::LoopBuilder::Continue() {
628 DCHECK(!IsDone());
629 pending_header_merges_.push_back(smasm_->current_environment_);
630 smasm_->CopyCurrentAsDead();
631 }
632
633
634 void StructuredMachineAssembler::LoopBuilder::Break() {
635 DCHECK(!IsDone());
636 pending_exit_merges_.push_back(smasm_->current_environment_);
637 smasm_->CopyCurrentAsDead();
638 }
639
640
641 void StructuredMachineAssembler::LoopBuilder::End() {
642 DCHECK(!IsDone());
643 if (smasm_->current_environment_ != NULL) {
644 Continue();
645 }
646 // Do loop header merges.
647 smasm_->MergeBackEdgesToLoopHeader(header_environment_,
648 &pending_header_merges_);
649 int initial_size = static_cast<int>(header_environment_->variables_.size());
650 // Do loop exit merges, truncating loop variables away.
651 smasm_->Merge(&pending_exit_merges_, initial_size);
652 for (EnvironmentVector::iterator i = pending_exit_merges_.begin();
653 i != pending_exit_merges_.end(); ++i) {
654 smasm_->AddGoto(*i, smasm_->current_environment_);
655 }
656 pending_header_merges_.clear();
657 pending_exit_merges_.clear();
658 header_environment_ = NULL;
659 DCHECK(IsDone());
660 }
661
662 } // namespace compiler
663 } // namespace internal
664 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/structured-machine-assembler.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698