Files
sdk/runtime/vm/intermediate_language.cc
T
kmillikin@google.com 01695137f8 Turn CopyTemp and SetTemp into instructions.
These were always used and assumed to be in a stylized form (CopyTemp in
Bind and SetTemp in Do).  Make this required by the IL.  This change allows
eliminating the relative indexing in favor of temporary names, without
restructuring the compiler at all.

R=srdjan@google.com
BUG=
TEST=

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@5072 260f80e4-7a28-3924-810f-c04153c831b5
2012-03-07 10:24:01 +00:00

143 lines
3.6 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* PickTempInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitPickTemp(this);
return successor_;
}
Instruction* TuckTempInstr::Accept(FlowGraphVisitor* visitor) {
visitor->VisitTuckTemp(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 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);
}
void PickTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
}
void TuckTempInstr::Postorder(GrowableArray<BlockEntryInstr*>* block_entries) {
flip_mark();
if (successor_->mark() != mark()) successor_->Postorder(block_entries);
}
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);
}
}
} // namespace dart