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

Unified Diff: runtime/vm/intermediate_language.h

Issue 9454012: Add type testing and casting support. (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..47a48daada9c5f626ced1aca552eba783833d392 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -156,22 +156,64 @@ 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.
+class BlockEntryInstr;
+#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); \
+ }
+
+
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) { }
+ // 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
srdjan 2012/02/23 16:50:26 I think the IsXXX and AsXXX are better. Typical us
+
+ // Type testing and conversions for other classes of instructions.
+ bool IsBlockEntry() const { return IsJoinEntry() || IsTargetEntry(); }
+
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;
- }
// 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;
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0;
// Print an instruction without a four space indent, and no trailing
// newline. Basic block entries are labeled with their block number.
@@ -190,92 +232,113 @@ 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_;
srdjan 2012/02/23 16:50:26 Optional: DISALLOW_yada_yada (here and below), but
+};
+
+
+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 void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
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 void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
private:
- const intptr_t temp_index_;
- Computation* computation_;
+ intptr_t block_number_;
srdjan 2012/02/23 16:50:26 Superclass has already field block_number_, remove
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)
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 void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
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)
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 void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
private:
- intptr_t block_number_;
+ const intptr_t temp_index_;
+ Computation* computation_;
Instruction* successor_;
};
@@ -284,9 +347,11 @@ class ReturnInstr : public Instruction {
public:
explicit ReturnInstr(Value* value) : Instruction(), value_(value) { }
+ DECLARE_INSTRUCTION(Return)
+
virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
@@ -303,12 +368,14 @@ class BranchInstr : public Instruction {
true_successor_(NULL),
false_successor_(NULL) { }
+ DECLARE_INSTRUCTION(Branch)
+
virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); }
TargetEntryInstr** true_successor_address() { return &true_successor_; }
TargetEntryInstr** false_successor_address() { return &false_successor_; }
- virtual void Postorder(GrowableArray<Instruction*>* block_entries);
+ virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries);
virtual Instruction* Print() const;
@@ -318,6 +385,8 @@ class BranchInstr : public Instruction {
TargetEntryInstr* false_successor_;
};
+#undef DECLARE_INSTRUCTION
+
} // 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