Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language.cc (revision 15455) |
| +++ runtime/vm/intermediate_language.cc (working copy) |
| @@ -1472,23 +1472,23 @@ |
| // Optimizations that eliminate or simplify individual instructions. |
| -Instruction* Instruction::Canonicalize() { |
| +Instruction* Instruction::Canonicalize(FlowGraphOptimizer* optimizer) { |
| return this; |
| } |
| -Definition* Definition::Canonicalize() { |
| +Definition* Definition::Canonicalize(FlowGraphOptimizer* optimizer) { |
| return this; |
| } |
| -Definition* AssertBooleanInstr::Canonicalize() { |
| +Definition* AssertBooleanInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| const intptr_t value_cid = value()->ResultCid(); |
| return (value_cid == kBoolCid) ? value()->definition() : this; |
| } |
| -Definition* AssertAssignableInstr::Canonicalize() { |
| +Definition* AssertAssignableInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| // (1) Replace the assert with its input if the input has a known compatible |
| // class-id. The class-ids handled here are those that are known to be |
| // results of IL instructions. |
| @@ -1506,15 +1506,39 @@ |
| // (2) Replace the assert with its input if the input is the result of a |
| // compatible assert itself. |
| AssertAssignableInstr* check = value()->definition()->AsAssertAssignable(); |
| - if ((check != NULL) && (check->dst_type().raw() == dst_type().raw())) { |
| + if ((check != NULL) && |
| + (check->dst_type().Canonicalize() == dst_type().Canonicalize())) { |
|
regis
2012/11/29 16:25:19
Aren't the types canonicalized already? It may be
Florian Schneider
2012/12/04 14:48:04
They are not all canonicalized. For now, I'm using
regis
2012/12/05 19:08:02
"For now"? Please add a TODO.
Why are they not can
|
| // TODO(fschneider): Propagate type-assertions across phi-nodes. |
| // TODO(fschneider): Eliminate more asserts with subtype relation. |
| return check; |
| } |
| + |
| + // (3) For uninstantiated target types: If the instantiator type arguments |
| + // are constant, instantiate the target type here. |
| + if (dst_type().IsInstantiated()) return this; |
| + |
| + ConstantInstr* constant_type_args = |
| + instantiator_type_arguments()->definition()->AsConstant(); |
| + if (constant_type_args != NULL && |
| + !constant_type_args->value().IsNull() && |
| + constant_type_args->value().IsTypeArguments()) { |
| + const TypeArguments& instantiator_type_args = |
| + TypeArguments::Cast(constant_type_args->value()); |
| + const AbstractType& new_dst_type = AbstractType::ZoneHandle( |
| + dst_type().InstantiateFrom(instantiator_type_args)); |
|
regis
2012/11/29 16:25:19
You should canonicalize new_dst_type here.
Florian Schneider
2012/12/04 14:48:04
Done.
|
| + set_dst_type(new_dst_type); |
| + ConstantInstr* null_constant = new ConstantInstr(Object::ZoneHandle()); |
| + // It is ok to insert instructions before the current during |
| + // forward iteration. |
| + optimizer->InsertBefore(this, null_constant, NULL, Definition::kValue); |
| + instantiator_type_arguments()->RemoveFromInputUseList(); |
| + instantiator_type_arguments()->set_definition(null_constant); |
| + instantiator_type_arguments()->AddToInputUseList(); |
| + } |
| return this; |
| } |
| -Definition* StrictCompareInstr::Canonicalize() { |
| +Definition* StrictCompareInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| if (!right()->BindsToConstant()) return this; |
| const Object& right_constant = right()->BoundConstant(); |
| Definition* left_defn = left()->definition(); |
| @@ -1530,7 +1554,7 @@ |
| } |
| -Instruction* CheckClassInstr::Canonicalize() { |
| +Instruction* CheckClassInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| const intptr_t value_cid = value()->ResultCid(); |
| const intptr_t num_checks = unary_checks().NumberOfChecks(); |
| if ((num_checks == 1) && |
| @@ -1542,12 +1566,13 @@ |
| } |
| -Instruction* CheckSmiInstr::Canonicalize() { |
| +Instruction* CheckSmiInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| return (value()->ResultCid() == kSmiCid) ? NULL : this; |
| } |
| -Instruction* CheckEitherNonSmiInstr::Canonicalize() { |
| +Instruction* CheckEitherNonSmiInstr::Canonicalize( |
| + FlowGraphOptimizer* optimizer) { |
| if ((left()->ResultCid() == kDoubleCid) || |
| (right()->ResultCid() == kDoubleCid)) { |
| return NULL; // Remove from the graph. |