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

Unified Diff: runtime/vm/intermediate_language.h

Issue 9453014: Implement a simple InstructionVisitor class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 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
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language.h
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index a7bc540dd7fcbc21168fcb968ba833c8e08882fe..b470ea0a696d0e283516cdb219b8eb6abd67d8a6 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -156,28 +156,68 @@ class ConstantValue: public Value {
// | Branch <Value> <Instruction> <Instruction>
// | Empty <Instruction>
+// M is a single argument macro. It is applied to each concrete instruction
+// type name. The concrete instruction classes are the name with Instr
+// concatenated.
+#define FOR_EACH_INSTRUCTION(M) \
+ M(JoinEntry) \
+ M(TargetEntry) \
+ M(Do) \
+ M(Bind) \
+ M(Return) \
+ M(Branch)
+
+
+// Forward declarations for Instruction classes.
+class BlockEntryInstr;
+class InstructionVisitor;
+#define FORWARD_DECLARATION(type) class type##Instr;
+FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
+#undef FORWARD_DECLARATION
+
+
+// Functions required in all concrete instruction classes.
+#define DECLARE_INSTRUCTION(type) \
+ virtual Tag tag() const { return k##type; } \
+ static type##Instr* cast(Instruction* instr) { \
+ ASSERT(instr->Is##type()); \
+ return reinterpret_cast<type##Instr*>(instr); \
+ } \
+ virtual Instruction* Accept(InstructionVisitor* visitor);
+
+
class Instruction : public ZoneAllocated {
public:
+ // Declare a tag for each concrete instruction type.
+#define DECLARE_TAG(type) k##type,
+ enum Tag {
+ FOR_EACH_INSTRUCTION(DECLARE_TAG)
+ kInstructionCount // To follow the trailing comma from the macro.
+ };
+#undef DECLARE_TAG
+
Instruction() : mark_(false) { }
- virtual void SetSuccessor(Instruction* instr) = 0;
- virtual bool IsBlockEntry() const { return false; }
- virtual void SetBlockNumber(intptr_t number) { UNREACHABLE(); }
- virtual intptr_t GetBlockNumber() const {
- UNREACHABLE();
- return -1;
- }
+ // Pure virtual tag accessor.
+ virtual Tag tag() const = 0;
+ // Non-virtual type testing functions.
+#define DEFINE_TYPE_FUNCTIONS(type) \
+ bool Is##type() const { return tag() == k##type; }
+ FOR_EACH_INSTRUCTION(DEFINE_TYPE_FUNCTIONS)
+#undef DEFINE_TYPE_FUNCTIONS
+
+ // Type testing and conversions for other classes of instructions.
+ bool IsBlockEntry() const { return IsJoinEntry() || IsTargetEntry(); }
+
+ // Visiting support.
+ virtual Instruction* Accept(InstructionVisitor* visitor) = 0;
+
+ virtual void SetSuccessor(Instruction* instr) = 0;
// Perform a postorder traversal of the instruction graph reachable from
// this instruction. Accumulate basic block entries in the order visited
// in the in/out parameter 'block_entries'.
- virtual void Postorder(GrowableArray<Instruction*>* block_entries) = 0;
-
- // Print an instruction without a four space indent, and no trailing
- // newline. Basic block entries are labeled with their block number.
- // Return the instruction's successor if there is a single successor
- // otherwise NULL.
- virtual Instruction* Print() const = 0;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0;
// Mark bit to support non-reentrant recursive traversal (i.e.,
// identification of cycles). Before and after a traversal, all the nodes
@@ -190,92 +230,110 @@ class Instruction : public ZoneAllocated {
};
-class DoInstr : public Instruction {
+// Basic block entries are administrative nodes. Joins are the only nodes
+// with multiple predecessors. Targets are the other basic block entries.
+// The types enforce edge-split form---joins are forbidden as the successors
+// of branches.
+class BlockEntryInstr : public Instruction {
public:
- explicit DoInstr(Computation* comp)
- : Instruction(), computation_(comp), successor_(NULL) { }
+ BlockEntryInstr() : Instruction(), block_number_(-1) { }
+
+ static BlockEntryInstr* cast(Instruction* instr) {
+ ASSERT(instr->IsBlockEntry());
+ return reinterpret_cast<BlockEntryInstr*>(instr);
+ }
+
+ intptr_t block_number() const { return block_number_; }
+ void set_block_number(intptr_t number) { block_number_ = number; }
+
+ private:
+ intptr_t block_number_;
+};
+
+
+class JoinEntryInstr : public BlockEntryInstr {
+ public:
+ JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { }
+
+ DECLARE_INSTRUCTION(JoinEntry)
virtual void SetSuccessor(Instruction* instr) {
ASSERT(successor_ == NULL);
successor_ = instr;
}
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
-
- virtual Instruction* Print() const;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
- Computation* computation_;
Instruction* successor_;
};
-class BindInstr : public Instruction {
+class TargetEntryInstr : public BlockEntryInstr {
public:
- BindInstr(intptr_t temp_index, Computation* computation)
- : Instruction(),
- temp_index_(temp_index),
- computation_(computation),
- successor_(NULL) { }
+ TargetEntryInstr() : BlockEntryInstr(), block_number_(-1), successor_(NULL) {
+ }
+
+ DECLARE_INSTRUCTION(TargetEntry)
virtual void SetSuccessor(Instruction* instr) {
ASSERT(successor_ == NULL);
successor_ = instr;
}
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
-
- virtual Instruction* Print() const;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
- const intptr_t temp_index_;
- Computation* computation_;
+ intptr_t block_number_;
Instruction* successor_;
};
-class JoinEntryInstr : public Instruction {
+class DoInstr : public Instruction {
public:
- JoinEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { }
+ explicit DoInstr(Computation* comp)
+ : Instruction(), computation_(comp), successor_(NULL) { }
+
+ DECLARE_INSTRUCTION(Do)
+
+ Computation* computation() const { return computation_; }
virtual void SetSuccessor(Instruction* instr) {
ASSERT(successor_ == NULL);
successor_ = instr;
}
- virtual bool IsBlockEntry() const { return true; }
- virtual void SetBlockNumber(intptr_t number) { block_number_ = number; }
- virtual intptr_t GetBlockNumber() const { return block_number_; }
-
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
-
- virtual Instruction* Print() const;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
- intptr_t block_number_;
+ Computation* computation_;
Instruction* successor_;
};
-class TargetEntryInstr : public Instruction {
+class BindInstr : public Instruction {
public:
- TargetEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { }
+ BindInstr(intptr_t temp_index, Computation* computation)
+ : Instruction(),
+ temp_index_(temp_index),
+ computation_(computation),
+ successor_(NULL) { }
+
+ DECLARE_INSTRUCTION(Bind)
+
+ intptr_t temp_index() const { return temp_index_; }
+ Computation* computation() const { return computation_; }
virtual void SetSuccessor(Instruction* instr) {
ASSERT(successor_ == NULL);
successor_ = instr;
}
- virtual bool IsBlockEntry() const { return true; }
- virtual void SetBlockNumber(intptr_t number) { block_number_ = number; }
- virtual intptr_t GetBlockNumber() const { return block_number_; }
-
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
-
- virtual Instruction* Print() const;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
- intptr_t block_number_;
+ const intptr_t temp_index_;
+ Computation* computation_;
Instruction* successor_;
};
@@ -284,11 +342,13 @@ class ReturnInstr : public Instruction {
public:
explicit ReturnInstr(Value* value) : Instruction(), value_(value) { }
- virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
+ DECLARE_INSTRUCTION(Return)
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
+ Value* value() const { return value_; }
- virtual Instruction* Print() const;
+ virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
+
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
Value* value_;
@@ -303,14 +363,18 @@ class BranchInstr : public Instruction {
true_successor_(NULL),
false_successor_(NULL) { }
- virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
+ DECLARE_INSTRUCTION(Branch)
+
+ Value* value() const { return value_; }
+ TargetEntryInstr* true_successor() const { return true_successor_; }
+ TargetEntryInstr* false_successor() const { return false_successor_; }
TargetEntryInstr** true_successor_address() { return &true_successor_; }
TargetEntryInstr** false_successor_address() { return &false_successor_; }
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
+ virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
- virtual Instruction* Print() const;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
private:
Value* value_;
@@ -318,6 +382,27 @@ class BranchInstr : public Instruction {
TargetEntryInstr* false_successor_;
};
+#undef DECLARE_INSTRUCTION
+
+
+class InstructionVisitor {
+ public:
+ InstructionVisitor() { }
+ virtual ~InstructionVisitor() { }
+
+ // Visit each block in the array list in reverse, and for each block its
+ // instructions in order from the block entry to exit.
+ void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order);
+
+#define DECLARE_VISIT(type) \
+ virtual void Visit##type(type##Instr* instr) { }
+ FOR_EACH_INSTRUCTION(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InstructionVisitor);
+};
+
} // namespace dart
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698