Index: runtime/vm/intermediate_language_mips.cc |
=================================================================== |
--- runtime/vm/intermediate_language_mips.cc (revision 29797) |
+++ runtime/vm/intermediate_language_mips.cc (working copy) |
@@ -304,98 +304,11 @@ |
locs->set_out(Location::RequiresRegister()); |
return locs; |
} |
- if (IsCheckedStrictEqual()) { |
- const intptr_t kNumTemps = 1; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
- locs->set_in(0, Location::RequiresRegister()); |
- locs->set_in(1, Location::RequiresRegister()); |
- locs->set_temp(0, Location::RequiresRegister()); |
- locs->set_out(Location::RequiresRegister()); |
- return locs; |
- } |
- if (IsPolymorphic()) { |
- const intptr_t kNumTemps = 1; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- locs->set_in(0, Location::RegisterLocation(A1)); |
- locs->set_in(1, Location::RegisterLocation(A0)); |
- locs->set_temp(0, Location::RegisterLocation(T0)); |
- locs->set_out(Location::RegisterLocation(V0)); |
- return locs; |
- } |
- const intptr_t kNumTemps = 1; |
- LocationSummary* locs = |
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
- locs->set_in(0, Location::RegisterLocation(A1)); |
- locs->set_in(1, Location::RegisterLocation(A0)); |
- locs->set_temp(0, Location::RegisterLocation(T0)); |
- locs->set_out(Location::RegisterLocation(V0)); |
- return locs; |
+ UNREACHABLE(); |
+ return NULL; |
} |
-// A1: left. |
-// A0: right. |
-// Uses T0 to load ic_call_data. |
-// Result in V0. |
-static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, |
- intptr_t deopt_id, |
- intptr_t token_pos, |
- Token::Kind kind, |
- LocationSummary* locs, |
- const ICData& original_ic_data) { |
- if (!compiler->is_optimizing()) { |
- compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
- deopt_id, |
- token_pos); |
- } |
- const int kNumberOfArguments = 2; |
- const Array& kNoArgumentNames = Object::null_array(); |
- const int kNumArgumentsChecked = 2; |
- |
- __ TraceSimMsg("EmitEqualityAsInstanceCall"); |
- __ Comment("EmitEqualityAsInstanceCall"); |
- |
- ICData& equality_ic_data = ICData::ZoneHandle(); |
- if (compiler->is_optimizing() && FLAG_propagate_ic_data) { |
- ASSERT(!original_ic_data.IsNull()); |
- if (original_ic_data.NumberOfChecks() == 0) { |
- // IC call for reoptimization populates original ICData. |
- equality_ic_data = original_ic_data.raw(); |
- } else { |
- // Megamorphic call. |
- equality_ic_data = original_ic_data.AsUnaryClassChecks(); |
- } |
- } else { |
- const Array& arguments_descriptor = |
- Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments, |
- kNoArgumentNames)); |
- equality_ic_data = ICData::New(compiler->parsed_function().function(), |
- Symbols::EqualOperator(), |
- arguments_descriptor, |
- deopt_id, |
- kNumArgumentsChecked); |
- } |
- compiler->GenerateInstanceCall(deopt_id, |
- token_pos, |
- kNumberOfArguments, |
- kNoArgumentNames, |
- locs, |
- equality_ic_data); |
- if (kind == Token::kNE) { |
- Label true_label, done; |
- // Negate the condition: true label returns false and vice versa. |
- __ BranchEqual(V0, Bool::True(), &true_label); |
- __ LoadObject(V0, Bool::True()); |
- __ b(&done); |
- __ Bind(&true_label); |
- __ LoadObject(V0, Bool::False()); |
- __ Bind(&done); |
- } |
-} |
- |
- |
static void LoadValueCid(FlowGraphCompiler* compiler, |
Register value_cid_reg, |
Register value_reg, |
@@ -448,178 +361,6 @@ |
} |
-// A1: left, also on stack. |
-// A0: right, also on stack. |
-static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
- const ICData& orig_ic_data, |
- LocationSummary* locs, |
- BranchInstr* branch, |
- Token::Kind kind, |
- intptr_t deopt_id, |
- intptr_t token_pos) { |
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
- const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); |
- ASSERT(ic_data.NumberOfChecks() > 0); |
- ASSERT(ic_data.num_args_tested() == 1); |
- Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); |
- Register left = locs->in(0).reg(); |
- Register right = locs->in(1).reg(); |
- ASSERT(left == A1); |
- ASSERT(right == A0); |
- Register temp = locs->temp(0).reg(); |
- |
- __ TraceSimMsg("EmitEqualityAsPolymorphicCall"); |
- __ Comment("EmitEqualityAsPolymorphicCall"); |
- |
- LoadValueCid(compiler, temp, left, |
- (ic_data.GetReceiverClassIdAt(0) == kSmiCid) ? NULL : deopt); |
- // 'temp' contains class-id of the left argument. |
- ObjectStore* object_store = Isolate::Current()->object_store(); |
- Condition cond = TokenKindToSmiCondition(kind); |
- Label done; |
- const intptr_t len = ic_data.NumberOfChecks(); |
- for (intptr_t i = 0; i < len; i++) { |
- // Assert that the Smi is at position 0, if at all. |
- ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); |
- Label next_test; |
- if (i < len - 1) { |
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), &next_test); |
- } else { |
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt); |
- } |
- const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
- if (target.Owner() == object_store->object_class()) { |
- // Object.== is same as ===. |
- __ Drop(2); |
- __ slt(CMPRES1, left, right); |
- __ slt(CMPRES2, right, left); |
- if (branch != NULL) { |
- branch->EmitBranchOnCondition(compiler, cond); |
- } else { |
- Register result = locs->out().reg(); |
- Label load_true; |
- EmitBranchAfterCompare(compiler, cond, &load_true); |
- __ LoadObject(result, Bool::False()); |
- __ b(&done); |
- __ Bind(&load_true); |
- __ LoadObject(result, Bool::True()); |
- } |
- } else { |
- const int kNumberOfArguments = 2; |
- const Array& kNoArgumentNames = Object::null_array(); |
- compiler->GenerateStaticCall(deopt_id, |
- token_pos, |
- target, |
- kNumberOfArguments, |
- kNoArgumentNames, |
- locs); |
- if (branch == NULL) { |
- if (kind == Token::kNE) { |
- Label is_true; |
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); |
- __ beq(CMPRES, CMPRES2, &is_true); |
- __ LoadObject(V0, Bool::True()); |
- __ b(&done); |
- __ Bind(&is_true); |
- __ LoadObject(V0, Bool::False()); |
- } |
- } else { |
- if (branch->is_checked()) { |
- EmitAssertBoolean(V0, token_pos, deopt_id, locs, compiler); |
- } |
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); |
- branch->EmitBranchOnCondition(compiler, cond); |
- } |
- } |
- if (i < len - 1) { |
- __ b(&done); |
- __ Bind(&next_test); |
- } |
- } |
- __ Bind(&done); |
-} |
- |
- |
-// Emit code when ICData's targets are all Object == (which is ===). |
-static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, |
- const ICData& orig_ic_data, |
- const LocationSummary& locs, |
- Token::Kind kind, |
- BranchInstr* branch, |
- intptr_t deopt_id) { |
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
- Register left = locs.in(0).reg(); |
- Register right = locs.in(1).reg(); |
- Register temp = locs.temp(0).reg(); |
- Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); |
- |
- __ Comment("CheckedStrictEqual"); |
- |
- __ andi(CMPRES, left, Immediate(kSmiTagMask)); |
- __ beq(CMPRES, ZR, deopt); |
- // 'left' is not Smi. |
- Label identity_compare; |
- __ LoadImmediate(CMPRES1, reinterpret_cast<int32_t>(Object::null())); |
- __ beq(right, CMPRES1, &identity_compare); |
- __ beq(left, CMPRES1, &identity_compare); |
- |
- __ LoadClassId(temp, left); |
- const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); |
- const intptr_t len = ic_data.NumberOfChecks(); |
- for (intptr_t i = 0; i < len; i++) { |
- if (i == (len - 1)) { |
- __ BranchNotEqual(temp, ic_data.GetReceiverClassIdAt(i), deopt); |
- } else { |
- __ BranchEqual(temp, ic_data.GetReceiverClassIdAt(i), &identity_compare); |
- } |
- } |
- __ Bind(&identity_compare); |
- __ subu(CMPRES1, left, right); |
- if (branch == NULL) { |
- Label done, is_equal; |
- Register result = locs.out().reg(); |
- __ beq(CMPRES, ZR, &is_equal); |
- // Not equal. |
- __ LoadObject(result, Bool::Get(kind != Token::kEQ)); |
- __ b(&done); |
- __ Bind(&is_equal); |
- __ LoadObject(result, Bool::Get(kind == Token::kEQ)); |
- __ Bind(&done); |
- |
- } else { |
- Condition cond = TokenKindToSmiCondition(kind); |
- __ mov(CMPRES2, ZR); |
- branch->EmitBranchOnCondition(compiler, cond); |
- } |
-} |
- |
- |
-// First test if receiver is NULL, in which case === is applied. |
-// If type feedback was provided (lists of <class-id, target>), do a |
-// type by type check (either === or static call to the operator. |
-static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, |
- LocationSummary* locs, |
- Token::Kind kind, |
- BranchInstr* branch, |
- const ICData& ic_data, |
- intptr_t deopt_id, |
- intptr_t token_pos) { |
- ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
- ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
- Register left = locs->in(0).reg(); |
- Register right = locs->in(1).reg(); |
- __ TraceSimMsg("EmitGenericEqualityCompare"); |
- __ Comment("EmitGenericEqualityCompare"); |
- ASSERT(left == A1); |
- ASSERT(right == A0); |
- __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
- __ sw(A1, Address(SP, 1 * kWordSize)); |
- __ sw(A0, Address(SP, 0 * kWordSize)); |
- EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, |
- deopt_id, token_pos); |
-} |
- |
- |
static Condition FlipCondition(Condition condition) { |
switch (condition) { |
case EQ: return EQ; |
@@ -739,30 +480,7 @@ |
EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch); |
return; |
} |
- if (IsCheckedStrictEqual()) { |
- EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, |
- deopt_id()); |
- return; |
- } |
- if (IsPolymorphic()) { |
- EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), |
- deopt_id(), token_pos()); |
- return; |
- } |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- ASSERT(left == A1); |
- ASSERT(right == A0); |
- __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
- __ sw(A1, Address(SP, 1 * kWordSize)); |
- __ sw(A0, Address(SP, 0 * kWordSize)); |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- kind(), |
- locs(), |
- *ic_data()); |
- ASSERT(locs()->out().reg() == V0); |
+ UNREACHABLE(); |
} |
@@ -784,35 +502,7 @@ |
EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); |
return; |
} |
- if (IsCheckedStrictEqual()) { |
- EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, |
- deopt_id()); |
- return; |
- } |
- if (IsPolymorphic()) { |
- EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), |
- deopt_id(), token_pos()); |
- return; |
- } |
- Register left = locs()->in(0).reg(); |
- Register right = locs()->in(1).reg(); |
- ASSERT(left == A1); |
- ASSERT(right == A0); |
- __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
- __ sw(A1, Address(SP, 1 * kWordSize)); |
- __ sw(A0, Address(SP, 0 * kWordSize)); |
- EmitEqualityAsInstanceCall(compiler, |
- deopt_id(), |
- token_pos(), |
- Token::kEQ, // kNE reverse occurs at branch. |
- locs(), |
- *ic_data()); |
- if (branch->is_checked()) { |
- EmitAssertBoolean(V0, token_pos(), deopt_id(), locs(), compiler); |
- } |
- Condition branch_condition = (kind() == Token::kNE) ? NE : EQ; |
- __ CompareObject(CMPRES1, CMPRES2, V0, Bool::True()); |
- branch->EmitBranchOnCondition(compiler, branch_condition); |
+ UNREACHABLE(); |
} |