Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/growable_array.h" | 9 #include "vm/growable_array.h" |
| 10 #include "vm/handles_impl.h" | 10 #include "vm/handles_impl.h" |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 | 149 |
| 150 | 150 |
| 151 // Instructions. | 151 // Instructions. |
| 152 // | 152 // |
| 153 // <Instruction> ::= Do <Computation> <Instruction> | 153 // <Instruction> ::= Do <Computation> <Instruction> |
| 154 // | Bind <int> <Computation> <Instruction> | 154 // | Bind <int> <Computation> <Instruction> |
| 155 // | Return <Value> | 155 // | Return <Value> |
| 156 // | Branch <Value> <Instruction> <Instruction> | 156 // | Branch <Value> <Instruction> <Instruction> |
| 157 // | Empty <Instruction> | 157 // | Empty <Instruction> |
| 158 | 158 |
| 159 // M is a single argument macro. It is applied to each concrete instruction | |
| 160 // type name. The concrete instruction classes are the name with Instr | |
| 161 // concatenated. | |
| 162 #define FOR_EACH_INSTRUCTION(M) \ | |
| 163 M(JoinEntry) \ | |
| 164 M(TargetEntry) \ | |
| 165 M(Do) \ | |
| 166 M(Bind) \ | |
| 167 M(Return) \ | |
| 168 M(Branch) | |
| 169 | |
| 170 | |
| 171 // Forward declarations. | |
| 172 class BlockEntryInstr; | |
| 173 #define FORWARD_DECLARATION(type) class type##Instr; | |
| 174 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | |
| 175 #undef FORWARD_DECLARATION | |
| 176 | |
| 177 | |
| 178 // Functions required in all concrete instruction classes. | |
| 179 #define DECLARE_INSTRUCTION(type) \ | |
| 180 virtual Tag tag() const { return k##type; } \ | |
| 181 static type##Instr* cast(Instruction* instr) { \ | |
| 182 ASSERT(instr->Is##type()); \ | |
| 183 return reinterpret_cast<type##Instr*>(instr); \ | |
| 184 } | |
| 185 | |
| 186 | |
| 159 class Instruction : public ZoneAllocated { | 187 class Instruction : public ZoneAllocated { |
| 160 public: | 188 public: |
| 189 // Declare a tag for each concrete instruction type. | |
| 190 #define DECLARE_TAG(type) k##type, | |
| 191 enum Tag { | |
| 192 FOR_EACH_INSTRUCTION(DECLARE_TAG) | |
| 193 kInstructionCount // To follow the trailing comma from the macro. | |
| 194 }; | |
| 195 #undef DECLARE_TAG | |
| 196 | |
| 161 Instruction() : mark_(false) { } | 197 Instruction() : mark_(false) { } |
| 162 | 198 |
| 199 // Pure virtual tag accessor. | |
| 200 virtual Tag tag() const = 0; | |
| 201 | |
| 202 // Non-virtual type testing functions. | |
| 203 #define DEFINE_TYPE_FUNCTIONS(type) \ | |
| 204 bool Is##type() const { return tag() == k##type; } | |
| 205 FOR_EACH_INSTRUCTION(DEFINE_TYPE_FUNCTIONS) | |
| 206 #undef DEFINE_TYPE_FUNCTIONS | |
|
srdjan
2012/02/23 16:50:26
I think the IsXXX and AsXXX are better. Typical us
| |
| 207 | |
| 208 // Type testing and conversions for other classes of instructions. | |
| 209 bool IsBlockEntry() const { return IsJoinEntry() || IsTargetEntry(); } | |
| 210 | |
| 163 virtual void SetSuccessor(Instruction* instr) = 0; | 211 virtual void SetSuccessor(Instruction* instr) = 0; |
| 164 virtual bool IsBlockEntry() const { return false; } | |
| 165 virtual void SetBlockNumber(intptr_t number) { UNREACHABLE(); } | |
| 166 virtual intptr_t GetBlockNumber() const { | |
| 167 UNREACHABLE(); | |
| 168 return -1; | |
| 169 } | |
| 170 | 212 |
| 171 // Perform a postorder traversal of the instruction graph reachable from | 213 // Perform a postorder traversal of the instruction graph reachable from |
| 172 // this instruction. Accumulate basic block entries in the order visited | 214 // this instruction. Accumulate basic block entries in the order visited |
| 173 // in the in/out parameter 'block_entries'. | 215 // in the in/out parameter 'block_entries'. |
| 174 virtual void Postorder(GrowableArray<Instruction*>* block_entries) = 0; | 216 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; |
| 175 | 217 |
| 176 // Print an instruction without a four space indent, and no trailing | 218 // Print an instruction without a four space indent, and no trailing |
| 177 // newline. Basic block entries are labeled with their block number. | 219 // newline. Basic block entries are labeled with their block number. |
| 178 // Return the instruction's successor if there is a single successor | 220 // Return the instruction's successor if there is a single successor |
| 179 // otherwise NULL. | 221 // otherwise NULL. |
| 180 virtual Instruction* Print() const = 0; | 222 virtual Instruction* Print() const = 0; |
| 181 | 223 |
| 182 // Mark bit to support non-reentrant recursive traversal (i.e., | 224 // Mark bit to support non-reentrant recursive traversal (i.e., |
| 183 // identification of cycles). Before and after a traversal, all the nodes | 225 // identification of cycles). Before and after a traversal, all the nodes |
| 184 // must have the same mark. | 226 // must have the same mark. |
| 185 bool mark() const { return mark_; } | 227 bool mark() const { return mark_; } |
| 186 void flip_mark() { mark_ = !mark_; } | 228 void flip_mark() { mark_ = !mark_; } |
| 187 | 229 |
| 188 private: | 230 private: |
| 189 bool mark_; | 231 bool mark_; |
| 190 }; | 232 }; |
| 191 | 233 |
| 192 | 234 |
| 235 // Basic block entries are administrative nodes. Joins are the only nodes | |
| 236 // with multiple predecessors. Targets are the other basic block entries. | |
| 237 // The types enforce edge-split form---joins are forbidden as the successors | |
| 238 // of branches. | |
| 239 class BlockEntryInstr : public Instruction { | |
| 240 public: | |
| 241 BlockEntryInstr() : Instruction(), block_number_(-1) { } | |
| 242 | |
| 243 static BlockEntryInstr* cast(Instruction* instr) { | |
| 244 ASSERT(instr->IsBlockEntry()); | |
| 245 return reinterpret_cast<BlockEntryInstr*>(instr); | |
| 246 } | |
| 247 | |
| 248 intptr_t block_number() const { return block_number_; } | |
| 249 void set_block_number(intptr_t number) { block_number_ = number; } | |
| 250 | |
| 251 private: | |
| 252 intptr_t block_number_; | |
|
srdjan
2012/02/23 16:50:26
Optional: DISALLOW_yada_yada (here and below), but
| |
| 253 }; | |
| 254 | |
| 255 | |
| 256 class JoinEntryInstr : public BlockEntryInstr { | |
| 257 public: | |
| 258 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { } | |
| 259 | |
| 260 DECLARE_INSTRUCTION(JoinEntry) | |
| 261 | |
| 262 virtual void SetSuccessor(Instruction* instr) { | |
| 263 ASSERT(successor_ == NULL); | |
| 264 successor_ = instr; | |
| 265 } | |
| 266 | |
| 267 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | |
| 268 | |
| 269 virtual Instruction* Print() const; | |
| 270 | |
| 271 private: | |
| 272 Instruction* successor_; | |
| 273 }; | |
| 274 | |
| 275 | |
| 276 class TargetEntryInstr : public BlockEntryInstr { | |
| 277 public: | |
| 278 TargetEntryInstr() : BlockEntryInstr(), block_number_(-1), successor_(NULL) { | |
| 279 } | |
| 280 | |
| 281 DECLARE_INSTRUCTION(TargetEntry) | |
| 282 | |
| 283 virtual void SetSuccessor(Instruction* instr) { | |
| 284 ASSERT(successor_ == NULL); | |
| 285 successor_ = instr; | |
| 286 } | |
| 287 | |
| 288 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | |
| 289 | |
| 290 virtual Instruction* Print() const; | |
| 291 | |
| 292 private: | |
| 293 intptr_t block_number_; | |
|
srdjan
2012/02/23 16:50:26
Superclass has already field block_number_, remove
| |
| 294 Instruction* successor_; | |
| 295 }; | |
| 296 | |
| 297 | |
| 193 class DoInstr : public Instruction { | 298 class DoInstr : public Instruction { |
| 194 public: | 299 public: |
| 195 explicit DoInstr(Computation* comp) | 300 explicit DoInstr(Computation* comp) |
| 196 : Instruction(), computation_(comp), successor_(NULL) { } | 301 : Instruction(), computation_(comp), successor_(NULL) { } |
| 197 | 302 |
| 303 DECLARE_INSTRUCTION(Do) | |
| 304 | |
| 198 virtual void SetSuccessor(Instruction* instr) { | 305 virtual void SetSuccessor(Instruction* instr) { |
| 199 ASSERT(successor_ == NULL); | 306 ASSERT(successor_ == NULL); |
| 200 successor_ = instr; | 307 successor_ = instr; |
| 201 } | 308 } |
| 202 | 309 |
| 203 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | 310 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); |
| 204 | 311 |
| 205 virtual Instruction* Print() const; | 312 virtual Instruction* Print() const; |
| 206 | 313 |
| 207 private: | 314 private: |
| 208 Computation* computation_; | 315 Computation* computation_; |
| 209 Instruction* successor_; | 316 Instruction* successor_; |
| 210 }; | 317 }; |
| 211 | 318 |
| 212 | 319 |
| 213 class BindInstr : public Instruction { | 320 class BindInstr : public Instruction { |
| 214 public: | 321 public: |
| 215 BindInstr(intptr_t temp_index, Computation* computation) | 322 BindInstr(intptr_t temp_index, Computation* computation) |
| 216 : Instruction(), | 323 : Instruction(), |
| 217 temp_index_(temp_index), | 324 temp_index_(temp_index), |
| 218 computation_(computation), | 325 computation_(computation), |
| 219 successor_(NULL) { } | 326 successor_(NULL) { } |
| 220 | 327 |
| 328 DECLARE_INSTRUCTION(Bind) | |
| 329 | |
| 221 virtual void SetSuccessor(Instruction* instr) { | 330 virtual void SetSuccessor(Instruction* instr) { |
| 222 ASSERT(successor_ == NULL); | 331 ASSERT(successor_ == NULL); |
| 223 successor_ = instr; | 332 successor_ = instr; |
| 224 } | 333 } |
| 225 | 334 |
| 226 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | 335 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); |
| 227 | 336 |
| 228 virtual Instruction* Print() const; | 337 virtual Instruction* Print() const; |
| 229 | 338 |
| 230 private: | 339 private: |
| 231 const intptr_t temp_index_; | 340 const intptr_t temp_index_; |
| 232 Computation* computation_; | 341 Computation* computation_; |
| 233 Instruction* successor_; | 342 Instruction* successor_; |
| 234 }; | 343 }; |
| 235 | 344 |
| 236 | |
| 237 class JoinEntryInstr : public Instruction { | |
| 238 public: | |
| 239 JoinEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { } | |
| 240 | |
| 241 virtual void SetSuccessor(Instruction* instr) { | |
| 242 ASSERT(successor_ == NULL); | |
| 243 successor_ = instr; | |
| 244 } | |
| 245 | |
| 246 virtual bool IsBlockEntry() const { return true; } | |
| 247 virtual void SetBlockNumber(intptr_t number) { block_number_ = number; } | |
| 248 virtual intptr_t GetBlockNumber() const { return block_number_; } | |
| 249 | |
| 250 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | |
| 251 | |
| 252 virtual Instruction* Print() const; | |
| 253 | |
| 254 private: | |
| 255 intptr_t block_number_; | |
| 256 Instruction* successor_; | |
| 257 }; | |
| 258 | |
| 259 | |
| 260 class TargetEntryInstr : public Instruction { | |
| 261 public: | |
| 262 TargetEntryInstr() : Instruction(), block_number_(-1), successor_(NULL) { } | |
| 263 | |
| 264 virtual void SetSuccessor(Instruction* instr) { | |
| 265 ASSERT(successor_ == NULL); | |
| 266 successor_ = instr; | |
| 267 } | |
| 268 | |
| 269 virtual bool IsBlockEntry() const { return true; } | |
| 270 virtual void SetBlockNumber(intptr_t number) { block_number_ = number; } | |
| 271 virtual intptr_t GetBlockNumber() const { return block_number_; } | |
| 272 | |
| 273 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | |
| 274 | |
| 275 virtual Instruction* Print() const; | |
| 276 | |
| 277 private: | |
| 278 intptr_t block_number_; | |
| 279 Instruction* successor_; | |
| 280 }; | |
| 281 | |
| 282 | 345 |
| 283 class ReturnInstr : public Instruction { | 346 class ReturnInstr : public Instruction { |
| 284 public: | 347 public: |
| 285 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { } | 348 explicit ReturnInstr(Value* value) : Instruction(), value_(value) { } |
| 286 | 349 |
| 350 DECLARE_INSTRUCTION(Return) | |
| 351 | |
| 287 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 352 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 288 | 353 |
| 289 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | 354 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); |
| 290 | 355 |
| 291 virtual Instruction* Print() const; | 356 virtual Instruction* Print() const; |
| 292 | 357 |
| 293 private: | 358 private: |
| 294 Value* value_; | 359 Value* value_; |
| 295 }; | 360 }; |
| 296 | 361 |
| 297 | 362 |
| 298 class BranchInstr : public Instruction { | 363 class BranchInstr : public Instruction { |
| 299 public: | 364 public: |
| 300 explicit BranchInstr(Value* value) | 365 explicit BranchInstr(Value* value) |
| 301 : Instruction(), | 366 : Instruction(), |
| 302 value_(value), | 367 value_(value), |
| 303 true_successor_(NULL), | 368 true_successor_(NULL), |
| 304 false_successor_(NULL) { } | 369 false_successor_(NULL) { } |
| 305 | 370 |
| 371 DECLARE_INSTRUCTION(Branch) | |
| 372 | |
| 306 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 373 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 307 | 374 |
| 308 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 375 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
| 309 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 376 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
| 310 | 377 |
| 311 virtual void Postorder(GrowableArray<Instruction*>* block_entries); | 378 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); |
| 312 | 379 |
| 313 virtual Instruction* Print() const; | 380 virtual Instruction* Print() const; |
| 314 | 381 |
| 315 private: | 382 private: |
| 316 Value* value_; | 383 Value* value_; |
| 317 TargetEntryInstr* true_successor_; | 384 TargetEntryInstr* true_successor_; |
| 318 TargetEntryInstr* false_successor_; | 385 TargetEntryInstr* false_successor_; |
| 319 }; | 386 }; |
| 320 | 387 |
| 388 #undef DECLARE_INSTRUCTION | |
| 389 | |
| 321 | 390 |
| 322 } // namespace dart | 391 } // namespace dart |
| 323 | 392 |
| 324 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 393 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |