Files
sdk/runtime/vm/intermediate_language.cc
T
kmillikin@google.com b565b15849 Expand the instruction visitor to visit computations and values.
For compilation passes we will want a visitor that can reach computations
and values, rather than virtual functions in the computation/value classes.
Implement the visitor signature and double dispatching.  Use it to remove
the virtual Print functions.

R=srdjan@google.com
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com//9471010

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@4664 260f80e4-7a28-3924-810f-c04153c831b5
2012-02-28 08:58:49 +00:00

119 lines
3.0 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/intermediate_language.h"
#include "vm/object.h"
#include "vm/os.h"
#include "vm/scopes.h"
namespace dart {
// ==== Support for visiting flow graphs.
#define DEFINE_ACCEPT(ShortName, ClassName) \
void ClassName::Accept(FlowGraphVisitor* visitor) { \
visitor->Visit##ShortName(this); \
}
FOR_EACH_COMPUTATION(DEFINE_ACCEPT)
#undef DEFINE_ACCEPT
Instruction* JoinEntryInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitJoinEntry(this);
return successor_;
}
Instruction* TargetEntryInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitTargetEntry(this);
return successor_;
}
Instruction* DoInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitDo(this);
return successor_;
}
Instruction* BindInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitBind(this);
return successor_;
}
Instruction* ReturnInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitReturn(this);
return NULL;
}
Instruction* BranchInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitBranch(this);
return NULL;
}
// Default implementation of visiting basic blocks. Can be overridden.
void FlowGraphVisitor::VisitBlocks(
const GrowableArray<BlockEntryInstr*>& block_order) {
for (intptr_t i = block_order.length() - 1; i >= 0; --i) {
Instruction* current = block_order[i]->Accept(this);
while ((current != NULL) && !current->IsBlockEntry()) {
current = current->Accept(this);
}
}
}
// ==== Postorder graph traversal.
void DoInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
}
void BindInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
}
void ReturnInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
}
void BranchInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
// Visit the false successor before the true successor so they appear in
// true/false order in reverse postorder.
if (false_successor_->mark() != mark()) {
false_successor_->Postorder(block_entries);
}
if (true_successor_->mark() != mark()) {
true_successor_->Postorder(block_entries);
}
}
void JoinEntryInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
block_entries->Add(this);
}
void TargetEntryInstr::Postorder(
GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
block_entries->Add(this);
}
} // namespace dart