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 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/hash_map.h" | 10 #include "vm/hash_map.h" |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 986 } else if (comparison->IsEqualityCompare()) { | 986 } else if (comparison->IsEqualityCompare()) { |
| 987 HandleEqualityCompare(this, comparison->AsEqualityCompare(), instr, | 987 HandleEqualityCompare(this, comparison->AsEqualityCompare(), instr, |
| 988 current_iterator()); | 988 current_iterator()); |
| 989 } else { | 989 } else { |
| 990 ASSERT(comparison->IsStrictCompare()); | 990 ASSERT(comparison->IsStrictCompare()); |
| 991 // Nothing to do. | 991 // Nothing to do. |
| 992 } | 992 } |
| 993 } | 993 } |
| 994 | 994 |
| 995 | 995 |
| 996 // SminessPropagator ensures that CheckSmis are eliminated across phis. | |
| 997 class SminessPropagator { | |
| 998 public: | |
| 999 explicit SminessPropagator(FlowGraph* flow_graph) | |
| 1000 : flow_graph_(flow_graph), | |
| 1001 known_smis_(new BitVector(flow_graph_->current_ssa_temp_index())), | |
| 1002 rollback_checks_(10), | |
| 1003 in_worklist_(NULL), | |
| 1004 worklist_(0) { } | |
| 1005 | |
| 1006 void Propagate(); | |
| 1007 | |
| 1008 private: | |
| 1009 void PropagateSminessRecursive(BlockEntryInstr* block); | |
| 1010 void AddToWorklist(PhiInstr* phi); | |
| 1011 PhiInstr* RemoveLastFromWorklist(); | |
| 1012 void ProcessPhis(); | |
| 1013 | |
| 1014 FlowGraph* flow_graph_; | |
| 1015 | |
| 1016 BitVector* known_smis_; | |
| 1017 GrowableArray<intptr_t> rollback_checks_; | |
| 1018 | |
| 1019 BitVector* in_worklist_; | |
| 1020 GrowableArray<PhiInstr*> worklist_; | |
| 1021 }; | |
| 1022 | |
| 1023 | |
| 1024 void SminessPropagator::AddToWorklist(PhiInstr* phi) { | |
| 1025 if (in_worklist_ == NULL) { | |
| 1026 in_worklist_ = new BitVector(flow_graph_->current_ssa_temp_index()); | |
| 1027 } | |
| 1028 if (!in_worklist_->Contains(phi->ssa_temp_index())) { | |
| 1029 in_worklist_->Add(phi->ssa_temp_index()); | |
| 1030 worklist_.Add(phi); | |
| 1031 } | |
| 1032 } | |
| 1033 | |
| 1034 | |
| 1035 PhiInstr* SminessPropagator::RemoveLastFromWorklist() { | |
| 1036 PhiInstr* phi = worklist_.Last(); | |
| 1037 worklist_.RemoveLast(); | |
|
Florian Schneider
2012/09/12 17:13:11
Add ASSERT(in_worklist_->Contains(phi->ssa_temp_in
| |
| 1038 in_worklist_->Remove(phi->ssa_temp_index()); | |
| 1039 return phi; | |
| 1040 } | |
| 1041 | |
| 1042 | |
| 1043 static bool IsSmiPhi(PhiInstr* phi) { | |
| 1044 for (intptr_t i = 0; i < phi->InputCount(); i++) { | |
| 1045 Value* input = phi->InputAt(i); | |
| 1046 if ((input->definition() != phi) && | |
| 1047 (input->ResultCid() != kSmiCid)) { | |
| 1048 return false; | |
| 1049 } | |
| 1050 } | |
| 1051 return true; | |
| 1052 } | |
| 1053 | |
| 1054 | |
| 1055 void SminessPropagator::ProcessPhis() { | |
| 1056 while (!worklist_.is_empty()) { | |
| 1057 PhiInstr* phi = RemoveLastFromWorklist(); | |
| 1058 if (IsSmiPhi(phi)) { | |
|
Florian Schneider
2012/09/12 17:13:11
Maybe assert
ASSERT(phi->GetPropagatedCid() != kS
| |
| 1059 phi->SetPropagatedCid(kSmiCid); | |
| 1060 for (Value* use = phi->input_use_list(); | |
| 1061 use != NULL; | |
| 1062 use = use->next_use()) { | |
| 1063 if (use->definition()->IsPhi() && | |
| 1064 (use->definition()->GetPropagatedCid() != kSmiCid)) { | |
| 1065 AddToWorklist(use->definition()->AsPhi()); | |
| 1066 } | |
| 1067 } | |
| 1068 } | |
| 1069 } | |
| 1070 } | |
| 1071 | |
| 1072 | |
| 1073 void SminessPropagator::PropagateSminessRecursive(BlockEntryInstr* block) { | |
| 1074 const intptr_t rollback_point = rollback_checks_.length(); | |
| 1075 | |
| 1076 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { | |
| 1077 Instruction* instr = it.Current(); | |
| 1078 if (instr->IsCheckSmi()) { | |
| 1079 const intptr_t value_ssa_index = | |
| 1080 instr->InputAt(0)->definition()->ssa_temp_index(); | |
| 1081 if (!known_smis_->Contains(value_ssa_index)) { | |
| 1082 known_smis_->Add(value_ssa_index); | |
| 1083 rollback_checks_.Add(value_ssa_index); | |
| 1084 } | |
| 1085 } | |
| 1086 } | |
| 1087 | |
| 1088 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { | |
| 1089 PropagateSminessRecursive(block->dominated_blocks()[i]); | |
| 1090 } | |
| 1091 | |
| 1092 if (block->last_instruction()->SuccessorCount() == 1 && | |
| 1093 block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | |
| 1094 JoinEntryInstr* join = | |
| 1095 block->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | |
| 1096 intptr_t pred_index = join->IndexOfPredecessor(block); | |
| 1097 ASSERT(pred_index >= 0); | |
| 1098 if (join->phis() != NULL) { | |
| 1099 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | |
| 1100 PhiInstr* phi = (*join->phis())[i]; | |
| 1101 if (phi == NULL) continue; | |
| 1102 Value* use = phi->InputAt(pred_index); | |
| 1103 const intptr_t value_ssa_index = use->definition()->ssa_temp_index(); | |
| 1104 if (known_smis_->Contains(value_ssa_index) && | |
| 1105 (phi->GetPropagatedCid() != kSmiCid)) { | |
| 1106 use->set_reaching_cid(kSmiCid); | |
| 1107 AddToWorklist(phi); | |
| 1108 } | |
| 1109 } | |
| 1110 } | |
| 1111 } | |
| 1112 | |
| 1113 for (intptr_t i = rollback_point; i < rollback_checks_.length(); i++) { | |
| 1114 known_smis_->Remove(rollback_checks_[i]); | |
| 1115 } | |
| 1116 rollback_checks_.TruncateTo(rollback_point); | |
| 1117 } | |
| 1118 | |
| 1119 | |
| 1120 void SminessPropagator::Propagate() { | |
| 1121 PropagateSminessRecursive(flow_graph_->graph_entry()); | |
| 1122 ProcessPhis(); | |
| 1123 } | |
| 1124 | |
| 1125 | |
| 1126 void FlowGraphOptimizer::PropagateSminess() { | |
| 1127 SminessPropagator propagator(flow_graph_); | |
| 1128 propagator.Propagate(); | |
| 1129 } | |
| 1130 | |
| 1131 | |
| 996 void FlowGraphTypePropagator::VisitBlocks() { | 1132 void FlowGraphTypePropagator::VisitBlocks() { |
| 997 ASSERT(current_iterator_ == NULL); | 1133 ASSERT(current_iterator_ == NULL); |
| 998 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 1134 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 999 BlockEntryInstr* entry = block_order_[i]; | 1135 BlockEntryInstr* entry = block_order_[i]; |
| 1000 entry->Accept(this); | 1136 entry->Accept(this); |
| 1001 ForwardInstructionIterator it(entry); | 1137 ForwardInstructionIterator it(entry); |
| 1002 current_iterator_ = ⁢ | 1138 current_iterator_ = ⁢ |
| 1003 for (; !it.Done(); it.Advance()) { | 1139 for (; !it.Done(); it.Advance()) { |
| 1004 Instruction* current = it.Current(); | 1140 Instruction* current = it.Current(); |
| 1005 // No need to propagate the input types of the instruction, as long as | 1141 // No need to propagate the input types of the instruction, as long as |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1427 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. | 1563 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. |
| 1428 OptimizeRecursive(child, &child_map); | 1564 OptimizeRecursive(child, &child_map); |
| 1429 } else { | 1565 } else { |
| 1430 OptimizeRecursive(child, map); // Reuse map for the last child. | 1566 OptimizeRecursive(child, map); // Reuse map for the last child. |
| 1431 } | 1567 } |
| 1432 } | 1568 } |
| 1433 } | 1569 } |
| 1434 | 1570 |
| 1435 | 1571 |
| 1436 } // namespace dart | 1572 } // namespace dart |
| OLD | NEW |