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

Unified Diff: src/compiler/ia32/instruction-selector-ia32.cc

Issue 639123009: Classes: Add basic support for properties (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: git rebase Created 6 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/instruction.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index ba7425dd0bc3f7cfee033cd8d3bd7b329fc7086b..ca4bf1ba16f33ffd6bc7bd99fb3c32252b6b949a 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -469,10 +469,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
void InstructionSelector::VisitInt32MulHigh(Node* node) {
IA32OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(eax)};
- size_t temp_count = arraysize(temps);
Emit(kIA32ImulHigh, g.DefineAsFixed(node, edx),
- g.UseFixed(node->InputAt(0), eax), g.UseRegister(node->InputAt(1)),
- temp_count, temps);
+ g.UseFixed(node->InputAt(0), eax), g.UseUniqueRegister(node->InputAt(1)),
+ arraysize(temps), temps);
}
@@ -647,12 +646,12 @@ void InstructionSelector::VisitCall(Node* node) {
}
+namespace {
+
// Shared routine for multiple compare operations.
-static inline void VisitCompare(InstructionSelector* selector,
- InstructionCode opcode,
- InstructionOperand* left,
- InstructionOperand* right,
- FlagsContinuation* cont) {
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+ InstructionOperand* left, InstructionOperand* right,
+ FlagsContinuation* cont) {
IA32OperandGenerator g(selector);
if (cont->IsBranch()) {
selector->Emit(cont->Encode(opcode), NULL, left, right,
@@ -667,90 +666,92 @@ static inline void VisitCompare(InstructionSelector* selector,
}
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+ Node* left, Node* right, FlagsContinuation* cont,
+ bool commutative) {
+ IA32OperandGenerator g(selector);
+ if (commutative && g.CanBeBetterLeftOperand(right)) {
+ std::swap(left, right);
+ }
+ VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
+}
+
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+ FlagsContinuation* cont) {
+ VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
+ cont, node->op()->HasProperty(Operator::kCommutative));
+}
+
+
// Shared routine for multiple word compare operations.
-static inline void VisitWordCompare(InstructionSelector* selector, Node* node,
- InstructionCode opcode,
- FlagsContinuation* cont, bool commutative) {
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+ InstructionCode opcode, FlagsContinuation* cont) {
IA32OperandGenerator g(selector);
- Node* left = node->InputAt(0);
- Node* right = node->InputAt(1);
+ Node* const left = node->InputAt(0);
+ Node* const right = node->InputAt(1);
// Match immediates on left or right side of comparison.
if (g.CanBeImmediate(right)) {
VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
} else if (g.CanBeImmediate(left)) {
- if (!commutative) cont->Commute();
+ if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
} else {
- VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
+ VisitCompare(selector, opcode, left, right, cont,
+ node->op()->HasProperty(Operator::kCommutative));
}
}
-// Shared routine for multiple float compare operations.
-static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
- FlagsContinuation* cont) {
- IA32OperandGenerator g(selector);
- Node* left = node->InputAt(0);
- Node* right = node->InputAt(1);
- VisitCompare(selector, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right),
- cont);
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+ FlagsContinuation* cont) {
+ VisitWordCompare(selector, node, kIA32Cmp, cont);
}
-void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
- BasicBlock* fbranch) {
- IA32OperandGenerator g(this);
- Node* user = branch;
- Node* value = branch->InputAt(0);
-
- FlagsContinuation cont(kNotEqual, tbranch, fbranch);
-
- // If we can fall through to the true block, invert the branch.
- if (IsNextInAssemblyOrder(tbranch)) {
- cont.Negate();
- cont.SwapBlocks();
- }
-
- // Try to combine with comparisons against 0 by simply inverting the branch.
- while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
- Int32BinopMatcher m(value);
- if (m.right().Is(0)) {
- user = value;
- value = m.left().node();
- cont.Negate();
- } else {
- break;
- }
- }
-
+// Shared routine for word comparison with zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+ Node* value, FlagsContinuation* cont) {
// Try to combine the branch with a comparison.
- if (CanCover(user, value)) {
+ while (selector->CanCover(user, value)) {
switch (value->opcode()) {
- case IrOpcode::kWord32Equal:
- cont.OverwriteAndNegateIfEqual(kEqual);
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ case IrOpcode::kWord32Equal: {
+ // Try to combine with comparisons against 0 by simply inverting the
+ // continuation.
+ Int32BinopMatcher m(value);
+ if (m.right().Is(0)) {
+ user = value;
+ value = m.left().node();
+ cont->Negate();
+ continue;
+ }
+ cont->OverwriteAndNegateIfEqual(kEqual);
+ return VisitWordCompare(selector, value, cont);
+ }
case IrOpcode::kInt32LessThan:
- cont.OverwriteAndNegateIfEqual(kSignedLessThan);
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kInt32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kUint32LessThan:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kUint32LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kFloat64Equal:
- cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThan:
- cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kFloat64LessThanOrEqual:
- cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
- return VisitFloat64Compare(this, value, &cont);
+ cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+ return VisitFloat64Compare(selector, value, cont);
case IrOpcode::kProjection:
// Check if this is the overflow output projection of an
// <Operation>WithOverflow node.
@@ -762,14 +763,14 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
// *AFTER* this branch).
Node* node = value->InputAt(0);
Node* result = node->FindProjection(0);
- if (result == NULL || IsDefined(result)) {
+ if (result == NULL || selector->IsDefined(result)) {
switch (node->opcode()) {
case IrOpcode::kInt32AddWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(this, node, kIA32Add, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop(selector, node, kIA32Add, cont);
case IrOpcode::kInt32SubWithOverflow:
- cont.OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(this, node, kIA32Sub, &cont);
+ cont->OverwriteAndNegateIfEqual(kOverflow);
+ return VisitBinop(selector, node, kIA32Sub, cont);
default:
break;
}
@@ -777,61 +778,65 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
}
break;
case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
+ return VisitWordCompare(selector, value, cont);
case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kIA32Test, &cont, true);
+ return VisitWordCompare(selector, value, kIA32Test, cont);
default:
break;
}
+ break;
}
- // Branch could not be combined with a compare, emit compare against 0.
- VisitCompare(this, kIA32Cmp, g.Use(value), g.TempImmediate(0), &cont);
+ // Continuation could not be combined with a compare, emit compare against 0.
+ IA32OperandGenerator g(selector);
+ VisitCompare(selector, kIA32Cmp, g.Use(value), g.TempImmediate(0), cont);
+}
+
+} // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+ BasicBlock* fbranch) {
+ FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+ if (IsNextInAssemblyOrder(tbranch)) { // We can fallthru to the true block.
+ cont.Negate();
+ cont.SwapBlocks();
+ }
+ VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
}
void InstructionSelector::VisitWord32Equal(Node* const node) {
- Node* const user = node;
FlagsContinuation cont(kEqual, node);
- Int32BinopMatcher m(user);
+ Int32BinopMatcher m(node);
if (m.right().Is(0)) {
- Node* const value = m.left().node();
- if (CanCover(user, value)) {
- switch (value->opcode()) {
- case IrOpcode::kInt32Sub:
- return VisitWordCompare(this, value, kIA32Cmp, &cont, false);
- case IrOpcode::kWord32And:
- return VisitWordCompare(this, value, kIA32Test, &cont, true);
- default:
- break;
- }
- }
+ return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
}
- return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
+ VisitWordCompare(this, node, &cont);
}
void InstructionSelector::VisitInt32LessThan(Node* node) {
FlagsContinuation cont(kSignedLessThan, node);
- return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
+ VisitWordCompare(this, node, &cont);
}
void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
FlagsContinuation cont(kSignedLessThanOrEqual, node);
- return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
+ VisitWordCompare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThan(Node* node) {
FlagsContinuation cont(kUnsignedLessThan, node);
- return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
+ VisitWordCompare(this, node, &cont);
}
void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
- return VisitWordCompare(this, node, kIA32Cmp, &cont, false);
+ VisitWordCompare(this, node, &cont);
}
@@ -872,6 +877,12 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
VisitFloat64Compare(this, node, &cont);
}
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+ return MachineOperatorBuilder::Flag::kNoFlags;
+}
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/ia32/code-generator-ia32.cc ('k') | src/compiler/instruction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698