Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc |
| index 0c64c347fe51721707a272bef7e638cfb00ed102..702cbc8624e600d33733b027e613f5a6ff01abe0 100644 |
| --- a/runtime/vm/intermediate_language.cc |
| +++ b/runtime/vm/intermediate_language.cc |
| @@ -607,6 +607,7 @@ BranchInstr::BranchInstr(ComparisonInstr* comparison, bool is_checked) |
| is_checked_(is_checked), |
| constrained_type_(NULL), |
| constant_target_(NULL) { |
| + ASSERT(comparison->env() == NULL); |
| for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { |
| comparison->InputAt(i)->set_instruction(this); |
| } |
| @@ -636,6 +637,7 @@ void BranchInstr::SetComparison(ComparisonInstr* comp) { |
| } |
| // There should be no need to copy or unuse an environment. |
| ASSERT(comparison()->env() == NULL); |
| + ASSERT(comp->env() == NULL); |
| // Remove the current comparison's input uses. |
|
srdjan
2013/04/15 20:27:27
Would be probable more readable if CompareInstr* w
Vyacheslav Egorov (Google)
2013/04/16 11:51:16
I think instr is somewhat confusing as well. I ren
|
| comparison()->UnuseAllInputs(); |
| ASSERT(!comp->HasUses()); |
| @@ -1233,6 +1235,23 @@ Definition* AssertAssignableInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| } |
| +static bool RecognizeTestPattern(Value* left, Value* right) { |
|
srdjan
2013/04/15 20:27:27
Add comment what pattern is being recognized.
Vyacheslav Egorov (Google)
2013/04/16 11:51:16
Done.
|
| + if (!right->BindsToConstant()) { |
| + return false; |
| + } |
| + |
| + const Object& value = right->BoundConstant(); |
| + if (!value.IsSmi() || (Smi::Cast(value).Value() != 0)) { |
| + return false; |
| + } |
| + |
| + Definition* left_defn = left->definition(); |
| + return left_defn->IsBinarySmiOp() && |
| + (left_defn->AsBinarySmiOp()->op_kind() == Token::kBIT_AND) && |
| + left_defn->HasOnlyUse(left); |
| +} |
| + |
| + |
| Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| // Only handle strict-compares. |
| if (comparison()->IsStrictCompare()) { |
| @@ -1261,6 +1280,7 @@ Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| RemoveEnvironment(); |
| InheritDeoptTarget(comp); |
| + comp->RemoveEnvironment(); |
| comp->RemoveFromGraph(); |
| SetComparison(comp); |
| if (FLAG_trace_optimization) { |
| @@ -1272,6 +1292,25 @@ Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| comp->ClearSSATempIndex(); |
| comp->ClearTempIndex(); |
| } |
| + } else if (comparison()->IsSmiEquality()) { |
| + BinarySmiOpInstr* bit_and = NULL; |
| + if (RecognizeTestPattern(comparison()->left(), comparison()->right())) { |
| + bit_and = comparison()->left()->definition()->AsBinarySmiOp(); |
| + } else if (RecognizeTestPattern(comparison()->right(), |
| + comparison()->left())) { |
| + bit_and = comparison()->right()->definition()->AsBinarySmiOp(); |
| + } |
| + |
| + if (bit_and != NULL) { |
| + TestSmiInstr* test = new TestSmiInstr(comparison()->kind(), |
| + bit_and->left()->Copy(), |
| + bit_and->right()->Copy()); |
| + ASSERT(!CanDeoptimize()); |
| + InheritDeoptTarget(bit_and); |
| + RemoveEnvironment(); |
| + SetComparison(test); |
| + bit_and->RemoveFromGraph(); |
| + } |
| } |
| return this; |
| } |