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

Unified Diff: runtime/vm/intermediate_language.cc

Issue 59613005: Merge (x & y) == 0 pattern to emit a single test instruction. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language.cc
===================================================================
--- runtime/vm/intermediate_language.cc (revision 29964)
+++ runtime/vm/intermediate_language.cc (working copy)
@@ -760,6 +760,7 @@
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);
}
@@ -781,18 +782,19 @@
}
-void BranchInstr::SetComparison(ComparisonInstr* comp) {
- for (intptr_t i = comp->InputCount() - 1; i >= 0; --i) {
- Value* input = comp->InputAt(i);
+void BranchInstr::SetComparison(ComparisonInstr* new_comparison) {
+ for (intptr_t i = new_comparison->InputCount() - 1; i >= 0; --i) {
+ Value* input = new_comparison->InputAt(i);
input->definition()->AddInputUse(input);
input->set_instruction(this);
}
// There should be no need to copy or unuse an environment.
ASSERT(comparison()->env() == NULL);
+ ASSERT(new_comparison->env() == NULL);
// Remove the current comparison's input uses.
comparison()->UnuseAllInputs();
- ASSERT(!comp->HasUses());
- comparison_ = comp;
+ ASSERT(!new_comparison->HasUses());
+ comparison_ = new_comparison;
}
@@ -1617,6 +1619,25 @@
}
+// Recognize the pattern (a & b) == 0 where left is a bitwise and operation
+// and right is a constant 0.
+static bool RecognizeTestPattern(Value* left, Value* right) {
+ 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(FlowGraph* flow_graph) {
// Only handle strict-compares.
if (comparison()->IsStrictCompare()) {
@@ -1664,6 +1685,29 @@
comp->ClearSSATempIndex();
comp->ClearTempIndex();
}
+ } else if (comparison()->IsEqualityCompare() &&
+ comparison()->operation_cid() == kSmiCid) {
+ 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) {
+ if (FLAG_trace_optimization) {
+ OS::Print("Merging test smi v%" Pd "\n", bit_and->ssa_temp_index());
+ }
+ TestSmiInstr* test = new TestSmiInstr(comparison()->token_pos(),
+ comparison()->kind(),
+ bit_and->left()->Copy(),
+ bit_and->right()->Copy());
+ ASSERT(!CanDeoptimize());
+ RemoveEnvironment();
+ flow_graph->CopyDeoptTarget(this, bit_and);
+ SetComparison(test);
+ bit_and->RemoveFromGraph();
+ }
}
return this;
}

Powered by Google App Engine
This is Rietveld 408576698