| 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 #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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 ASSERT((replacement == NULL) || current->IsDefinition()); | 217 ASSERT((replacement == NULL) || current->IsDefinition()); |
| 218 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_); | 218 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_); |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 void FlowGraphOptimizer::InsertConversion(Representation from, | 225 void FlowGraphOptimizer::InsertConversion(Representation from, |
| 226 Representation to, | 226 Representation to, |
| 227 Instruction* instr, | |
| 228 Value* use, | 227 Value* use, |
| 229 Definition* def, | 228 Instruction* insert_before, |
| 230 Instruction* deopt_target) { | 229 Instruction* deopt_target) { |
| 231 Definition* converted = NULL; | 230 Definition* converted = NULL; |
| 232 if ((from == kTagged) && (to == kUnboxedMint)) { | 231 if ((from == kTagged) && (to == kUnboxedMint)) { |
| 232 ASSERT((deopt_target != NULL) || |
| 233 (use->definition()->GetPropagatedCid() == kDoubleCid)); |
| 233 const intptr_t deopt_id = (deopt_target != NULL) ? | 234 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 234 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 235 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 235 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); | 236 converted = new UnboxIntegerInstr(new Value(use->definition()), deopt_id); |
| 236 converted = new UnboxIntegerInstr(new Value(def), deopt_id); | |
| 237 } else if ((from == kUnboxedMint) && (to == kTagged)) { | 237 } else if ((from == kUnboxedMint) && (to == kTagged)) { |
| 238 converted = new BoxIntegerInstr(new Value(def)); | 238 converted = new BoxIntegerInstr(new Value(use->definition())); |
| 239 } else if (from == kUnboxedMint && to == kUnboxedDouble) { | 239 } else if (from == kUnboxedMint && to == kUnboxedDouble) { |
| 240 // Convert by boxing/unboxing. | 240 // Convert by boxing/unboxing. |
| 241 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. | 241 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. |
| 242 BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(def)); | 242 BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(use->definition())); |
| 243 InsertBefore(instr, boxed, NULL, Definition::kValue); | 243 InsertBefore(insert_before, boxed, NULL, Definition::kValue); |
| 244 const intptr_t deopt_id = (deopt_target != NULL) ? | 244 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 245 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 245 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 246 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); | 246 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); |
| 247 } else if ((from == kUnboxedDouble) && (to == kTagged)) { | 247 } else if ((from == kUnboxedDouble) && (to == kTagged)) { |
| 248 converted = new BoxDoubleInstr(new Value(def), NULL); | 248 converted = new BoxDoubleInstr(new Value(use->definition()), NULL); |
| 249 } else if ((from == kTagged) && (to == kUnboxedDouble)) { | 249 } else if ((from == kTagged) && (to == kUnboxedDouble)) { |
| 250 const intptr_t deopt_id = (deopt_target != NULL) ? | 250 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 251 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 251 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 252 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); | 252 ASSERT((deopt_target != NULL) || |
| 253 if (def->IsConstant() && def->AsConstant()->value().IsSmi()) { | 253 (use->definition()->GetPropagatedCid() == kDoubleCid)); |
| 254 const double dbl_val = | 254 ConstantInstr* constant = use->definition()->AsConstant(); |
| 255 Smi::Cast(def->AsConstant()->value()).AsDoubleValue(); | 255 if ((constant != NULL) && constant->value().IsSmi()) { |
| 256 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); |
| 256 const Double& dbl_obj = | 257 const Double& dbl_obj = |
| 257 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); | 258 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); |
| 258 ConstantInstr* double_const = new ConstantInstr(dbl_obj); | 259 ConstantInstr* double_const = new ConstantInstr(dbl_obj); |
| 259 InsertBefore(instr, double_const, NULL, Definition::kValue); | 260 InsertBefore(insert_before, double_const, NULL, Definition::kValue); |
| 260 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); | 261 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); |
| 261 } else { | 262 } else { |
| 262 converted = new UnboxDoubleInstr(new Value(def), deopt_id); | 263 converted = new UnboxDoubleInstr(new Value(use->definition()), deopt_id); |
| 263 } | 264 } |
| 264 } | 265 } |
| 265 ASSERT(converted != NULL); | 266 ASSERT(converted != NULL); |
| 266 InsertBefore(instr, converted, use->instruction()->env(), | 267 InsertBefore(insert_before, converted, use->instruction()->env(), |
| 267 Definition::kValue); | 268 Definition::kValue); |
| 268 use->set_definition(converted); | 269 use->set_definition(converted); |
| 269 } | 270 } |
| 270 | 271 |
| 271 | 272 |
| 272 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { | 273 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { |
| 273 const Representation from_rep = def->representation(); | 274 const Representation from_rep = def->representation(); |
| 274 | 275 |
| 275 for (Value* use = def->input_use_list(); | 276 for (Value::Iterator it(def->input_use_list()); |
| 276 use != NULL; | 277 !it.Done(); |
| 277 use = use->next_use()) { | 278 it.Advance()) { |
| 279 Value* use = it.Current(); |
| 278 const Representation to_rep = | 280 const Representation to_rep = |
| 279 use->instruction()->RequiredInputRepresentation(use->use_index()); | 281 use->instruction()->RequiredInputRepresentation(use->use_index()); |
| 280 if (from_rep == to_rep) { | 282 if (from_rep == to_rep) { |
| 281 continue; | 283 continue; |
| 282 } | 284 } |
| 283 | 285 |
| 284 Instruction* deopt_target = NULL; | 286 Instruction* insert_before; |
| 285 Instruction* instr = use->instruction(); | 287 Instruction* deopt_target; |
| 286 if (instr->IsPhi()) { | 288 PhiInstr* phi = use->instruction()->AsPhi(); |
| 287 if (!instr->AsPhi()->is_alive()) continue; | 289 if (phi != NULL) { |
| 290 if (!phi->is_alive()) continue; |
| 288 | 291 |
| 289 // For phis conversions have to be inserted in the predecessor. | 292 // For phis conversions have to be inserted in the predecessor. |
| 290 const BlockEntryInstr* pred = | 293 insert_before = |
| 291 instr->AsPhi()->block()->PredecessorAt(use->use_index()); | 294 phi->block()->PredecessorAt(use->use_index())->last_instruction(); |
| 292 instr = pred->last_instruction(); | 295 deopt_target = NULL; |
| 293 } else { | 296 } else { |
| 294 deopt_target = instr; | 297 deopt_target = insert_before = use->instruction(); |
| 295 } | 298 } |
| 296 | 299 |
| 297 InsertConversion(from_rep, to_rep, instr, use, def, deopt_target); | 300 InsertConversion(from_rep, to_rep, use, insert_before, deopt_target); |
| 298 } | 301 } |
| 299 } | 302 } |
| 300 | 303 |
| 301 | 304 |
| 302 void FlowGraphOptimizer::SelectRepresentations() { | 305 void FlowGraphOptimizer::SelectRepresentations() { |
| 303 // Convervatively unbox all phis that were proven to be of type Double. | 306 // Convervatively unbox all phis that were proven to be of type Double. |
| 304 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 307 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 305 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); | 308 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); |
| 306 if (join_entry == NULL) continue; | 309 if (join_entry == NULL) continue; |
| 307 | 310 |
| (...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2192 return false; | 2195 return false; |
| 2193 } | 2196 } |
| 2194 | 2197 |
| 2195 return dom_block->Dominates(use_block); | 2198 return dom_block->Dominates(use_block); |
| 2196 } | 2199 } |
| 2197 | 2200 |
| 2198 | 2201 |
| 2199 void RangeAnalysis::RenameDominatedUses(Definition* def, | 2202 void RangeAnalysis::RenameDominatedUses(Definition* def, |
| 2200 Instruction* dom, | 2203 Instruction* dom, |
| 2201 Definition* other) { | 2204 Definition* other) { |
| 2202 Value* next_use = NULL; | 2205 for (Value::Iterator it(def->input_use_list()); |
| 2203 for (Value* use = def->input_use_list(); | 2206 !it.Done(); |
| 2204 use != NULL; | 2207 it.Advance()) { |
| 2205 use = next_use) { | 2208 Value* use = it.Current(); |
| 2206 next_use = use->next_use(); | |
| 2207 | 2209 |
| 2208 // Skip dead phis. | 2210 // Skip dead phis. |
| 2209 PhiInstr* phi = use->instruction()->AsPhi(); | 2211 PhiInstr* phi = use->instruction()->AsPhi(); |
| 2210 if ((phi != NULL) && !phi->is_alive()) continue; | 2212 if ((phi != NULL) && !phi->is_alive()) continue; |
| 2211 | 2213 |
| 2212 if (IsDominatedUse(dom, use)) { | 2214 if (IsDominatedUse(dom, use)) { |
| 2213 use->RemoveFromUseList(); | 2215 use->RemoveFromUseList(); |
| 2214 use->set_definition(other); | 2216 use->set_definition(other); |
| 2215 other->AddInputUse(use); | 2217 other->AddInputUse(use); |
| 2216 } | 2218 } |
| (...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4559 | 4561 |
| 4560 if (FLAG_trace_constant_propagation) { | 4562 if (FLAG_trace_constant_propagation) { |
| 4561 OS::Print("\n==== After constant propagation ====\n"); | 4563 OS::Print("\n==== After constant propagation ====\n"); |
| 4562 FlowGraphPrinter printer(*graph_); | 4564 FlowGraphPrinter printer(*graph_); |
| 4563 printer.PrintBlocks(); | 4565 printer.PrintBlocks(); |
| 4564 } | 4566 } |
| 4565 } | 4567 } |
| 4566 | 4568 |
| 4567 | 4569 |
| 4568 } // namespace dart | 4570 } // namespace dart |
| OLD | NEW |