Add immediate operand support for indexed operations.

The value and/or the index of indexed loads/stores can
be emitted as immediate operands to reduce the number
of registers needed when constants are used.
Review URL: https://chromiumcodereview.appspot.com//10933045

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12265 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
fschneider@google.com 2012-09-12 13:49:12 +00:00
parent 26a215b25a
commit a52116f4af
3 changed files with 105 additions and 37 deletions

View file

@ -1543,6 +1543,7 @@ void Assembler::StoreObject(const Address& dst, const Object& object) {
if (object.IsSmi() || object.IsNull()) {
movq(dst, Immediate(reinterpret_cast<int64_t>(object.raw())));
} else {
ASSERT(object.IsOld());
LoadObject(TMP, object);
movq(dst, TMP);
}

View file

@ -864,22 +864,43 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
static bool CanBeImmediateIndex(Value* index) {
if (!index->definition()->IsConstant()) return false;
const Object& constant = index->definition()->AsConstant()->value();
const Smi& smi_const = Smi::Cast(constant);
int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray);
return Utils::IsInt(32, disp);
}
LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
return LocationSummary::Make(kNumInputs,
Location::RequiresRegister(),
LocationSummary::kNoCall);
const intptr_t kNumTemps = 0;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
locs->set_in(0, Location::RequiresRegister());
locs->set_in(1, CanBeImmediateIndex(index())
? Location::RegisterOrConstant(index())
: Location::RequiresRegister());
locs->set_out(Location::RequiresRegister());
return locs;
}
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register array = locs()->in(0).reg();
Register index = locs()->in(1).reg();
Register result = locs()->out().reg();
// Note that index is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1);
__ movl(result, FieldAddress(array, index, TIMES_2, sizeof(RawArray)));
Location index = locs()->in(1);
if (index.IsRegister()) {
// Note that index is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1);
__ movl(result,
FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray)));
} else {
const int32_t disp =
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray);
__ movl(result, FieldAddress(array, disp));
}
}
@ -889,28 +910,39 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
locs->set_in(0, Location::RequiresRegister());
locs->set_in(1, Location::RequiresRegister());
locs->set_in(2, value()->NeedsStoreBuffer() ? Location::WritableRegister()
: Location::RequiresRegister());
locs->set_in(1, CanBeImmediateIndex(index())
? Location::RegisterOrConstant(index())
: Location::RequiresRegister());
locs->set_in(2, value()->NeedsStoreBuffer()
? Location::WritableRegister()
: Location::RegisterOrConstant(value()));
return locs;
}
void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register array = locs()->in(0).reg();
Register index = locs()->in(1).reg();
Register value = locs()->in(2).reg();
// Note that index is Smi, i.e, times 2.
ASSERT(kSmiTagShift == 1);
Location index = locs()->in(1);
FieldAddress field_address = index.IsConstant()
? FieldAddress(
array,
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray))
: FieldAddress(array, index.reg(), TIMES_2, sizeof(RawArray));
if (this->value()->NeedsStoreBuffer()) {
__ StoreIntoObject(array,
FieldAddress(array, index, TIMES_2, sizeof(RawArray)),
value);
Register value = locs()->in(2).reg();
__ StoreIntoObject(array, field_address, value);
} else {
__ StoreIntoObjectNoBarrier(array,
FieldAddress(array, index, TIMES_2, sizeof(RawArray)),
value);
if (locs()->in(2).IsConstant()) {
const Object& constant = locs()->in(2).constant();
__ StoreIntoObjectNoBarrier(array, field_address, constant);
} else {
Register value = locs()->in(2).reg();
__ StoreIntoObjectNoBarrier(array, field_address, value);
}
}
}

View file

@ -880,22 +880,45 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
}
static bool CanBeImmediateIndex(Value* index) {
if (!index->definition()->IsConstant()) return false;
const Object& constant = index->definition()->AsConstant()->value();
const Smi& smi_const = Smi::Cast(constant);
int64_t disp = smi_const.AsInt64Value() * kWordSize + sizeof(RawArray);
return Utils::IsInt(32, disp);
}
LocationSummary* LoadIndexedInstr::MakeLocationSummary() const {
const intptr_t kNumInputs = 2;
return LocationSummary::Make(kNumInputs,
Location::RequiresRegister(),
LocationSummary::kNoCall);
const intptr_t kNumTemps = 0;
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
locs->set_in(0, Location::RequiresRegister());
locs->set_in(1, CanBeImmediateIndex(index())
? Location::RegisterOrConstant(index())
: Location::RequiresRegister());
locs->set_out(Location::RequiresRegister());
return locs;
}
void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register array = locs()->in(0).reg();
Register index = locs()->in(1).reg();
Register result = locs()->out().reg();
// Note that index is Smi, i.e, times 4.
ASSERT(kSmiTagShift == 1);
__ movq(result, FieldAddress(array, index, TIMES_4, sizeof(RawArray)));
Location index = locs()->in(1);
if (index.IsRegister()) {
// Note that index is Smi, i.e, times 4.
ASSERT(kSmiTagShift == 1);
__ movq(result,
FieldAddress(array, index.reg(), TIMES_4, sizeof(RawArray)));
} else {
const int64_t disp =
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray);
ASSERT(Utils::IsInt(32, disp));
__ movq(result, FieldAddress(array, static_cast<int32_t>(disp)));
}
}
@ -905,28 +928,40 @@ LocationSummary* StoreIndexedInstr::MakeLocationSummary() const {
LocationSummary* locs =
new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
locs->set_in(0, Location::RequiresRegister());
locs->set_in(1, Location::RequiresRegister());
locs->set_in(2, value()->NeedsStoreBuffer() ? Location::WritableRegister()
: Location::RequiresRegister());
locs->set_in(1, CanBeImmediateIndex(index())
? Location::RegisterOrConstant(index())
: Location::RequiresRegister());
locs->set_in(2, value()->NeedsStoreBuffer()
? Location::WritableRegister()
: Location::RegisterOrConstant(value()));
return locs;
}
void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register array = locs()->in(0).reg();
Register index = locs()->in(1).reg();
Register value = locs()->in(2).reg();
// Note that index is Smi, i.e, times 4.
ASSERT(kSmiTagShift == 1);
Location index = locs()->in(1);
FieldAddress field_address = index.IsConstant()
? FieldAddress(
array,
static_cast<int32_t>(
Smi::Cast(index.constant()).Value() * kWordSize + sizeof(RawArray)))
: FieldAddress(array, index.reg(), TIMES_4, sizeof(RawArray));
if (this->value()->NeedsStoreBuffer()) {
__ StoreIntoObject(array,
FieldAddress(array, index, TIMES_4, sizeof(RawArray)),
value);
Register value = locs()->in(2).reg();
__ StoreIntoObject(array, field_address, value);
} else {
__ StoreIntoObjectNoBarrier(array,
FieldAddress(array, index, TIMES_4, sizeof(RawArray)),
value);
if (locs()->in(2).IsConstant()) {
const Object& constant = locs()->in(2).constant();
__ StoreObject(field_address, constant);
} else {
Register value = locs()->in(2).reg();
__ StoreIntoObjectNoBarrier(array, field_address, value);
}
}
}