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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 18111006: Collect edge count profiling data and reorder basic blocks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_inliner.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 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/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 GrowableArray<BlockEntryInstr*>* preorder, 1177 GrowableArray<BlockEntryInstr*>* preorder,
1178 GrowableArray<BlockEntryInstr*>* postorder, 1178 GrowableArray<BlockEntryInstr*>* postorder,
1179 GrowableArray<intptr_t>* parent, 1179 GrowableArray<intptr_t>* parent,
1180 intptr_t variable_count, 1180 intptr_t variable_count,
1181 intptr_t fixed_parameter_count); 1181 intptr_t fixed_parameter_count);
1182 1182
1183 // Perform a depth first search to prune code not reachable from an OSR 1183 // Perform a depth first search to prune code not reachable from an OSR
1184 // entry point. 1184 // entry point.
1185 bool PruneUnreachable(FlowGraphBuilder* builder, 1185 bool PruneUnreachable(FlowGraphBuilder* builder,
1186 GraphEntryInstr* graph_entry, 1186 GraphEntryInstr* graph_entry,
1187 Instruction* parent,
1187 intptr_t osr_id, 1188 intptr_t osr_id,
1188 BitVector* block_marks); 1189 BitVector* block_marks);
1189 1190
1190 virtual intptr_t InputCount() const { return 0; } 1191 virtual intptr_t InputCount() const { return 0; }
1191 virtual Value* InputAt(intptr_t i) const { 1192 virtual Value* InputAt(intptr_t i) const {
1192 UNREACHABLE(); 1193 UNREACHABLE();
1193 return NULL; 1194 return NULL;
1194 } 1195 }
1195 1196
1196 virtual intptr_t ArgumentCount() const { return 0; } 1197 virtual intptr_t ArgumentCount() const { return 0; }
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 1343
1343 CatchBlockEntryInstr* GetCatchEntry(intptr_t index); 1344 CatchBlockEntryInstr* GetCatchEntry(intptr_t index);
1344 1345
1345 GrowableArray<Definition*>* initial_definitions() { 1346 GrowableArray<Definition*>* initial_definitions() {
1346 return &initial_definitions_; 1347 return &initial_definitions_;
1347 } 1348 }
1348 ConstantInstr* constant_null(); 1349 ConstantInstr* constant_null();
1349 1350
1350 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; } 1351 bool IsCompiledForOsr() const { return osr_id_ != Isolate::kNoDeoptId; }
1351 1352
1353 intptr_t entry_count() const { return entry_count_; }
1354 void set_entry_count(intptr_t count) { entry_count_ = count; }
1355
1352 intptr_t spill_slot_count() const { return spill_slot_count_; } 1356 intptr_t spill_slot_count() const { return spill_slot_count_; }
1353 void set_spill_slot_count(intptr_t count) { 1357 void set_spill_slot_count(intptr_t count) {
1354 ASSERT(count >= 0); 1358 ASSERT(count >= 0);
1355 spill_slot_count_ = count; 1359 spill_slot_count_ = count;
1356 } 1360 }
1357 1361
1358 // Number of stack slots reserved for compiling try-catch. For functions 1362 // Number of stack slots reserved for compiling try-catch. For functions
1359 // without try-catch, this is 0. Otherwise, it is the number of local 1363 // without try-catch, this is 0. Otherwise, it is the number of local
1360 // variables. 1364 // variables.
1361 intptr_t fixed_slot_count() const { return fixed_slot_count_; } 1365 intptr_t fixed_slot_count() const { return fixed_slot_count_; }
(...skipping 15 matching lines...) Expand all
1377 1381
1378 private: 1382 private:
1379 virtual void ClearPredecessors() {} 1383 virtual void ClearPredecessors() {}
1380 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); } 1384 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
1381 1385
1382 const ParsedFunction& parsed_function_; 1386 const ParsedFunction& parsed_function_;
1383 TargetEntryInstr* normal_entry_; 1387 TargetEntryInstr* normal_entry_;
1384 GrowableArray<CatchBlockEntryInstr*> catch_entries_; 1388 GrowableArray<CatchBlockEntryInstr*> catch_entries_;
1385 GrowableArray<Definition*> initial_definitions_; 1389 GrowableArray<Definition*> initial_definitions_;
1386 const intptr_t osr_id_; 1390 const intptr_t osr_id_;
1391 intptr_t entry_count_;
1387 intptr_t spill_slot_count_; 1392 intptr_t spill_slot_count_;
1388 intptr_t fixed_slot_count_; // For try-catch in optimized code. 1393 intptr_t fixed_slot_count_; // For try-catch in optimized code.
1389 1394
1390 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 1395 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
1391 }; 1396 };
1392 1397
1393 1398
1394 class JoinEntryInstr : public BlockEntryInstr { 1399 class JoinEntryInstr : public BlockEntryInstr {
1395 public: 1400 public:
1396 JoinEntryInstr(intptr_t block_id, intptr_t try_index) 1401 JoinEntryInstr(intptr_t block_id, intptr_t try_index)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 1465
1461 private: 1466 private:
1462 ZoneGrowableArray<PhiInstr*>* phis_; 1467 ZoneGrowableArray<PhiInstr*>* phis_;
1463 intptr_t index_; 1468 intptr_t index_;
1464 }; 1469 };
1465 1470
1466 1471
1467 class TargetEntryInstr : public BlockEntryInstr { 1472 class TargetEntryInstr : public BlockEntryInstr {
1468 public: 1473 public:
1469 TargetEntryInstr(intptr_t block_id, intptr_t try_index) 1474 TargetEntryInstr(intptr_t block_id, intptr_t try_index)
1470 : BlockEntryInstr(block_id, try_index), predecessor_(NULL) { } 1475 : BlockEntryInstr(block_id, try_index),
1476 predecessor_(NULL),
1477 edge_weight_(0.0) {
1478 }
1471 1479
1472 DECLARE_INSTRUCTION(TargetEntry) 1480 DECLARE_INSTRUCTION(TargetEntry)
1473 1481
1482 double edge_weight() const { return edge_weight_; }
1483 void set_edge_weight(double weight) { edge_weight_ = weight; }
1484 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; }
1485
1474 virtual intptr_t PredecessorCount() const { 1486 virtual intptr_t PredecessorCount() const {
1475 return (predecessor_ == NULL) ? 0 : 1; 1487 return (predecessor_ == NULL) ? 0 : 1;
1476 } 1488 }
1477 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { 1489 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const {
1478 ASSERT((index == 0) && (predecessor_ != NULL)); 1490 ASSERT((index == 0) && (predecessor_ != NULL));
1479 return predecessor_; 1491 return predecessor_;
1480 } 1492 }
1481 1493
1482 virtual void PrintTo(BufferFormatter* f) const; 1494 virtual void PrintTo(BufferFormatter* f) const;
1483 1495
1484 private: 1496 private:
1485 friend class BlockEntryInstr; // Access to predecessor_ when inlining. 1497 friend class BlockEntryInstr; // Access to predecessor_ when inlining.
1486 1498
1487 virtual void ClearPredecessors() { predecessor_ = NULL; } 1499 virtual void ClearPredecessors() { predecessor_ = NULL; }
1488 virtual void AddPredecessor(BlockEntryInstr* predecessor) { 1500 virtual void AddPredecessor(BlockEntryInstr* predecessor) {
1489 ASSERT(predecessor_ == NULL); 1501 ASSERT(predecessor_ == NULL);
1490 predecessor_ = predecessor; 1502 predecessor_ = predecessor;
1491 } 1503 }
1492 1504
1493 BlockEntryInstr* predecessor_; 1505 BlockEntryInstr* predecessor_;
1506 double edge_weight_;
1494 1507
1495 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 1508 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
1496 }; 1509 };
1497 1510
1498 1511
1499 class CatchBlockEntryInstr : public BlockEntryInstr { 1512 class CatchBlockEntryInstr : public BlockEntryInstr {
1500 public: 1513 public:
1501 CatchBlockEntryInstr(intptr_t block_id, 1514 CatchBlockEntryInstr(intptr_t block_id,
1502 intptr_t try_index, 1515 intptr_t try_index,
1503 const Array& handler_types, 1516 const Array& handler_types,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 Definition(); 1576 Definition();
1564 1577
1565 virtual Definition* AsDefinition() { return this; } 1578 virtual Definition* AsDefinition() { return this; }
1566 1579
1567 bool IsComparison() { return (AsComparison() != NULL); } 1580 bool IsComparison() { return (AsComparison() != NULL); }
1568 virtual ComparisonInstr* AsComparison() { return NULL; } 1581 virtual ComparisonInstr* AsComparison() { return NULL; }
1569 1582
1570 // Overridden by definitions that push arguments. 1583 // Overridden by definitions that push arguments.
1571 virtual intptr_t ArgumentCount() const { return 0; } 1584 virtual intptr_t ArgumentCount() const { return 0; }
1572 1585
1586 // Overridden by definitions that have call counts.
1587 virtual intptr_t CallCount() const {
1588 UNREACHABLE();
1589 return -1;
1590 }
1591
1573 intptr_t temp_index() const { return temp_index_; } 1592 intptr_t temp_index() const { return temp_index_; }
1574 void set_temp_index(intptr_t index) { temp_index_ = index; } 1593 void set_temp_index(intptr_t index) { temp_index_ = index; }
1575 void ClearTempIndex() { temp_index_ = -1; } 1594 void ClearTempIndex() { temp_index_ = -1; }
1576 1595
1577 intptr_t ssa_temp_index() const { return ssa_temp_index_; } 1596 intptr_t ssa_temp_index() const { return ssa_temp_index_; }
1578 void set_ssa_temp_index(intptr_t index) { 1597 void set_ssa_temp_index(intptr_t index) {
1579 ASSERT(index >= 0); 1598 ASSERT(index >= 0);
1580 ASSERT(is_used()); 1599 ASSERT(is_used());
1581 ssa_temp_index_ = index; 1600 ssa_temp_index_ = index;
1582 } 1601 }
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 const intptr_t token_pos_; 1999 const intptr_t token_pos_;
1981 2000
1982 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); 2001 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
1983 }; 2002 };
1984 2003
1985 2004
1986 class GotoInstr : public TemplateInstruction<0> { 2005 class GotoInstr : public TemplateInstruction<0> {
1987 public: 2006 public:
1988 explicit GotoInstr(JoinEntryInstr* entry) 2007 explicit GotoInstr(JoinEntryInstr* entry)
1989 : successor_(entry), 2008 : successor_(entry),
1990 parallel_move_(NULL) { } 2009 edge_weight_(0.0),
2010 parallel_move_(NULL) {
2011 }
1991 2012
1992 DECLARE_INSTRUCTION(Goto) 2013 DECLARE_INSTRUCTION(Goto)
1993 2014
1994 virtual intptr_t ArgumentCount() const { return 0; } 2015 virtual intptr_t ArgumentCount() const { return 0; }
1995 2016
1996 JoinEntryInstr* successor() const { return successor_; } 2017 JoinEntryInstr* successor() const { return successor_; }
1997 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } 2018 void set_successor(JoinEntryInstr* successor) { successor_ = successor; }
1998 virtual intptr_t SuccessorCount() const; 2019 virtual intptr_t SuccessorCount() const;
1999 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 2020 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
2000 2021
2022 double edge_weight() const { return edge_weight_; }
2023 void set_edge_weight(double weight) { edge_weight_ = weight; }
2024 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; }
2025
2001 virtual bool CanBecomeDeoptimizationTarget() const { 2026 virtual bool CanBecomeDeoptimizationTarget() const {
2002 // Goto instruction can be used as a deoptimization target when LICM 2027 // Goto instruction can be used as a deoptimization target when LICM
2003 // hoists instructions out of the loop. 2028 // hoists instructions out of the loop.
2004 return true; 2029 return true;
2005 } 2030 }
2006 2031
2007 virtual bool CanDeoptimize() const { return false; } 2032 virtual bool CanDeoptimize() const { return false; }
2008 2033
2009 virtual EffectSet Effects() const { return EffectSet::None(); } 2034 virtual EffectSet Effects() const { return EffectSet::None(); }
2010 2035
(...skipping 11 matching lines...) Expand all
2022 } 2047 }
2023 return parallel_move_; 2048 return parallel_move_;
2024 } 2049 }
2025 2050
2026 virtual void PrintTo(BufferFormatter* f) const; 2051 virtual void PrintTo(BufferFormatter* f) const;
2027 2052
2028 virtual bool MayThrow() const { return false; } 2053 virtual bool MayThrow() const { return false; }
2029 2054
2030 private: 2055 private:
2031 JoinEntryInstr* successor_; 2056 JoinEntryInstr* successor_;
2057 double edge_weight_;
2032 2058
2033 // Parallel move that will be used by linear scan register allocator to 2059 // Parallel move that will be used by linear scan register allocator to
2034 // connect live ranges at the end of the block and resolve phis. 2060 // connect live ranges at the end of the block and resolve phis.
2035 ParallelMoveInstr* parallel_move_; 2061 ParallelMoveInstr* parallel_move_;
2036 }; 2062 };
2037 2063
2038 2064
2039 class ControlInstruction : public Instruction { 2065 class ControlInstruction : public Instruction {
2040 public: 2066 public:
2041 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { } 2067 ControlInstruction() : true_successor_(NULL), false_successor_(NULL) { }
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
2589 DECLARE_INSTRUCTION(ClosureCall) 2615 DECLARE_INSTRUCTION(ClosureCall)
2590 2616
2591 const Array& argument_names() const { return ast_node_.arguments()->names(); } 2617 const Array& argument_names() const { return ast_node_.arguments()->names(); }
2592 intptr_t token_pos() const { return ast_node_.token_pos(); } 2618 intptr_t token_pos() const { return ast_node_.token_pos(); }
2593 2619
2594 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2620 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2595 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2621 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2596 return (*arguments_)[index]; 2622 return (*arguments_)[index];
2597 } 2623 }
2598 2624
2625 // TODO(kmillikin): implement exact call counts for closure calls.
2626 virtual intptr_t CallCount() const { return 1; }
2627
2599 virtual void PrintOperandsTo(BufferFormatter* f) const; 2628 virtual void PrintOperandsTo(BufferFormatter* f) const;
2600 2629
2601 virtual bool CanDeoptimize() const { return true; } 2630 virtual bool CanDeoptimize() const { return true; }
2602 2631
2603 virtual EffectSet Effects() const { return EffectSet::All(); } 2632 virtual EffectSet Effects() const { return EffectSet::All(); }
2604 2633
2605 virtual bool MayThrow() const { return true; } 2634 virtual bool MayThrow() const { return true; }
2606 2635
2607 private: 2636 private:
2608 const ClosureCallNode& ast_node_; 2637 const ClosureCallNode& ast_node_;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2703 2732
2704 virtual intptr_t ArgumentCount() const { 2733 virtual intptr_t ArgumentCount() const {
2705 return instance_call()->ArgumentCount(); 2734 return instance_call()->ArgumentCount();
2706 } 2735 }
2707 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2736 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2708 return instance_call()->PushArgumentAt(index); 2737 return instance_call()->PushArgumentAt(index);
2709 } 2738 }
2710 2739
2711 bool HasRecognizedTarget() const; 2740 bool HasRecognizedTarget() const;
2712 2741
2742 virtual intptr_t CallCount() const { return ic_data().AggregateCount(); }
2743
2713 DECLARE_INSTRUCTION(PolymorphicInstanceCall) 2744 DECLARE_INSTRUCTION(PolymorphicInstanceCall)
2714 2745
2715 const ICData& ic_data() const { return ic_data_; } 2746 const ICData& ic_data() const { return ic_data_; }
2716 2747
2717 virtual bool CanDeoptimize() const { return true; } 2748 virtual bool CanDeoptimize() const { return true; }
2718 2749
2719 virtual EffectSet Effects() const { return EffectSet::All(); } 2750 virtual EffectSet Effects() const { return EffectSet::All(); }
2720 2751
2721 virtual void PrintOperandsTo(BufferFormatter* f) const; 2752 virtual void PrintOperandsTo(BufferFormatter* f) const;
2722 2753
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3107 // Accessors forwarded to the AST node. 3138 // Accessors forwarded to the AST node.
3108 const Function& function() const { return function_; } 3139 const Function& function() const { return function_; }
3109 const Array& argument_names() const { return argument_names_; } 3140 const Array& argument_names() const { return argument_names_; }
3110 intptr_t token_pos() const { return token_pos_; } 3141 intptr_t token_pos() const { return token_pos_; }
3111 3142
3112 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 3143 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
3113 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 3144 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
3114 return (*arguments_)[index]; 3145 return (*arguments_)[index];
3115 } 3146 }
3116 3147
3148 virtual intptr_t CallCount() const { return ic_data()->AggregateCount(); }
3149
3117 virtual void PrintOperandsTo(BufferFormatter* f) const; 3150 virtual void PrintOperandsTo(BufferFormatter* f) const;
3118 3151
3119 virtual bool CanDeoptimize() const { return true; } 3152 virtual bool CanDeoptimize() const { return true; }
3120 3153
3121 virtual EffectSet Effects() const { return EffectSet::All(); } 3154 virtual EffectSet Effects() const { return EffectSet::All(); }
3122 3155
3123 void set_result_cid(intptr_t value) { result_cid_ = value; } 3156 void set_result_cid(intptr_t value) { result_cid_ = value; }
3124 3157
3125 bool is_known_list_constructor() const { return is_known_list_constructor_; } 3158 bool is_known_list_constructor() const { return is_known_list_constructor_; }
3126 void set_is_known_list_constructor(bool value) { 3159 void set_is_known_list_constructor(bool value) {
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after
6748 ForwardInstructionIterator* current_iterator_; 6781 ForwardInstructionIterator* current_iterator_;
6749 6782
6750 private: 6783 private:
6751 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 6784 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
6752 }; 6785 };
6753 6786
6754 6787
6755 } // namespace dart 6788 } // namespace dart
6756 6789
6757 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 6790 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698