| 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.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 current->set_previous(previous); | 60 current->set_previous(previous); |
| 61 previous = current; | 61 previous = current; |
| 62 } | 62 } |
| 63 } | 63 } |
| 64 } | 64 } |
| 65 | 65 |
| 66 | 66 |
| 67 #ifdef DEBUG | 67 #ifdef DEBUG |
| 68 // Debugging code to verify the construction of use lists. | 68 // Debugging code to verify the construction of use lists. |
| 69 | 69 |
| 70 static intptr_t MembershipCount(UseVal* use, UseVal* list) { | 70 static intptr_t MembershipCount(Value* use, Value* list) { |
| 71 intptr_t count = 0; | 71 intptr_t count = 0; |
| 72 while (list != NULL) { | 72 while (list != NULL) { |
| 73 if (list == use) ++count; | 73 if (list == use) ++count; |
| 74 list = list->next_use(); | 74 list = list->next_use(); |
| 75 } | 75 } |
| 76 return count; | 76 return count; |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 static void ResetUseListsInInstruction(Instruction* instr) { | 80 static void ResetUseListsInInstruction(Instruction* instr) { |
| 81 Definition* defn = instr->AsDefinition(); | 81 Definition* defn = instr->AsDefinition(); |
| 82 if (defn != NULL) { | 82 if (defn != NULL) { |
| 83 defn->set_input_use_list(NULL); | 83 defn->set_input_use_list(NULL); |
| 84 defn->set_env_use_list(NULL); | 84 defn->set_env_use_list(NULL); |
| 85 } | 85 } |
| 86 for (intptr_t i = 0; i < instr->InputCount(); ++i) { | 86 for (intptr_t i = 0; i < instr->InputCount(); ++i) { |
| 87 UseVal* use = instr->InputAt(i)->AsUse(); | 87 Value* use = instr->InputAt(i); |
| 88 if (use == NULL) continue; | |
| 89 use->set_instruction(NULL); | 88 use->set_instruction(NULL); |
| 90 use->set_use_index(-1); | 89 use->set_use_index(-1); |
| 91 use->set_next_use(NULL); | 90 use->set_next_use(NULL); |
| 92 } | 91 } |
| 93 if (instr->env() != NULL) { | 92 if (instr->env() != NULL) { |
| 94 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { | 93 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { |
| 95 UseVal* use = instr->env()->values()[i]->AsUse(); | 94 Value* use = instr->env()->values()[i]; |
| 96 if (use == NULL) continue; | |
| 97 use->set_instruction(NULL); | 95 use->set_instruction(NULL); |
| 98 use->set_use_index(-1); | 96 use->set_use_index(-1); |
| 99 use->set_next_use(NULL); | 97 use->set_next_use(NULL); |
| 100 } | 98 } |
| 101 } | 99 } |
| 102 } | 100 } |
| 103 | 101 |
| 104 | 102 |
| 105 bool FlowGraph::ResetUseLists() { | 103 bool FlowGraph::ResetUseLists() { |
| 106 // Reset global constants. | 104 // Reset global constants. |
| 107 ResetUseListsInInstruction(graph_entry_->constant_null()); | 105 ResetUseListsInInstruction(graph_entry_->constant_null()); |
| 108 | 106 |
| 109 // Reset definitions referenced from the start environment. | 107 // Reset definitions referenced from the start environment. |
| 110 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { | 108 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { |
| 111 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); | 109 Value* env_use = graph_entry_->start_env()->values()[i]; |
| 112 if (env_use != NULL) ResetUseListsInInstruction(env_use->definition()); | 110 ResetUseListsInInstruction(env_use->definition()); |
| 113 } | 111 } |
| 114 | 112 |
| 115 // Reset phis in join entries and the instructions in each block. | 113 // Reset phis in join entries and the instructions in each block. |
| 116 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 114 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 117 BlockEntryInstr* entry = preorder_[i]; | 115 BlockEntryInstr* entry = preorder_[i]; |
| 118 JoinEntryInstr* join = entry->AsJoinEntry(); | 116 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 119 if (join != NULL && join->phis() != NULL) { | 117 if (join != NULL && join->phis() != NULL) { |
| 120 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 118 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 121 PhiInstr* phi = (*join->phis())[i]; | 119 PhiInstr* phi = (*join->phis())[i]; |
| 122 if (phi != NULL) ResetUseListsInInstruction(phi); | 120 if (phi != NULL) ResetUseListsInInstruction(phi); |
| 123 } | 121 } |
| 124 } | 122 } |
| 125 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 123 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 126 ResetUseListsInInstruction(it.Current()); | 124 ResetUseListsInInstruction(it.Current()); |
| 127 } | 125 } |
| 128 } | 126 } |
| 129 return true; // Return true so we can ASSERT the reset code. | 127 return true; // Return true so we can ASSERT the reset code. |
| 130 } | 128 } |
| 131 | 129 |
| 132 | 130 |
| 133 static void ValidateUseListsInInstruction(Instruction* instr) { | 131 static void ValidateUseListsInInstruction(Instruction* instr) { |
| 134 ASSERT(instr != NULL); | 132 ASSERT(instr != NULL); |
| 135 ASSERT(!instr->IsJoinEntry()); | 133 ASSERT(!instr->IsJoinEntry()); |
| 136 for (intptr_t i = 0; i < instr->InputCount(); ++i) { | 134 for (intptr_t i = 0; i < instr->InputCount(); ++i) { |
| 137 UseVal* use = instr->InputAt(i)->AsUse(); | 135 Value* use = instr->InputAt(i); |
| 138 if (use == NULL) continue; | |
| 139 ASSERT(use->use_index() == i); | 136 ASSERT(use->use_index() == i); |
| 140 ASSERT(1 == MembershipCount(use, use->definition()->input_use_list())); | 137 ASSERT(1 == MembershipCount(use, use->definition()->input_use_list())); |
| 141 } | 138 } |
| 142 Environment* env = instr->env(); | 139 Environment* env = instr->env(); |
| 143 if (env != NULL) { | 140 if (env != NULL) { |
| 144 for (intptr_t i = 0; i < env->values().length(); ++i) { | 141 for (intptr_t i = 0; i < env->values().length(); ++i) { |
| 145 UseVal* use = env->values()[i]->AsUse(); | 142 Value* use = env->values()[i]; |
| 146 if (use == NULL) continue; | |
| 147 ASSERT(use->use_index() == i); | 143 ASSERT(use->use_index() == i); |
| 148 ASSERT(1 == MembershipCount(use, use->definition()->env_use_list())); | 144 ASSERT(1 == MembershipCount(use, use->definition()->env_use_list())); |
| 149 } | 145 } |
| 150 } | 146 } |
| 151 Definition* defn = instr->AsDefinition(); | 147 Definition* defn = instr->AsDefinition(); |
| 152 if (defn != NULL) { | 148 if (defn != NULL) { |
| 153 for (UseVal* use = defn->input_use_list(); | 149 for (Value* use = defn->input_use_list(); |
| 154 use != NULL; | 150 use != NULL; |
| 155 use = use->next_use()) { | 151 use = use->next_use()) { |
| 156 ASSERT(defn == use->definition()); | 152 ASSERT(defn == use->definition()); |
| 157 ASSERT(use == use->instruction()->InputAt(use->use_index())); | 153 ASSERT(use == use->instruction()->InputAt(use->use_index())); |
| 158 } | 154 } |
| 159 for (UseVal* use = defn->env_use_list(); | 155 for (Value* use = defn->env_use_list(); |
| 160 use != NULL; | 156 use != NULL; |
| 161 use = use->next_use()) { | 157 use = use->next_use()) { |
| 162 ASSERT(defn == use->definition()); | 158 ASSERT(defn == use->definition()); |
| 163 ASSERT(use == use->instruction()->env()->values()[use->use_index()]); | 159 ASSERT(use == use->instruction()->env()->values()[use->use_index()]); |
| 164 } | 160 } |
| 165 } | 161 } |
| 166 } | 162 } |
| 167 | 163 |
| 168 | 164 |
| 169 bool FlowGraph::ValidateUseLists() { | 165 bool FlowGraph::ValidateUseLists() { |
| 170 // Validate global constants. | 166 // Validate global constants. |
| 171 ValidateUseListsInInstruction(graph_entry_->constant_null()); | 167 ValidateUseListsInInstruction(graph_entry_->constant_null()); |
| 172 | 168 |
| 173 // Validate definitions referenced from the start environment. | 169 // Validate definitions referenced from the start environment. |
| 174 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { | 170 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { |
| 175 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); | 171 Value* env_use = graph_entry_->start_env()->values()[i]; |
| 176 if (env_use != NULL) ValidateUseListsInInstruction(env_use->definition()); | 172 ValidateUseListsInInstruction(env_use->definition()); |
| 177 } | 173 } |
| 178 | 174 |
| 179 // Validate phis in join entries and the instructions in each block. | 175 // Validate phis in join entries and the instructions in each block. |
| 180 for (intptr_t i = 0; i < preorder_.length(); ++i) { | 176 for (intptr_t i = 0; i < preorder_.length(); ++i) { |
| 181 BlockEntryInstr* entry = preorder_[i]; | 177 BlockEntryInstr* entry = preorder_[i]; |
| 182 JoinEntryInstr* join = entry->AsJoinEntry(); | 178 JoinEntryInstr* join = entry->AsJoinEntry(); |
| 183 if (join != NULL && join->phis() != NULL) { | 179 if (join != NULL && join->phis() != NULL) { |
| 184 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 180 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 185 PhiInstr* phi = (*join->phis())[i]; | 181 PhiInstr* phi = (*join->phis())[i]; |
| 186 if (phi != NULL) ValidateUseListsInInstruction(phi); | 182 if (phi != NULL) ValidateUseListsInInstruction(phi); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 200 DEBUG_ASSERT(defn->input_use_list() == NULL); | 196 DEBUG_ASSERT(defn->input_use_list() == NULL); |
| 201 DEBUG_ASSERT(defn->env_use_list() == NULL); | 197 DEBUG_ASSERT(defn->env_use_list() == NULL); |
| 202 defn->set_input_use_list(NULL); | 198 defn->set_input_use_list(NULL); |
| 203 defn->set_env_use_list(NULL); | 199 defn->set_env_use_list(NULL); |
| 204 } | 200 } |
| 205 | 201 |
| 206 | 202 |
| 207 static void RecordInputUses(Instruction* instr) { | 203 static void RecordInputUses(Instruction* instr) { |
| 208 ASSERT(instr != NULL); | 204 ASSERT(instr != NULL); |
| 209 for (intptr_t i = 0; i < instr->InputCount(); ++i) { | 205 for (intptr_t i = 0; i < instr->InputCount(); ++i) { |
| 210 UseVal* use = instr->InputAt(i)->AsUse(); | 206 Value* use = instr->InputAt(i); |
| 211 if (use == NULL) continue; | |
| 212 DEBUG_ASSERT(use->instruction() == NULL); | 207 DEBUG_ASSERT(use->instruction() == NULL); |
| 213 DEBUG_ASSERT(use->use_index() == -1); | 208 DEBUG_ASSERT(use->use_index() == -1); |
| 214 DEBUG_ASSERT(use->next_use() == NULL); | 209 DEBUG_ASSERT(use->next_use() == NULL); |
| 215 DEBUG_ASSERT(0 == MembershipCount(use, | 210 DEBUG_ASSERT(0 == MembershipCount(use, |
| 216 use->definition()->input_use_list())); | 211 use->definition()->input_use_list())); |
| 217 use->set_instruction(instr); | 212 use->set_instruction(instr); |
| 218 use->set_use_index(i); | 213 use->set_use_index(i); |
| 219 use->AddToInputUseList(); | 214 use->AddToInputUseList(); |
| 220 } | 215 } |
| 221 } | 216 } |
| 222 | 217 |
| 223 | 218 |
| 224 static void RecordEnvUses(Instruction* instr) { | 219 static void RecordEnvUses(Instruction* instr) { |
| 225 ASSERT(instr != NULL); | 220 ASSERT(instr != NULL); |
| 226 if (instr->env() == NULL) return; | 221 if (instr->env() == NULL) return; |
| 227 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { | 222 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { |
| 228 UseVal* use = instr->env()->values()[i]->AsUse(); | 223 Value* use = instr->env()->values()[i]; |
| 229 if (use == NULL) continue; | |
| 230 DEBUG_ASSERT(use->instruction() == NULL); | 224 DEBUG_ASSERT(use->instruction() == NULL); |
| 231 DEBUG_ASSERT(use->use_index() == -1); | 225 DEBUG_ASSERT(use->use_index() == -1); |
| 232 DEBUG_ASSERT(use->next_use() == NULL); | 226 DEBUG_ASSERT(use->next_use() == NULL); |
| 233 DEBUG_ASSERT(0 == MembershipCount(use, use->definition()->env_use_list())); | 227 DEBUG_ASSERT(0 == MembershipCount(use, use->definition()->env_use_list())); |
| 234 use->set_instruction(instr); | 228 use->set_instruction(instr); |
| 235 use->set_use_index(i); | 229 use->set_use_index(i); |
| 236 use->AddToEnvUseList(); | 230 use->AddToEnvUseList(); |
| 237 } | 231 } |
| 238 } | 232 } |
| 239 | 233 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 262 if (block->last_instruction()->SuccessorCount() == 1 && | 256 if (block->last_instruction()->SuccessorCount() == 1 && |
| 263 block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 257 block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 264 JoinEntryInstr* join = | 258 JoinEntryInstr* join = |
| 265 block->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 259 block->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 266 intptr_t pred_index = join->IndexOfPredecessor(block); | 260 intptr_t pred_index = join->IndexOfPredecessor(block); |
| 267 ASSERT(pred_index >= 0); | 261 ASSERT(pred_index >= 0); |
| 268 if (join->phis() != NULL) { | 262 if (join->phis() != NULL) { |
| 269 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 263 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 270 PhiInstr* phi = (*join->phis())[i]; | 264 PhiInstr* phi = (*join->phis())[i]; |
| 271 if (phi == NULL) continue; | 265 if (phi == NULL) continue; |
| 272 UseVal* use = phi->InputAt(pred_index)->AsUse(); | 266 Value* use = phi->InputAt(pred_index); |
| 273 if (use == NULL) continue; | |
| 274 DEBUG_ASSERT(use->instruction() == NULL); | 267 DEBUG_ASSERT(use->instruction() == NULL); |
| 275 DEBUG_ASSERT(use->use_index() == -1); | 268 DEBUG_ASSERT(use->use_index() == -1); |
| 276 DEBUG_ASSERT(use->next_use() == NULL); | 269 DEBUG_ASSERT(use->next_use() == NULL); |
| 277 DEBUG_ASSERT(0 == MembershipCount(use, | 270 DEBUG_ASSERT(0 == MembershipCount(use, |
| 278 use->definition()->input_use_list())); | 271 use->definition()->input_use_list())); |
| 279 use->set_instruction(phi); | 272 use->set_instruction(phi); |
| 280 use->set_use_index(pred_index); | 273 use->set_use_index(pred_index); |
| 281 use->AddToInputUseList(); | 274 use->AddToInputUseList(); |
| 282 } | 275 } |
| 283 } | 276 } |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // gets a full copy of the environment. Later we optimize this by | 534 // gets a full copy of the environment. Later we optimize this by |
| 542 // eliminating unnecessary environments. | 535 // eliminating unnecessary environments. |
| 543 current->set_env(new Environment(*env, non_copied_parameter_count_)); | 536 current->set_env(new Environment(*env, non_copied_parameter_count_)); |
| 544 | 537 |
| 545 // 2a. Handle uses: | 538 // 2a. Handle uses: |
| 546 // Update expression stack environment for each use. | 539 // Update expression stack environment for each use. |
| 547 // For each use of a LoadLocal or StoreLocal: Replace it with the value | 540 // For each use of a LoadLocal or StoreLocal: Replace it with the value |
| 548 // from the environment. | 541 // from the environment. |
| 549 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { | 542 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { |
| 550 Value* v = current->InputAt(i); | 543 Value* v = current->InputAt(i); |
| 551 if (!v->IsUse()) continue; | |
| 552 // Update expression stack. | 544 // Update expression stack. |
| 553 ASSERT(env->length() > variable_count()); | 545 ASSERT(env->length() > variable_count()); |
| 554 | 546 |
| 555 Definition* input_defn = env->Last(); | 547 Definition* input_defn = env->Last(); |
| 556 env->RemoveLast(); | 548 env->RemoveLast(); |
| 557 | 549 |
| 558 BindInstr* as_bind = v->AsUse()->definition()->AsBind(); | 550 BindInstr* as_bind = v->definition()->AsBind(); |
| 559 if ((as_bind != NULL) && | 551 if ((as_bind != NULL) && |
| 560 (as_bind->computation()->IsLoadLocal() || | 552 (as_bind->computation()->IsLoadLocal() || |
| 561 as_bind->computation()->IsStoreLocal())) { | 553 as_bind->computation()->IsStoreLocal())) { |
| 562 // Remove the load/store from the graph. | 554 // Remove the load/store from the graph. |
| 563 as_bind->RemoveFromGraph(); | 555 as_bind->RemoveFromGraph(); |
| 564 // Assert we are not referencing nulls in the initial environment. | 556 // Assert we are not referencing nulls in the initial environment. |
| 565 ASSERT(input_defn->ssa_temp_index() != -1); | 557 ASSERT(input_defn->ssa_temp_index() != -1); |
| 566 current->SetInputAt(i, new UseVal(input_defn)); | 558 current->SetInputAt(i, new Value(input_defn)); |
| 567 } | 559 } |
| 568 } | 560 } |
| 569 | 561 |
| 570 // Drop pushed arguments for calls. | 562 // Drop pushed arguments for calls. |
| 571 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { | 563 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { |
| 572 env->RemoveLast(); | 564 env->RemoveLast(); |
| 573 } | 565 } |
| 574 | 566 |
| 575 // 2b. Handle LoadLocal and StoreLocal. | 567 // 2b. Handle LoadLocal and StoreLocal. |
| 576 // For each LoadLocal: Remove it from the graph. | 568 // For each LoadLocal: Remove it from the graph. |
| 577 // For each StoreLocal: Remove it from the graph and update the environment. | 569 // For each StoreLocal: Remove it from the graph and update the environment. |
| 578 BindInstr* bind = current->AsBind(); | 570 BindInstr* bind = current->AsBind(); |
| 579 if (bind != NULL) { | 571 if (bind != NULL) { |
| 580 LoadLocalComp* load = bind->computation()->AsLoadLocal(); | 572 LoadLocalComp* load = bind->computation()->AsLoadLocal(); |
| 581 StoreLocalComp* store = bind->computation()->AsStoreLocal(); | 573 StoreLocalComp* store = bind->computation()->AsStoreLocal(); |
| 582 if ((load != NULL) || (store != NULL)) { | 574 if ((load != NULL) || (store != NULL)) { |
| 583 intptr_t index; | 575 intptr_t index; |
| 584 if (store != NULL) { | 576 if (store != NULL) { |
| 585 index = store->local().BitIndexIn(non_copied_parameter_count_); | 577 index = store->local().BitIndexIn(non_copied_parameter_count_); |
| 586 // Update renaming environment. | 578 // Update renaming environment. |
| 587 ASSERT(store->value()->IsUse()); | 579 (*env)[index] = store->value()->definition(); |
| 588 (*env)[index] = store->value()->AsUse()->definition(); | |
| 589 } else { | 580 } else { |
| 590 // The graph construction ensures we do not have an unused LoadLocal | 581 // The graph construction ensures we do not have an unused LoadLocal |
| 591 // computation. | 582 // computation. |
| 592 ASSERT(bind->is_used()); | 583 ASSERT(bind->is_used()); |
| 593 index = load->local().BitIndexIn(non_copied_parameter_count_); | 584 index = load->local().BitIndexIn(non_copied_parameter_count_); |
| 594 | 585 |
| 595 PhiInstr* phi = (*env)[index]->AsPhi(); | 586 PhiInstr* phi = (*env)[index]->AsPhi(); |
| 596 if ((phi != NULL) && !phi->is_alive()) { | 587 if ((phi != NULL) && !phi->is_alive()) { |
| 597 phi->mark_alive(); | 588 phi->mark_alive(); |
| 598 live_phis->Add(phi); | 589 live_phis->Add(phi); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 627 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 637 JoinEntryInstr* successor = | 628 JoinEntryInstr* successor = |
| 638 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 629 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 639 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); | 630 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); |
| 640 ASSERT(pred_index >= 0); | 631 ASSERT(pred_index >= 0); |
| 641 if (successor->phis() != NULL) { | 632 if (successor->phis() != NULL) { |
| 642 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { | 633 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { |
| 643 PhiInstr* phi = (*successor->phis())[i]; | 634 PhiInstr* phi = (*successor->phis())[i]; |
| 644 if (phi != NULL) { | 635 if (phi != NULL) { |
| 645 // Rename input operand. | 636 // Rename input operand. |
| 646 phi->SetInputAt(pred_index, new UseVal((*env)[i])); | 637 phi->SetInputAt(pred_index, new Value((*env)[i])); |
| 647 } | 638 } |
| 648 } | 639 } |
| 649 } | 640 } |
| 650 } | 641 } |
| 651 } | 642 } |
| 652 | 643 |
| 653 | 644 |
| 654 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { | 645 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { |
| 655 while (!live_phis->is_empty()) { | 646 while (!live_phis->is_empty()) { |
| 656 PhiInstr* phi = live_phis->Last(); | 647 PhiInstr* phi = live_phis->Last(); |
| 657 live_phis->RemoveLast(); | 648 live_phis->RemoveLast(); |
| 658 for (intptr_t i = 0; i < phi->InputCount(); i++) { | 649 for (intptr_t i = 0; i < phi->InputCount(); i++) { |
| 659 Value* val = phi->InputAt(i); | 650 Value* val = phi->InputAt(i); |
| 660 if (!val->IsUse()) continue; | 651 PhiInstr* used_phi = val->definition()->AsPhi(); |
| 661 PhiInstr* used_phi = val->AsUse()->definition()->AsPhi(); | |
| 662 if ((used_phi != NULL) && !used_phi->is_alive()) { | 652 if ((used_phi != NULL) && !used_phi->is_alive()) { |
| 663 used_phi->mark_alive(); | 653 used_phi->mark_alive(); |
| 664 live_phis->Add(used_phi); | 654 live_phis->Add(used_phi); |
| 665 } | 655 } |
| 666 } | 656 } |
| 667 } | 657 } |
| 668 } | 658 } |
| 669 | 659 |
| 670 | 660 |
| 671 void FlowGraph::Bailout(const char* reason) const { | 661 void FlowGraph::Bailout(const char* reason) const { |
| 672 const char* kFormat = "FlowGraph Bailout: %s %s"; | 662 const char* kFormat = "FlowGraph Bailout: %s %s"; |
| 673 const char* function_name = parsed_function_.function().ToCString(); | 663 const char* function_name = parsed_function_.function().ToCString(); |
| 674 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 664 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 675 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 665 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 676 OS::SNPrint(chars, len, kFormat, function_name, reason); | 666 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 677 const Error& error = Error::Handle( | 667 const Error& error = Error::Handle( |
| 678 LanguageError::New(String::Handle(String::New(chars)))); | 668 LanguageError::New(String::Handle(String::New(chars)))); |
| 679 Isolate::Current()->long_jump_base()->Jump(1, error); | 669 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 680 } | 670 } |
| 681 | 671 |
| 682 | 672 |
| 683 } // namespace dart | 673 } // namespace dart |
| OLD | NEW |