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

Unified Diff: test/cctest/compiler/structured-machine-assembler.cc

Issue 544053002: [turbofan] Get rid of the StructuredMacroAssembler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 side-by-side diff with in-line comments
Download patch
Index: test/cctest/compiler/structured-machine-assembler.cc
diff --git a/test/cctest/compiler/structured-machine-assembler.cc b/test/cctest/compiler/structured-machine-assembler.cc
deleted file mode 100644
index 66c408a815af5fca1ee14c0b1141d89a014c3880..0000000000000000000000000000000000000000
--- a/test/cctest/compiler/structured-machine-assembler.cc
+++ /dev/null
@@ -1,630 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/pipeline.h"
-#include "src/compiler/scheduler.h"
-#include "test/cctest/compiler/structured-machine-assembler.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-Node* Variable::Get() const { return smasm_->GetVariable(offset_); }
-
-
-void Variable::Set(Node* value) const { smasm_->SetVariable(offset_, value); }
-
-
-StructuredMachineAssembler::StructuredMachineAssembler(
- Graph* graph, MachineSignature* machine_sig, MachineType word)
- : RawMachineAssembler(graph, machine_sig, word),
- current_environment_(new (zone())
- Environment(zone(), schedule()->start(), false)),
- number_of_variables_(0) {}
-
-
-Node* StructuredMachineAssembler::MakeNode(Operator* op, int input_count,
- Node** inputs) {
- DCHECK(ScheduleValid());
- DCHECK(current_environment_ != NULL);
- Node* node = graph()->NewNode(op, input_count, inputs);
- BasicBlock* block = NULL;
- switch (op->opcode()) {
- case IrOpcode::kParameter:
- case IrOpcode::kInt32Constant:
- case IrOpcode::kInt64Constant:
- case IrOpcode::kFloat64Constant:
- case IrOpcode::kExternalConstant:
- case IrOpcode::kNumberConstant:
- case IrOpcode::kHeapConstant:
- // Parameters and constants must be in start.
- block = schedule()->start();
- break;
- default:
- // Verify all leaf nodes handled above.
- DCHECK((op->OutputCount() == 0) == (op->opcode() == IrOpcode::kStore));
- block = current_environment_->block_;
- break;
- }
- if (block != NULL) {
- schedule()->AddNode(block, node);
- }
- return node;
-}
-
-
-Variable StructuredMachineAssembler::NewVariable(Node* initial_value) {
- CHECK(initial_value != NULL);
- int offset = number_of_variables_++;
- // Extend current environment to correct number of values.
- NodeVector* variables = CurrentVars();
- size_t to_add = number_of_variables_ - variables->size();
- if (to_add != 0) {
- variables->reserve(number_of_variables_);
- variables->insert(variables->end(), to_add, NULL);
- }
- variables->at(offset) = initial_value;
- return Variable(this, offset);
-}
-
-
-Node* StructuredMachineAssembler::GetVariable(int offset) {
- DCHECK(ScheduleValid());
- return VariableAt(current_environment_, offset);
-}
-
-
-void StructuredMachineAssembler::SetVariable(int offset, Node* value) {
- DCHECK(ScheduleValid());
- Node*& ref = VariableAt(current_environment_, offset);
- ref = value;
-}
-
-
-Node*& StructuredMachineAssembler::VariableAt(Environment* environment,
- int32_t offset) {
- // Variable used out of scope.
- CHECK(static_cast<size_t>(offset) < environment->variables_.size());
- Node*& value = environment->variables_.at(offset);
- CHECK(value != NULL); // Variable used out of scope.
- return value;
-}
-
-
-void StructuredMachineAssembler::Return(Node* value) {
- BasicBlock* block = current_environment_->block_;
- if (block != NULL) {
- schedule()->AddReturn(block, value);
- }
- CopyCurrentAsDead();
-}
-
-
-void StructuredMachineAssembler::CopyCurrentAsDead() {
- DCHECK(current_environment_ != NULL);
- bool is_dead = current_environment_->is_dead_;
- current_environment_->is_dead_ = true;
- Environment* next = Copy(current_environment_);
- current_environment_->is_dead_ = is_dead;
- current_environment_ = next;
-}
-
-
-StructuredMachineAssembler::Environment* StructuredMachineAssembler::Copy(
- Environment* env, int truncate_at) {
- Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_);
- if (!new_env->is_dead_) {
- new_env->block_ = schedule()->NewBasicBlock();
- }
- new_env->variables_.reserve(truncate_at);
- NodeVectorIter end = env->variables_.end();
- DCHECK(truncate_at <= static_cast<int>(env->variables_.size()));
- end -= static_cast<int>(env->variables_.size()) - truncate_at;
- new_env->variables_.insert(new_env->variables_.begin(),
- env->variables_.begin(), end);
- return new_env;
-}
-
-
-StructuredMachineAssembler::Environment*
-StructuredMachineAssembler::CopyForLoopHeader(Environment* env) {
- Environment* new_env = new (zone()) Environment(zone(), NULL, env->is_dead_);
- if (!new_env->is_dead_) {
- new_env->block_ = schedule()->NewBasicBlock();
- }
- new_env->variables_.reserve(env->variables_.size());
- for (NodeVectorIter i = env->variables_.begin(); i != env->variables_.end();
- ++i) {
- Node* phi = NULL;
- if (*i != NULL) {
- phi = graph()->NewNode(common()->Phi(1), *i);
- if (new_env->block_ != NULL) {
- schedule()->AddNode(new_env->block_, phi);
- }
- }
- new_env->variables_.push_back(phi);
- }
- return new_env;
-}
-
-
-void StructuredMachineAssembler::MergeBackEdgesToLoopHeader(
- Environment* header, EnvironmentVector* environments) {
- // Only merge as many variables are were declared before this loop.
- int n = static_cast<int>(header->variables_.size());
- // TODO(dcarney): invert loop order and extend phis once.
- for (EnvironmentVector::iterator i = environments->begin();
- i != environments->end(); ++i) {
- Environment* from = *i;
- if (from->is_dead_) continue;
- AddGoto(from, header);
- for (int i = 0; i < n; ++i) {
- Node* phi = header->variables_[i];
- if (phi == NULL) continue;
- phi->set_op(common()->Phi(phi->InputCount() + 1));
- phi->AppendInput(zone(), VariableAt(from, i));
- }
- }
-}
-
-
-void StructuredMachineAssembler::Merge(EnvironmentVector* environments,
- int truncate_at) {
- DCHECK(current_environment_ == NULL || current_environment_->is_dead_);
- Environment* next = new (zone()) Environment(zone(), NULL, false);
- current_environment_ = next;
- size_t n_vars = number_of_variables_;
- NodeVector& vars = next->variables_;
- vars.reserve(n_vars);
- Node** scratch = NULL;
- size_t n_envs = environments->size();
- Environment** live_environments =
- zone()->NewArray<Environment*>(static_cast<int>(n_envs));
- size_t n_live = 0;
- for (size_t i = 0; i < n_envs; i++) {
- if (environments->at(i)->is_dead_) continue;
- live_environments[n_live++] = environments->at(i);
- }
- n_envs = n_live;
- if (n_live == 0) next->is_dead_ = true;
- if (!next->is_dead_) {
- next->block_ = schedule()->NewBasicBlock();
- }
- for (size_t j = 0; j < n_vars; ++j) {
- Node* resolved = NULL;
- // Find first non equal variable.
- size_t i = 0;
- for (; i < n_envs; i++) {
- DCHECK(live_environments[i]->variables_.size() <= n_vars);
- Node* val = NULL;
- if (j < static_cast<size_t>(truncate_at)) {
- val = live_environments[i]->variables_.at(j);
- // TODO(dcarney): record start position at time of split.
- // all variables after this should not be NULL.
- if (val != NULL) {
- val = VariableAt(live_environments[i], static_cast<int>(j));
- }
- }
- if (val == resolved) continue;
- if (i != 0) break;
- resolved = val;
- }
- // Have to generate a phi.
- if (i < n_envs) {
- // All values thus far uninitialized, variable used out of scope.
- CHECK(resolved != NULL);
- // Init scratch buffer.
- if (scratch == NULL) {
- scratch = zone()->NewArray<Node*>(static_cast<int>(n_envs));
- }
- for (size_t k = 0; k < i; k++) {
- scratch[k] = resolved;
- }
- for (; i < n_envs; i++) {
- scratch[i] = live_environments[i]->variables_[j];
- }
- resolved = graph()->NewNode(common()->Phi(static_cast<int>(n_envs)),
- static_cast<int>(n_envs), scratch);
- if (next->block_ != NULL) {
- schedule()->AddNode(next->block_, resolved);
- }
- }
- vars.push_back(resolved);
- }
-}
-
-
-void StructuredMachineAssembler::AddGoto(Environment* from, Environment* to) {
- if (to->is_dead_) {
- DCHECK(from->is_dead_);
- return;
- }
- DCHECK(!from->is_dead_);
- schedule()->AddGoto(from->block_, to->block_);
-}
-
-
-// TODO(dcarney): add pass before rpo to schedule to compute these.
-BasicBlock* StructuredMachineAssembler::TrampolineFor(BasicBlock* block) {
- BasicBlock* trampoline = schedule()->NewBasicBlock();
- schedule()->AddGoto(trampoline, block);
- return trampoline;
-}
-
-
-void StructuredMachineAssembler::AddBranch(Environment* environment,
- Node* condition,
- Environment* true_val,
- Environment* false_val) {
- DCHECK(environment->is_dead_ == true_val->is_dead_);
- DCHECK(environment->is_dead_ == false_val->is_dead_);
- if (true_val->block_ == false_val->block_) {
- if (environment->is_dead_) return;
- AddGoto(environment, true_val);
- return;
- }
- Node* branch = graph()->NewNode(common()->Branch(), condition);
- if (environment->is_dead_) return;
- BasicBlock* true_block = TrampolineFor(true_val->block_);
- BasicBlock* false_block = TrampolineFor(false_val->block_);
- schedule()->AddBranch(environment->block_, branch, true_block, false_block);
-}
-
-
-StructuredMachineAssembler::Environment::Environment(Zone* zone,
- BasicBlock* block,
- bool is_dead)
- : block_(block), variables_(zone), is_dead_(is_dead) {}
-
-
-StructuredMachineAssembler::IfBuilder::IfBuilder(
- StructuredMachineAssembler* smasm)
- : smasm_(smasm),
- if_clauses_(smasm_->zone()),
- pending_exit_merges_(smasm_->zone()) {
- DCHECK(smasm_->current_environment_ != NULL);
- PushNewIfClause();
- DCHECK(!IsDone());
-}
-
-
-StructuredMachineAssembler::IfBuilder&
-StructuredMachineAssembler::IfBuilder::If() {
- DCHECK(smasm_->current_environment_ != NULL);
- IfClause* clause = CurrentClause();
- if (clause->then_environment_ != NULL || clause->else_environment_ != NULL) {
- PushNewIfClause();
- }
- return *this;
-}
-
-
-StructuredMachineAssembler::IfBuilder&
-StructuredMachineAssembler::IfBuilder::If(Node* condition) {
- If();
- IfClause* clause = CurrentClause();
- // Store branch for future resolution.
- UnresolvedBranch* next = new (smasm_->zone())
- UnresolvedBranch(smasm_->current_environment_, condition, NULL);
- if (clause->unresolved_list_tail_ != NULL) {
- clause->unresolved_list_tail_->next_ = next;
- }
- clause->unresolved_list_tail_ = next;
- // Push onto merge queues.
- clause->pending_else_merges_.push_back(next);
- clause->pending_then_merges_.push_back(next);
- smasm_->current_environment_ = NULL;
- return *this;
-}
-
-
-void StructuredMachineAssembler::IfBuilder::And() {
- CurrentClause()->ResolvePendingMerges(smasm_, kCombineThen, kExpressionTerm);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::Or() {
- CurrentClause()->ResolvePendingMerges(smasm_, kCombineElse, kExpressionTerm);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::Then() {
- CurrentClause()->ResolvePendingMerges(smasm_, kCombineThen, kExpressionDone);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::Else() {
- AddCurrentToPending();
- CurrentClause()->ResolvePendingMerges(smasm_, kCombineElse, kExpressionDone);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::AddCurrentToPending() {
- if (smasm_->current_environment_ != NULL &&
- !smasm_->current_environment_->is_dead_) {
- pending_exit_merges_.push_back(smasm_->current_environment_);
- }
- smasm_->current_environment_ = NULL;
-}
-
-
-void StructuredMachineAssembler::IfBuilder::PushNewIfClause() {
- int curr_size =
- static_cast<int>(smasm_->current_environment_->variables_.size());
- IfClause* clause = new (smasm_->zone()) IfClause(smasm_->zone(), curr_size);
- if_clauses_.push_back(clause);
-}
-
-
-StructuredMachineAssembler::IfBuilder::IfClause::IfClause(
- Zone* zone, int initial_environment_size)
- : unresolved_list_tail_(NULL),
- initial_environment_size_(initial_environment_size),
- expression_states_(zone),
- pending_then_merges_(zone),
- pending_else_merges_(zone),
- then_environment_(NULL),
- else_environment_(NULL) {
- PushNewExpressionState();
-}
-
-
-StructuredMachineAssembler::IfBuilder::PendingMergeStackRange
-StructuredMachineAssembler::IfBuilder::IfClause::ComputeRelevantMerges(
- CombineType combine_type) {
- DCHECK(!expression_states_.empty());
- PendingMergeStack* stack;
- int start;
- if (combine_type == kCombineThen) {
- stack = &pending_then_merges_;
- start = expression_states_.back().pending_then_size_;
- } else {
- DCHECK(combine_type == kCombineElse);
- stack = &pending_else_merges_;
- start = expression_states_.back().pending_else_size_;
- }
- PendingMergeStackRange data;
- data.merge_stack_ = stack;
- data.start_ = start;
- data.size_ = static_cast<int>(stack->size()) - start;
- return data;
-}
-
-
-void StructuredMachineAssembler::IfBuilder::IfClause::ResolvePendingMerges(
- StructuredMachineAssembler* smasm, CombineType combine_type,
- ResolutionType resolution_type) {
- DCHECK(smasm->current_environment_ == NULL);
- PendingMergeStackRange data = ComputeRelevantMerges(combine_type);
- DCHECK_EQ(data.merge_stack_->back(), unresolved_list_tail_);
- DCHECK(data.size_ > 0);
- // TODO(dcarney): assert no new variables created during expression building.
- int truncate_at = initial_environment_size_;
- if (data.size_ == 1) {
- // Just copy environment in common case.
- smasm->current_environment_ =
- smasm->Copy(unresolved_list_tail_->environment_, truncate_at);
- } else {
- EnvironmentVector environments(smasm->zone());
- environments.reserve(data.size_);
- CopyEnvironments(data, &environments);
- DCHECK(static_cast<int>(environments.size()) == data.size_);
- smasm->Merge(&environments, truncate_at);
- }
- Environment* then_environment = then_environment_;
- Environment* else_environment = NULL;
- if (resolution_type == kExpressionDone) {
- DCHECK(expression_states_.size() == 1);
- // Set the current then_ or else_environment_ to the new merged environment.
- if (combine_type == kCombineThen) {
- DCHECK(then_environment_ == NULL && else_environment_ == NULL);
- this->then_environment_ = smasm->current_environment_;
- } else {
- DCHECK(else_environment_ == NULL);
- this->else_environment_ = smasm->current_environment_;
- }
- } else {
- DCHECK(resolution_type == kExpressionTerm);
- DCHECK(then_environment_ == NULL && else_environment_ == NULL);
- }
- if (combine_type == kCombineThen) {
- then_environment = smasm->current_environment_;
- } else {
- DCHECK(combine_type == kCombineElse);
- else_environment = smasm->current_environment_;
- }
- // Finalize branches and clear the pending stack.
- FinalizeBranches(smasm, data, combine_type, then_environment,
- else_environment);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::IfClause::CopyEnvironments(
- const PendingMergeStackRange& data, EnvironmentVector* environments) {
- PendingMergeStack::iterator i = data.merge_stack_->begin();
- PendingMergeStack::iterator end = data.merge_stack_->end();
- for (i += data.start_; i != end; ++i) {
- environments->push_back((*i)->environment_);
- }
-}
-
-
-void StructuredMachineAssembler::IfBuilder::IfClause::PushNewExpressionState() {
- ExpressionState next;
- next.pending_then_size_ = static_cast<int>(pending_then_merges_.size());
- next.pending_else_size_ = static_cast<int>(pending_else_merges_.size());
- expression_states_.push_back(next);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::IfClause::PopExpressionState() {
- expression_states_.pop_back();
- DCHECK(!expression_states_.empty());
-}
-
-
-void StructuredMachineAssembler::IfBuilder::IfClause::FinalizeBranches(
- StructuredMachineAssembler* smasm, const PendingMergeStackRange& data,
- CombineType combine_type, Environment* const then_environment,
- Environment* const else_environment) {
- DCHECK(unresolved_list_tail_ != NULL);
- DCHECK(smasm->current_environment_ != NULL);
- if (data.size_ == 0) return;
- PendingMergeStack::iterator curr = data.merge_stack_->begin();
- PendingMergeStack::iterator end = data.merge_stack_->end();
- // Finalize everything but the head first,
- // in the order the branches enter the merge block.
- end -= 1;
- Environment* true_val = then_environment;
- Environment* false_val = else_environment;
- Environment** next;
- if (combine_type == kCombineThen) {
- next = &false_val;
- } else {
- DCHECK(combine_type == kCombineElse);
- next = &true_val;
- }
- for (curr += data.start_; curr != end; ++curr) {
- UnresolvedBranch* branch = *curr;
- *next = branch->next_->environment_;
- smasm->AddBranch(branch->environment_, branch->condition_, true_val,
- false_val);
- }
- DCHECK(curr + 1 == data.merge_stack_->end());
- // Now finalize the tail if possible.
- if (then_environment != NULL && else_environment != NULL) {
- UnresolvedBranch* branch = *curr;
- smasm->AddBranch(branch->environment_, branch->condition_, then_environment,
- else_environment);
- }
- // Clear the merge stack.
- PendingMergeStack::iterator begin = data.merge_stack_->begin();
- begin += data.start_;
- data.merge_stack_->erase(begin, data.merge_stack_->end());
- DCHECK_EQ(static_cast<int>(data.merge_stack_->size()), data.start_);
-}
-
-
-void StructuredMachineAssembler::IfBuilder::End() {
- DCHECK(!IsDone());
- AddCurrentToPending();
- size_t current_pending = pending_exit_merges_.size();
- // All unresolved branch edges are now set to pending.
- for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end();
- ++i) {
- IfClause* clause = *i;
- DCHECK(clause->expression_states_.size() == 1);
- PendingMergeStackRange data;
- // Copy then environments.
- data = clause->ComputeRelevantMerges(kCombineThen);
- clause->CopyEnvironments(data, &pending_exit_merges_);
- Environment* head = NULL;
- // Will resolve the head node in the else_merge
- if (data.size_ > 0 && clause->then_environment_ == NULL &&
- clause->else_environment_ == NULL) {
- head = pending_exit_merges_.back();
- pending_exit_merges_.pop_back();
- }
- // Copy else environments.
- data = clause->ComputeRelevantMerges(kCombineElse);
- clause->CopyEnvironments(data, &pending_exit_merges_);
- if (head != NULL) {
- // Must have data to merge, or else head will never get a branch.
- DCHECK(data.size_ != 0);
- pending_exit_merges_.push_back(head);
- }
- }
- smasm_->Merge(&pending_exit_merges_,
- if_clauses_[0]->initial_environment_size_);
- // Anything initally pending jumps into the new environment.
- for (size_t i = 0; i < current_pending; ++i) {
- smasm_->AddGoto(pending_exit_merges_[i], smasm_->current_environment_);
- }
- // Resolve all branches.
- for (IfClauses::iterator i = if_clauses_.begin(); i != if_clauses_.end();
- ++i) {
- IfClause* clause = *i;
- // Must finalize all environments, so ensure they are set correctly.
- Environment* then_environment = clause->then_environment_;
- if (then_environment == NULL) {
- then_environment = smasm_->current_environment_;
- }
- Environment* else_environment = clause->else_environment_;
- PendingMergeStackRange data;
- // Finalize then environments.
- data = clause->ComputeRelevantMerges(kCombineThen);
- clause->FinalizeBranches(smasm_, data, kCombineThen, then_environment,
- else_environment);
- // Finalize else environments.
- // Now set the else environment so head is finalized for edge case above.
- if (else_environment == NULL) {
- else_environment = smasm_->current_environment_;
- }
- data = clause->ComputeRelevantMerges(kCombineElse);
- clause->FinalizeBranches(smasm_, data, kCombineElse, then_environment,
- else_environment);
- }
- // Future accesses to this builder should crash immediately.
- pending_exit_merges_.clear();
- if_clauses_.clear();
- DCHECK(IsDone());
-}
-
-
-StructuredMachineAssembler::LoopBuilder::LoopBuilder(
- StructuredMachineAssembler* smasm)
- : smasm_(smasm),
- header_environment_(NULL),
- pending_header_merges_(smasm_->zone()),
- pending_exit_merges_(smasm_->zone()) {
- DCHECK(smasm_->current_environment_ != NULL);
- // Create header environment.
- header_environment_ = smasm_->CopyForLoopHeader(smasm_->current_environment_);
- smasm_->AddGoto(smasm_->current_environment_, header_environment_);
- // Create body environment.
- Environment* body = smasm_->Copy(header_environment_);
- smasm_->AddGoto(header_environment_, body);
- smasm_->current_environment_ = body;
- DCHECK(!IsDone());
-}
-
-
-void StructuredMachineAssembler::LoopBuilder::Continue() {
- DCHECK(!IsDone());
- pending_header_merges_.push_back(smasm_->current_environment_);
- smasm_->CopyCurrentAsDead();
-}
-
-
-void StructuredMachineAssembler::LoopBuilder::Break() {
- DCHECK(!IsDone());
- pending_exit_merges_.push_back(smasm_->current_environment_);
- smasm_->CopyCurrentAsDead();
-}
-
-
-void StructuredMachineAssembler::LoopBuilder::End() {
- DCHECK(!IsDone());
- if (smasm_->current_environment_ != NULL) {
- Continue();
- }
- // Do loop header merges.
- smasm_->MergeBackEdgesToLoopHeader(header_environment_,
- &pending_header_merges_);
- int initial_size = static_cast<int>(header_environment_->variables_.size());
- // Do loop exit merges, truncating loop variables away.
- smasm_->Merge(&pending_exit_merges_, initial_size);
- for (EnvironmentVector::iterator i = pending_exit_merges_.begin();
- i != pending_exit_merges_.end(); ++i) {
- smasm_->AddGoto(*i, smasm_->current_environment_);
- }
- pending_header_merges_.clear();
- pending_exit_merges_.clear();
- header_environment_ = NULL;
- DCHECK(IsDone());
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
« no previous file with comments | « test/cctest/compiler/structured-machine-assembler.h ('k') | test/cctest/compiler/test-structured-ifbuilder-fuzzer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698