Chromium Code Reviews| 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 |