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

Unified Diff: runtime/vm/intermediate_language_arm.cc

Issue 15697009: Enable code optimization on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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 | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/stub_code_arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_arm.cc
===================================================================
--- runtime/vm/intermediate_language_arm.cc (revision 23031)
+++ runtime/vm/intermediate_language_arm.cc (working copy)
@@ -339,7 +339,10 @@
const intptr_t kNumTemps = 1;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
- UNIMPLEMENTED(); // TODO(regis): Verify register allocation.
+ locs->set_in(0, Location::RegisterLocation(R1));
+ locs->set_in(1, Location::RegisterLocation(R0));
+ locs->set_temp(0, Location::RegisterLocation(R5));
+ locs->set_out(Location::RegisterLocation(R0));
return locs;
}
const intptr_t kNumTemps = 1;
@@ -457,6 +460,104 @@
}
+static Condition NegateCondition(Condition condition) {
+ switch (condition) {
+ case EQ: return NE;
+ case NE: return EQ;
+ case LT: return GE;
+ case LE: return GT;
+ case GT: return LE;
+ case GE: return LT;
+ case CC: return CS;
+ case LS: return HI;
+ case HI: return LS;
+ case CS: return CC;
+ default:
+ UNIMPLEMENTED();
+ return EQ;
+ }
+}
+
+
+// R1: left.
+// R0: right.
+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 == R1);
+ ASSERT(right == R0);
+ Register temp = locs->temp(0).reg();
+ 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;
+ __ CompareImmediate(temp, ic_data.GetReceiverClassIdAt(i));
+ if (i < len - 1) {
+ __ b(&next_test, NE);
+ } else {
+ __ b(deopt, NE);
+ }
+ const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
+ if (target.Owner() == object_store->object_class()) {
+ // Object.== is same as ===.
+ __ cmp(left, ShifterOperand(right));
+ if (branch != NULL) {
+ branch->EmitBranchOnCondition(compiler, cond);
+ } else {
+ Register result = locs->out().reg();
+ __ LoadObject(result, Bool::True(), cond);
+ __ LoadObject(result, Bool::False(), NegateCondition(cond));
+ }
+ } else {
+ const int kNumberOfArguments = 2;
+ const Array& kNoArgumentNames = Array::Handle();
+ compiler->GenerateStaticCall(deopt_id,
+ token_pos,
+ target,
+ kNumberOfArguments,
+ kNoArgumentNames,
+ locs);
+ if (branch == NULL) {
+ if (kind == Token::kNE) {
+ __ CompareObject(R0, Bool::True());
+ __ LoadObject(R0, Bool::True(), NE);
+ __ LoadObject(R0, Bool::False(), EQ);
+ }
+ } else {
+ if (branch->is_checked()) {
+ EmitAssertBoolean(R0, token_pos, deopt_id, locs, compiler);
+ }
+ __ CompareObject(R0, 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& ic_data,
@@ -478,26 +579,38 @@
const ICData& ic_data,
intptr_t deopt_id,
intptr_t token_pos) {
- UNIMPLEMENTED();
-}
-
-
-static Condition NegateCondition(Condition condition) {
- switch (condition) {
- case EQ: return NE;
- case NE: return EQ;
- case LT: return GE;
- case LE: return GT;
- case GT: return LE;
- case GE: return LT;
- case CC: return CS;
- case LS: return HI;
- case HI: return LS;
- case CS: return CC;
- default:
- UNIMPLEMENTED();
- return EQ;
+ 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();
+ Label done, identity_compare, non_null_compare;
+ __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
+ __ cmp(right, ShifterOperand(IP));
+ __ b(&identity_compare, EQ);
+ __ cmp(left, ShifterOperand(IP));
+ __ b(&non_null_compare, NE);
+ // Comparison with NULL is "===".
+ __ Bind(&identity_compare);
+ __ cmp(left, ShifterOperand(right));
+ Condition cond = TokenKindToSmiCondition(kind);
+ if (branch != NULL) {
+ branch->EmitBranchOnCondition(compiler, cond);
+ } else {
+ Register result = locs->out().reg();
+ Label load_true;
+ __ b(&load_true, cond);
+ __ LoadObject(result, Bool::False());
+ __ b(&done);
+ __ Bind(&load_true);
+ __ LoadObject(result, Bool::True());
}
+ __ b(&done);
+ __ Bind(&non_null_compare); // Receiver is not null.
+ ASSERT(left == R1);
+ ASSERT(right == R0);
+ EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
+ deopt_id, token_pos);
+ __ Bind(&done);
}
@@ -845,13 +958,25 @@
LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 1;
+ return LocationSummary::Make(kNumInputs,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall);
}
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ Register object = locs()->in(0).reg();
+ Register result = locs()->out().reg();
+ Label load, done;
+ __ tst(object, ShifterOperand(kSmiTagMask));
+ __ b(&load, NE);
+ __ LoadImmediate(result, Smi::RawValue(kSmiCid));
+ __ b(&done);
+ __ Bind(&load);
+ __ LoadClassId(result, object);
+ __ SmiTag(result);
+ __ Bind(&done);
}
@@ -992,9 +1117,6 @@
}
Register result = locs()->out().reg();
- if ((index_scale() == 1) && index.IsRegister()) {
- __ SmiUntag(index.reg());
- }
switch (class_id()) {
case kTypedDataInt8ArrayCid:
ASSERT(index_scale() == 1);
@@ -1105,7 +1227,7 @@
case kTypedDataUint16ArrayCid:
case kTypedDataInt32ArrayCid:
case kTypedDataUint32ArrayCid:
- locs->set_in(2, Location::RequiresRegister());
+ locs->set_in(2, Location::WritableRegister());
break;
case kTypedDataFloat32ArrayCid:
// TODO(regis): Verify.
@@ -1479,13 +1601,29 @@
LocationSummary* InstanceOfInstr::MakeLocationSummary() const {
- UNIMPLEMENTED();
- return NULL;
+ const intptr_t kNumInputs = 3;
+ const intptr_t kNumTemps = 0;
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+ summary->set_in(0, Location::RegisterLocation(R0));
+ summary->set_in(1, Location::RegisterLocation(R2));
+ summary->set_in(2, Location::RegisterLocation(R1));
+ summary->set_out(Location::RegisterLocation(R0));
+ return summary;
}
void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
+ ASSERT(locs()->in(0).reg() == R0); // Value.
+ ASSERT(locs()->in(1).reg() == R2); // Instantiator.
+ ASSERT(locs()->in(2).reg() == R1); // Instantiator type arguments.
+
+ compiler->GenerateInstanceOf(token_pos(),
+ deopt_id(),
+ type(),
+ negate_result(),
+ locs());
+ ASSERT(locs()->out().reg() == R0);
}
@@ -1935,9 +2073,13 @@
}
case Token::kMUL: {
__ SmiUntag(left);
- __ mul(result, left, right);
- if (deopt != NULL) {
- UNIMPLEMENTED();
+ if (deopt == NULL) {
+ __ mul(result, left, right);
+ } else {
+ __ smull(result, IP, left, right);
+ // IP: result bits 32..63.
+ __ cmp(IP, ShifterOperand(result, ASR, 31));
+ __ b(deopt, NE);
}
break;
}
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/stub_code_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698