OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 M(Float64x2OneArg) \ | 493 M(Float64x2OneArg) \ |
494 M(ExtractNthOutput) \ | 494 M(ExtractNthOutput) \ |
495 M(BinaryUint32Op) \ | 495 M(BinaryUint32Op) \ |
496 M(ShiftUint32Op) \ | 496 M(ShiftUint32Op) \ |
497 M(UnaryUint32Op) \ | 497 M(UnaryUint32Op) \ |
498 M(BoxUint32) \ | 498 M(BoxUint32) \ |
499 M(UnboxUint32) \ | 499 M(UnboxUint32) \ |
500 M(BoxInt32) \ | 500 M(BoxInt32) \ |
501 M(UnboxInt32) \ | 501 M(UnboxInt32) \ |
502 M(UnboxedIntConverter) \ | 502 M(UnboxedIntConverter) \ |
503 M(GrowRegExpStack) \ | |
504 M(Deoptimize) | 503 M(Deoptimize) |
505 | 504 |
506 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ | 505 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ |
507 M(BlockEntry) \ | 506 M(BlockEntry) \ |
508 M(BoxInteger) \ | 507 M(BoxInteger) \ |
509 M(UnboxInteger) \ | 508 M(UnboxInteger) \ |
510 M(Comparison) \ | 509 M(Comparison) \ |
511 M(UnaryIntegerOp) \ | 510 M(UnaryIntegerOp) \ |
512 M(BinaryIntegerOp) | 511 M(BinaryIntegerOp) |
513 | 512 |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1222 // number of the block's spanning-tree parent. As a side effect of this | 1221 // number of the block's spanning-tree parent. As a side effect of this |
1223 // function, the set of basic block predecessors (e.g., block entry | 1222 // function, the set of basic block predecessors (e.g., block entry |
1224 // instructions of predecessor blocks) and also the last instruction in the | 1223 // instructions of predecessor blocks) and also the last instruction in the |
1225 // block is recorded in each entry instruction. Returns true when called the | 1224 // block is recorded in each entry instruction. Returns true when called the |
1226 // first time on this particular block within one graph traversal, and false | 1225 // first time on this particular block within one graph traversal, and false |
1227 // on all successive calls. | 1226 // on all successive calls. |
1228 bool DiscoverBlock(BlockEntryInstr* predecessor, | 1227 bool DiscoverBlock(BlockEntryInstr* predecessor, |
1229 GrowableArray<BlockEntryInstr*>* preorder, | 1228 GrowableArray<BlockEntryInstr*>* preorder, |
1230 GrowableArray<intptr_t>* parent); | 1229 GrowableArray<intptr_t>* parent); |
1231 | 1230 |
1232 // Perform a depth first search to prune code not reachable from an OSR | |
1233 // entry point. | |
1234 bool PruneUnreachable(GraphEntryInstr* graph_entry, | |
1235 Instruction* parent, | |
1236 intptr_t osr_id, | |
1237 BitVector* block_marks); | |
1238 | |
1239 virtual intptr_t InputCount() const { return 0; } | 1231 virtual intptr_t InputCount() const { return 0; } |
1240 virtual Value* InputAt(intptr_t i) const { | 1232 virtual Value* InputAt(intptr_t i) const { |
1241 UNREACHABLE(); | 1233 UNREACHABLE(); |
1242 return NULL; | 1234 return NULL; |
1243 } | 1235 } |
1244 | 1236 |
1245 virtual intptr_t ArgumentCount() const { return 0; } | 1237 virtual intptr_t ArgumentCount() const { return 0; } |
1246 | 1238 |
1247 virtual bool CanBecomeDeoptimizationTarget() const { | 1239 virtual bool CanBecomeDeoptimizationTarget() const { |
1248 // BlockEntry environment is copied to Goto and Branch instructions | 1240 // BlockEntry environment is copied to Goto and Branch instructions |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1297 try_index_(try_index), | 1289 try_index_(try_index), |
1298 preorder_number_(-1), | 1290 preorder_number_(-1), |
1299 postorder_number_(-1), | 1291 postorder_number_(-1), |
1300 dominator_(NULL), | 1292 dominator_(NULL), |
1301 dominated_blocks_(1), | 1293 dominated_blocks_(1), |
1302 last_instruction_(NULL), | 1294 last_instruction_(NULL), |
1303 offset_(-1), | 1295 offset_(-1), |
1304 parallel_move_(NULL), | 1296 parallel_move_(NULL), |
1305 loop_info_(NULL) {} | 1297 loop_info_(NULL) {} |
1306 | 1298 |
1299 // Perform a depth first search to prune code not reachable from an OSR | |
1300 // entry point. | |
erikcorry
2017/06/22 13:08:06
Perform a depth first search to find the OSR entry
Vyacheslav Egorov (Google)
2017/06/22 14:58:48
Done.
| |
1301 bool PruneUnreachable(GraphEntryInstr* graph_entry, | |
1302 Instruction* parent, | |
1303 BitVector* block_marks); | |
1304 | |
1307 private: | 1305 private: |
1308 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } | 1306 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } |
1309 | 1307 |
1310 virtual void ClearPredecessors() = 0; | 1308 virtual void ClearPredecessors() = 0; |
1311 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 1309 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
1312 | 1310 |
1313 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1311 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1314 | 1312 |
1315 intptr_t block_id_; | 1313 intptr_t block_id_; |
1316 intptr_t try_index_; | 1314 intptr_t try_index_; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1410 | 1408 |
1411 void AddIndirectEntry(IndirectEntryInstr* entry) { | 1409 void AddIndirectEntry(IndirectEntryInstr* entry) { |
1412 indirect_entries_.Add(entry); | 1410 indirect_entries_.Add(entry); |
1413 } | 1411 } |
1414 | 1412 |
1415 GrowableArray<Definition*>* initial_definitions() { | 1413 GrowableArray<Definition*>* initial_definitions() { |
1416 return &initial_definitions_; | 1414 return &initial_definitions_; |
1417 } | 1415 } |
1418 ConstantInstr* constant_null(); | 1416 ConstantInstr* constant_null(); |
1419 | 1417 |
1418 void PruneUnreachableForOSR(Zone* zone, intptr_t max_block_id); | |
1420 bool IsCompiledForOsr() const; | 1419 bool IsCompiledForOsr() const; |
1420 intptr_t osr_id() const { return osr_id_; } | |
1421 | 1421 |
1422 intptr_t entry_count() const { return entry_count_; } | 1422 intptr_t entry_count() const { return entry_count_; } |
1423 void set_entry_count(intptr_t count) { entry_count_ = count; } | 1423 void set_entry_count(intptr_t count) { entry_count_ = count; } |
1424 | 1424 |
1425 intptr_t spill_slot_count() const { return spill_slot_count_; } | 1425 intptr_t spill_slot_count() const { return spill_slot_count_; } |
1426 void set_spill_slot_count(intptr_t count) { | 1426 void set_spill_slot_count(intptr_t count) { |
1427 ASSERT(count >= 0); | 1427 ASSERT(count >= 0); |
1428 spill_slot_count_ = count; | 1428 spill_slot_count_ = count; |
1429 } | 1429 } |
1430 | 1430 |
(...skipping 5849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7280 | 7280 |
7281 private: | 7281 private: |
7282 const Token::Kind op_kind_; | 7282 const Token::Kind op_kind_; |
7283 | 7283 |
7284 DISALLOW_COPY_AND_ASSIGN(UnaryDoubleOpInstr); | 7284 DISALLOW_COPY_AND_ASSIGN(UnaryDoubleOpInstr); |
7285 }; | 7285 }; |
7286 | 7286 |
7287 | 7287 |
7288 class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> { | 7288 class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> { |
7289 public: | 7289 public: |
7290 enum Kind { | |
7291 // kOsrAndPreemption stack overflow checks are emitted in both unoptimized | |
7292 // and optimized versions of the code and they serve as both preemption and | |
7293 // OSR entry points. | |
7294 kOsrAndPreemption, | |
7295 | |
7296 // kOsrOnly stack overflow checks are only needed in the unoptimized code | |
7297 // because we can't OSR optimized code. | |
7298 kOsrOnly, | |
7299 }; | |
7300 | |
7290 CheckStackOverflowInstr(TokenPosition token_pos, | 7301 CheckStackOverflowInstr(TokenPosition token_pos, |
7291 intptr_t loop_depth, | 7302 intptr_t loop_depth, |
7292 intptr_t deopt_id) | 7303 intptr_t deopt_id, |
7304 Kind kind = kOsrAndPreemption) | |
7293 : TemplateInstruction(deopt_id), | 7305 : TemplateInstruction(deopt_id), |
7294 token_pos_(token_pos), | 7306 token_pos_(token_pos), |
7295 loop_depth_(loop_depth) {} | 7307 loop_depth_(loop_depth), |
7308 kind_(kind) { | |
7309 ASSERT(kind != kOsrOnly || loop_depth > 0); | |
7310 } | |
7296 | 7311 |
7297 virtual TokenPosition token_pos() const { return token_pos_; } | 7312 virtual TokenPosition token_pos() const { return token_pos_; } |
7298 bool in_loop() const { return loop_depth_ > 0; } | 7313 bool in_loop() const { return loop_depth_ > 0; } |
7299 intptr_t loop_depth() const { return loop_depth_; } | 7314 intptr_t loop_depth() const { return loop_depth_; } |
7300 | 7315 |
7301 DECLARE_INSTRUCTION(CheckStackOverflow) | 7316 DECLARE_INSTRUCTION(CheckStackOverflow) |
7302 | 7317 |
7303 virtual bool ComputeCanDeoptimize() const { return true; } | 7318 virtual bool ComputeCanDeoptimize() const { return true; } |
7304 | 7319 |
7320 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | |
7321 | |
7305 virtual EffectSet Effects() const { return EffectSet::None(); } | 7322 virtual EffectSet Effects() const { return EffectSet::None(); } |
7306 | 7323 |
7307 PRINT_OPERANDS_TO_SUPPORT | 7324 PRINT_OPERANDS_TO_SUPPORT |
7308 | 7325 |
7309 private: | 7326 private: |
7310 const TokenPosition token_pos_; | 7327 const TokenPosition token_pos_; |
7311 const intptr_t loop_depth_; | 7328 const intptr_t loop_depth_; |
7329 const Kind kind_; | |
7312 | 7330 |
7313 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); | 7331 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); |
7314 }; | 7332 }; |
7315 | 7333 |
7316 | 7334 |
7317 // TODO(vegorov): remove this instruction in favor of Int32ToDouble. | 7335 // TODO(vegorov): remove this instruction in favor of Int32ToDouble. |
7318 class SmiToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { | 7336 class SmiToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7319 public: | 7337 public: |
7320 SmiToDoubleInstr(Value* value, TokenPosition token_pos) | 7338 SmiToDoubleInstr(Value* value, TokenPosition token_pos) |
7321 : token_pos_(token_pos) { | 7339 : token_pos_(token_pos) { |
(...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7970 | 7988 |
7971 private: | 7989 private: |
7972 const Representation from_representation_; | 7990 const Representation from_representation_; |
7973 const Representation to_representation_; | 7991 const Representation to_representation_; |
7974 bool is_truncating_; | 7992 bool is_truncating_; |
7975 | 7993 |
7976 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); | 7994 DISALLOW_COPY_AND_ASSIGN(UnboxedIntConverterInstr); |
7977 }; | 7995 }; |
7978 | 7996 |
7979 | 7997 |
7980 class GrowRegExpStackInstr : public TemplateDefinition<1, Throws> { | |
7981 public: | |
7982 explicit GrowRegExpStackInstr(Value* typed_data_cell) { | |
7983 SetInputAt(0, typed_data_cell); | |
7984 } | |
7985 | |
7986 Value* typed_data_cell() const { return inputs_[0]; } | |
7987 | |
7988 virtual bool ComputeCanDeoptimize() const { return MayThrow(); } | |
7989 virtual EffectSet Effects() const { return EffectSet::None(); } | |
7990 | |
7991 DECLARE_INSTRUCTION(GrowRegExpStack); | |
7992 | |
7993 private: | |
7994 DISALLOW_COPY_AND_ASSIGN(GrowRegExpStackInstr); | |
7995 }; | |
7996 | |
7997 | |
7998 #undef DECLARE_INSTRUCTION | 7998 #undef DECLARE_INSTRUCTION |
7999 | 7999 |
8000 class Environment : public ZoneAllocated { | 8000 class Environment : public ZoneAllocated { |
8001 public: | 8001 public: |
8002 // Iterate the non-NULL values in the innermost level of an environment. | 8002 // Iterate the non-NULL values in the innermost level of an environment. |
8003 class ShallowIterator : public ValueObject { | 8003 class ShallowIterator : public ValueObject { |
8004 public: | 8004 public: |
8005 explicit ShallowIterator(Environment* environment) | 8005 explicit ShallowIterator(Environment* environment) |
8006 : environment_(environment), index_(0) {} | 8006 : environment_(environment), index_(0) {} |
8007 | 8007 |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8256 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8256 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
8257 UNIMPLEMENTED(); \ | 8257 UNIMPLEMENTED(); \ |
8258 return NULL; \ | 8258 return NULL; \ |
8259 } \ | 8259 } \ |
8260 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8260 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
8261 | 8261 |
8262 | 8262 |
8263 } // namespace dart | 8263 } // namespace dart |
8264 | 8264 |
8265 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8265 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |