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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 12091091: Move recording of definition used from the value to the definition. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Restored RemoveFromUseList to class Value. Created 7 years, 10 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
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 #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/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 2221 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 for (Value* use = def->input_use_list(); 2232 for (Value* use = def->input_use_list();
2233 use != NULL; 2233 use != NULL;
2234 use = next_use) { 2234 use = next_use) {
2235 next_use = use->next_use(); 2235 next_use = use->next_use();
2236 2236
2237 // Skip dead phis. 2237 // Skip dead phis.
2238 PhiInstr* phi = use->instruction()->AsPhi(); 2238 PhiInstr* phi = use->instruction()->AsPhi();
2239 if ((phi != NULL) && !phi->is_alive()) continue; 2239 if ((phi != NULL) && !phi->is_alive()) continue;
2240 2240
2241 if (IsDominatedUse(dom, use)) { 2241 if (IsDominatedUse(dom, use)) {
2242 use->RemoveFromInputUseList(); 2242 use->RemoveFromUseList();
2243 use->set_definition(other); 2243 use->set_definition(other);
2244 use->AddToInputUseList(); 2244 other->AddInputUse(use);
2245 } 2245 }
2246 } 2246 }
2247 } 2247 }
2248 2248
2249 2249
2250 // For a comparison operation return an operation for the equivalent flipped 2250 // For a comparison operation return an operation for the equivalent flipped
2251 // comparison: a (op) b === b (op') a. 2251 // comparison: a (op) b === b (op') a.
2252 static Token::Kind FlipComparison(Token::Kind op) { 2252 static Token::Kind FlipComparison(Token::Kind op) {
2253 switch (op) { 2253 switch (op) {
2254 case Token::kEQ: return Token::kEQ; 2254 case Token::kEQ: return Token::kEQ;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 } 2310 }
2311 } 2311 }
2312 2312
2313 2313
2314 ConstraintInstr* RangeAnalysis::InsertConstraintFor(Definition* defn, 2314 ConstraintInstr* RangeAnalysis::InsertConstraintFor(Definition* defn,
2315 Range* constraint_range, 2315 Range* constraint_range,
2316 Instruction* after) { 2316 Instruction* after) {
2317 // No need to constrain constants. 2317 // No need to constrain constants.
2318 if (defn->IsConstant()) return NULL; 2318 if (defn->IsConstant()) return NULL;
2319 2319
2320 ConstraintInstr* constraint = 2320 Value* value = new Value(defn);
2321 new ConstraintInstr(new Value(defn), constraint_range); 2321 ConstraintInstr* constraint = new ConstraintInstr(value, constraint_range);
2322 constraint->InsertAfter(after); 2322 constraint->InsertAfter(after);
2323 constraint->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); 2323 constraint->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
2324 RenameDominatedUses(defn, after, constraint); 2324 RenameDominatedUses(defn, after, constraint);
2325 constraints_.Add(constraint); 2325 constraints_.Add(constraint);
2326 constraint->value()->set_instruction(constraint); 2326 value->set_instruction(constraint);
2327 constraint->value()->set_use_index(0); 2327 value->set_use_index(0);
2328 constraint->value()->AddToInputUseList(); 2328 defn->AddInputUse(value);
2329 return constraint; 2329 return constraint;
2330 } 2330 }
2331 2331
2332 2332
2333 void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) { 2333 void RangeAnalysis::ConstrainValueAfterBranch(Definition* defn, Value* use) {
2334 BranchInstr* branch = use->instruction()->AsBranch(); 2334 BranchInstr* branch = use->instruction()->AsBranch();
2335 RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp(); 2335 RelationalOpInstr* rel_op = branch->comparison()->AsRelationalOp();
2336 if ((rel_op != NULL) && (rel_op->operands_class_id() == kSmiCid)) { 2336 if ((rel_op != NULL) && (rel_op->operands_class_id() == kSmiCid)) {
2337 // Found comparison of two smis. Constrain defn at true and false 2337 // Found comparison of two smis. Constrain defn at true and false
2338 // successors using the other operand as a boundary. 2338 // successors using the other operand as a boundary.
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 ASSERT(last->env() != NULL); 2962 ASSERT(last->env() != NULL);
2963 last->env()->DeepCopyTo(current); 2963 last->env()->DeepCopyTo(current);
2964 current->deopt_id_ = last->GetDeoptId(); 2964 current->deopt_id_ = last->GetDeoptId();
2965 } 2965 }
2966 2966
2967 2967
2968 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it, 2968 void LICM::TryHoistCheckSmiThroughPhi(ForwardInstructionIterator* it,
2969 BlockEntryInstr* header, 2969 BlockEntryInstr* header,
2970 BlockEntryInstr* pre_header, 2970 BlockEntryInstr* pre_header,
2971 CheckSmiInstr* current) { 2971 CheckSmiInstr* current) {
2972 PhiInstr* phi = current->InputAt(0)->definition()->AsPhi(); 2972 PhiInstr* phi = current->value()->definition()->AsPhi();
2973 if (!header->loop_info()->Contains(phi->block()->preorder_number())) { 2973 if (!header->loop_info()->Contains(phi->block()->preorder_number())) {
2974 return; 2974 return;
2975 } 2975 }
2976 2976
2977 if (phi->GetPropagatedCid() == kSmiCid) { 2977 if (phi->GetPropagatedCid() == kSmiCid) {
2978 it->RemoveCurrentFromGraph(); 2978 it->RemoveCurrentFromGraph();
2979 return; 2979 return;
2980 } 2980 }
2981 2981
2982 // Check if there is only a single kDynamicCid input to the phi that 2982 // Check if there is only a single kDynamicCid input to the phi that
(...skipping 16 matching lines...) Expand all
2999 if ((non_smi_input == kNotFound) || 2999 if ((non_smi_input == kNotFound) ||
3000 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) { 3000 (phi->block()->PredecessorAt(non_smi_input) != pre_header)) {
3001 return; 3001 return;
3002 } 3002 }
3003 3003
3004 // Host CheckSmi instruction and make this phi smi one. 3004 // Host CheckSmi instruction and make this phi smi one.
3005 Hoist(it, pre_header, current); 3005 Hoist(it, pre_header, current);
3006 3006
3007 // Replace value we are checking with phi's input. Maintain use lists. 3007 // Replace value we are checking with phi's input. Maintain use lists.
3008 Definition* non_smi_input_defn = phi->InputAt(non_smi_input)->definition(); 3008 Definition* non_smi_input_defn = phi->InputAt(non_smi_input)->definition();
3009 current->value()->RemoveFromInputUseList(); 3009 current->value()->RemoveFromUseList();
3010 current->value()->set_definition(non_smi_input_defn); 3010 current->value()->set_definition(non_smi_input_defn);
3011 current->value()->AddToInputUseList(); 3011 non_smi_input_defn->AddInputUse(current->value());
3012 3012
3013 phi->SetPropagatedCid(kSmiCid); 3013 phi->SetPropagatedCid(kSmiCid);
3014 } 3014 }
3015 3015
3016 3016
3017 void LICM::Optimize(FlowGraph* flow_graph) { 3017 void LICM::Optimize(FlowGraph* flow_graph) {
3018 GrowableArray<BlockEntryInstr*> loop_headers; 3018 GrowableArray<BlockEntryInstr*> loop_headers;
3019 flow_graph->ComputeLoops(&loop_headers); 3019 flow_graph->ComputeLoops(&loop_headers);
3020 3020
3021 for (intptr_t i = 0; i < loop_headers.length(); ++i) { 3021 for (intptr_t i = 0; i < loop_headers.length(); ++i) {
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
3534 BlockEntryInstr* pred = block->PredecessorAt(i); 3534 BlockEntryInstr* pred = block->PredecessorAt(i);
3535 ZoneGrowableArray<Definition*>* pred_out_values = 3535 ZoneGrowableArray<Definition*>* pred_out_values =
3536 out_values_[pred->preorder_number()]; 3536 out_values_[pred->preorder_number()];
3537 ASSERT((*pred_out_values)[expr_id] != NULL); 3537 ASSERT((*pred_out_values)[expr_id] != NULL);
3538 3538
3539 // Sets of outgoing values are not linked into use lists so 3539 // Sets of outgoing values are not linked into use lists so
3540 // they might contain values that were replaced and removed 3540 // they might contain values that were replaced and removed
3541 // from the graph by this iteration. 3541 // from the graph by this iteration.
3542 // To prevent using them we additionally mark definitions themselves 3542 // To prevent using them we additionally mark definitions themselves
3543 // as replaced and store a pointer to the replacement. 3543 // as replaced and store a pointer to the replacement.
3544 Value* input = new Value((*pred_out_values)[expr_id]->Replacement()); 3544 Definition* replacement = (*pred_out_values)[expr_id]->Replacement();
3545 Value* input = new Value(replacement);
3545 phi->SetInputAt(i, input); 3546 phi->SetInputAt(i, input);
3546 3547
3547 // TODO(vegorov): add a helper function to handle input insertion. 3548 // TODO(vegorov): add a helper function to handle input insertion.
3548 input->set_instruction(phi); 3549 input->set_instruction(phi);
3549 input->set_use_index(i); 3550 input->set_use_index(i);
3550 input->AddToInputUseList(); 3551 replacement->AddInputUse(input);
3551 } 3552 }
3552 3553
3553 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index()); 3554 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index());
3554 phis_.Add(phi); // Postpone phi insertion until after load forwarding. 3555 phis_.Add(phi); // Postpone phi insertion until after load forwarding.
3555 3556
3556 return phi; 3557 return phi;
3557 } 3558 }
3558 3559
3559 // Iterate over basic blocks and replace exposed loads with incoming 3560 // Iterate over basic blocks and replace exposed loads with incoming
3560 // values. 3561 // values.
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 4606
4606 if (FLAG_trace_constant_propagation) { 4607 if (FLAG_trace_constant_propagation) {
4607 OS::Print("\n==== After constant propagation ====\n"); 4608 OS::Print("\n==== After constant propagation ====\n");
4608 FlowGraphPrinter printer(*graph_); 4609 FlowGraphPrinter printer(*graph_);
4609 printer.PrintBlocks(); 4610 printer.PrintBlocks();
4610 } 4611 }
4611 } 4612 }
4612 4613
4613 4614
4614 } // namespace dart 4615 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698