b565b15849
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
119 lines
3.0 KiB
C++
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
|