Index: runtime/vm/intermediate_language_x64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_x64.cc (revision 11450) |
+++ runtime/vm/intermediate_language_x64.cc (working copy) |
@@ -554,9 +554,10 @@ |
Register left = locs.in(0).reg(); |
Register right = locs.in(1).reg(); |
const bool left_is_smi = (branch == NULL) ? |
- false : (branch->left()->ResultCid() == kSmiCid); |
+ false : (branch->computation()->left()->ResultCid() == kSmiCid); |
const bool right_is_smi = (branch == NULL) ? |
- false : (branch->right()->ResultCid() == kSmiCid); |
+ false : (branch->computation()->right()->ResultCid() == kSmiCid); |
+ // TODO(fschneider): Move smi smi checks outside this instruction. |
if (!left_is_smi || !right_is_smi) { |
Register temp = locs.temp(0).reg(); |
Label* deopt = compiler->AddDeoptStub(deopt_id, |
@@ -629,6 +630,7 @@ |
void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
if (receiver_class_id() == kSmiCid) { |
// Deoptimizes if both arguments not Smi. |
EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. |
@@ -651,22 +653,65 @@ |
if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
EmitGenericEqualityCompare(compiler, locs(), kind(), NULL, *ic_data(), |
deopt_id(), token_pos(), try_index()); |
- } else { |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- __ pushq(left); |
- __ pushq(right); |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- try_index(), |
- kind(), |
- locs()); |
- ASSERT(locs()->out().reg() == RAX); |
+ return; |
} |
+ Register left = locs()->in(0).reg(); |
+ Register right = locs()->in(1).reg(); |
+ __ pushq(left); |
+ __ pushq(right); |
+ EmitEqualityAsInstanceCall(compiler, |
+ deopt_id(), |
+ token_pos(), |
+ try_index(), |
+ kind(), |
+ locs()); |
+ ASSERT(locs()->out().reg() == RAX); |
} |
+void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
+ if (receiver_class_id() == kSmiCid) { |
+ // Deoptimizes if both arguments not Smi. |
+ EmitSmiComparisonOp(compiler, *locs(), kind(), branch, |
+ deopt_id(), try_index()); |
+ return; |
+ } |
+ if (receiver_class_id() == kDoubleCid) { |
+ // Deoptimizes if both arguments are Smi, or if none is Double or Smi. |
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, |
+ deopt_id(), try_index()); |
+ return; |
+ } |
+ const bool is_checked_strict_equal = |
+ HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
+ if (is_checked_strict_equal) { |
+ EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, |
+ deopt_id(), try_index()); |
+ return; |
+ } |
+ if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
+ EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), |
+ deopt_id(), token_pos(), try_index()); |
+ return; |
+ } |
+ Register left = locs()->in(0).reg(); |
+ Register right = locs()->in(1).reg(); |
+ __ pushq(left); |
+ __ pushq(right); |
+ EmitEqualityAsInstanceCall(compiler, |
+ deopt_id(), |
+ token_pos(), |
+ try_index(), |
+ Token::kEQ, // kNE reverse occurs at branch. |
+ locs()); |
+ Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
+ __ CompareObject(RAX, compiler->bool_true()); |
+ branch->EmitBranchOnCondition(compiler, branch_condition); |
+} |
+ |
+ |
LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
const intptr_t kNumInputs = 2; |
if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { |
@@ -733,7 +778,6 @@ |
token_pos(), |
try_index(), |
locs()); |
- ASSERT(locs()->out().reg() == RAX); |
return; |
} |
const String& function_name = |
@@ -752,10 +796,27 @@ |
Array::ZoneHandle(), // No optional arguments. |
kNumArgsChecked, |
locs()); |
- ASSERT(locs()->out().reg() == RAX); |
} |
+void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ if (operands_class_id() == kSmiCid) { |
+ EmitSmiComparisonOp(compiler, *locs(), kind(), branch, |
+ deopt_id(), try_index()); |
+ return; |
+ } |
+ if (operands_class_id() == kDoubleCid) { |
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, |
+ deopt_id(), try_index()); |
+ return; |
+ } |
+ EmitNativeCode(compiler); |
+ __ CompareObject(RAX, compiler->bool_true()); |
+ branch->EmitBranchOnCondition(compiler, EQUAL); |
+} |
+ |
+ |
LocationSummary* NativeCallComp::MakeLocationSummary() const { |
const intptr_t kNumInputs = 0; |
const intptr_t kNumTemps = 3; |
@@ -2141,143 +2202,11 @@ |
} |
-// TODO(srdjan): Move to shared. |
-static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { |
- if (ic_data.num_args_tested() != 2) return false; |
- if (ic_data.NumberOfChecks() != 1) return false; |
- Function& target = Function::Handle(); |
- GrowableArray<intptr_t> class_ids; |
- ic_data.GetCheckAt(0, &class_ids, &target); |
- return (class_ids[0] == class_id) && (class_ids[1] == class_id); |
-} |
- |
- |
-static bool IsCheckedStrictEquals(const ICData& ic_data, Token::Kind kind) { |
- if ((kind == Token::kEQ) || (kind == Token::kNE)) { |
- return ic_data.AllTargetsHaveSameOwner(kInstanceCid); |
- } |
- return false; |
-} |
- |
- |
-LocationSummary* BranchInstr::MakeLocationSummary() const { |
- if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
- if (ICDataWithBothClassIds(*ic_data(), kSmiCid) || |
- ICDataWithBothClassIds(*ic_data(), kDoubleCid) || |
- IsCheckedStrictEquals(*ic_data(), kind())) { |
- const intptr_t kNumInputs = 2; |
- const intptr_t kNumTemps = 1; |
- LocationSummary* summary = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- summary->set_in(0, Location::RequiresRegister()); |
- summary->set_in(1, Location::RequiresRegister()); |
- summary->set_temp(0, Location::RequiresRegister()); |
- return summary; |
- } |
- if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { |
- const intptr_t kNumInputs = 2; |
- const intptr_t kNumTemps = 1; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- locs->set_in(0, Location::RegisterLocation(RAX)); |
- locs->set_in(1, Location::RegisterLocation(RCX)); |
- locs->set_temp(0, Location::RegisterLocation(RDX)); |
- return locs; |
- } |
- // Otherwise polymorphic dispatch. |
- } |
- // Call. |
- const intptr_t kNumInputs = 2; |
- const intptr_t kNumTemps = 0; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- locs->set_in(0, Location::RegisterLocation(RAX)); |
- locs->set_in(1, Location::RegisterLocation(RCX)); |
- return locs; |
-} |
- |
- |
void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- // Relational or equality. |
- if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
- if (ICDataWithBothClassIds(*ic_data(), kSmiCid)) { |
- EmitSmiComparisonOp(compiler, *locs(), kind(), this, |
- deopt_id(), try_index()); |
- return; |
- } |
- if (ICDataWithBothClassIds(*ic_data(), kDoubleCid)) { |
- EmitDoubleComparisonOp(compiler, *locs(), kind(), this, |
- deopt_id(), try_index()); |
- return; |
- } |
- if (IsCheckedStrictEquals(*ic_data(), kind())) { |
- EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this, |
- deopt_id(), try_index()); |
- return; |
- } |
- // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. |
- if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { |
- EmitGenericEqualityCompare(compiler, locs(), kind(), this, *ic_data(), |
- deopt_id(), token_pos(), try_index()); |
- return; |
- } |
- // Otherwise polymorphic dispatch? |
- } |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- __ pushq(left); |
- __ pushq(right); |
- if ((kind() == Token::kNE) || (kind() == Token::kEQ)) { |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- try_index(), |
- Token::kEQ, // kNE reverse occurs at branch. |
- locs()); |
- } else { |
- const String& function_name = |
- String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
- compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
- deopt_id(), |
- token_pos(), |
- try_index()); |
- const intptr_t kNumArguments = 2; |
- const intptr_t kNumArgsChecked = 2; // Type-feedback. |
- compiler->GenerateInstanceCall(deopt_id(), |
- token_pos(), |
- try_index(), |
- function_name, |
- kNumArguments, |
- Array::ZoneHandle(), // No optional args. |
- kNumArgsChecked, |
- locs()); |
- } |
- Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
- __ CompareObject(RAX, compiler->bool_true()); |
- EmitBranchOnCondition(compiler, branch_condition); |
+ computation()->EmitBranchCode(compiler, this); |
} |
-LocationSummary* StrictCompareAndBranchInstr::MakeLocationSummary() const { |
- const int kNumInputs = 2; |
- const int kNumTemps = 0; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- locs->set_in(0, Location::RequiresRegister()); |
- locs->set_in(1, Location::RequiresRegister()); |
- return locs; |
-} |
- |
- |
-void StrictCompareAndBranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- __ cmpq(left, right); |
- Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
- EmitBranchOnCondition(compiler, cond); |
-} |
- |
- |
LocationSummary* CheckClassComp::MakeLocationSummary() const { |
const intptr_t kNumInputs = 1; |
const intptr_t kNumTemps = 1; |