MIPS: Improve register allocation for Lithium representation changes on ARM
Port r10538 (21c5dc1). MIPS-specific changes: -moved MacroAssembler::SmiTagCheckOverflow definition to macro-assembler-mips.cc from the header -added optimized 3-argument version of said function -removed the related, completely unused TrySmiTag function BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9296045 Patch from Daniel Kalmar <kalmard@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10567 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
5dc4859fa4
commit
ab5d47ef21
@ -3714,13 +3714,12 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
|||||||
LNumberTagI* instr_;
|
LNumberTagI* instr_;
|
||||||
};
|
};
|
||||||
|
|
||||||
LOperand* input = instr->InputAt(0);
|
Register src = ToRegister(instr->InputAt(0));
|
||||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
Register dst = ToRegister(instr->result());
|
||||||
Register reg = ToRegister(input);
|
|
||||||
Register overflow = scratch0();
|
Register overflow = scratch0();
|
||||||
|
|
||||||
DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
|
DeferredNumberTagI* deferred = new DeferredNumberTagI(this, instr);
|
||||||
__ SmiTagCheckOverflow(reg, overflow);
|
__ SmiTagCheckOverflow(dst, src, overflow);
|
||||||
__ BranchOnOverflow(deferred->entry(), overflow);
|
__ BranchOnOverflow(deferred->entry(), overflow);
|
||||||
__ bind(deferred->exit());
|
__ bind(deferred->exit());
|
||||||
}
|
}
|
||||||
@ -3728,7 +3727,8 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
|
|||||||
|
|
||||||
void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
|
void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
|
||||||
Label slow;
|
Label slow;
|
||||||
Register reg = ToRegister(instr->InputAt(0));
|
Register src = ToRegister(instr->InputAt(0));
|
||||||
|
Register dst = ToRegister(instr->result());
|
||||||
FPURegister dbl_scratch = double_scratch0();
|
FPURegister dbl_scratch = double_scratch0();
|
||||||
|
|
||||||
// Preserve the value of all registers.
|
// Preserve the value of all registers.
|
||||||
@ -3738,14 +3738,16 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
|
|||||||
// disagree. Try to allocate a heap number in new space and store
|
// disagree. Try to allocate a heap number in new space and store
|
||||||
// the value in there. If that fails, call the runtime system.
|
// the value in there. If that fails, call the runtime system.
|
||||||
Label done;
|
Label done;
|
||||||
__ SmiUntag(reg);
|
if (dst.is(src)) {
|
||||||
__ Xor(reg, reg, Operand(0x80000000));
|
__ SmiUntag(src, dst);
|
||||||
__ mtc1(reg, dbl_scratch);
|
__ Xor(src, src, Operand(0x80000000));
|
||||||
|
}
|
||||||
|
__ mtc1(src, dbl_scratch);
|
||||||
__ cvt_d_w(dbl_scratch, dbl_scratch);
|
__ cvt_d_w(dbl_scratch, dbl_scratch);
|
||||||
if (FLAG_inline_new) {
|
if (FLAG_inline_new) {
|
||||||
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
|
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
|
||||||
__ AllocateHeapNumber(t1, a3, t0, t2, &slow);
|
__ AllocateHeapNumber(t1, a3, t0, t2, &slow);
|
||||||
if (!reg.is(t1)) __ mov(reg, t1);
|
__ Move(dst, t1);
|
||||||
__ Branch(&done);
|
__ Branch(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3755,15 +3757,16 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
|
|||||||
// TODO(3095996): Put a valid pointer value in the stack slot where the result
|
// TODO(3095996): Put a valid pointer value in the stack slot where the result
|
||||||
// register is stored, as this register is in the pointer map, but contains an
|
// register is stored, as this register is in the pointer map, but contains an
|
||||||
// integer value.
|
// integer value.
|
||||||
__ StoreToSafepointRegisterSlot(zero_reg, reg);
|
__ StoreToSafepointRegisterSlot(zero_reg, src);
|
||||||
|
__ StoreToSafepointRegisterSlot(zero_reg, dst);
|
||||||
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
|
||||||
if (!reg.is(v0)) __ mov(reg, v0);
|
__ Move(dst, v0);
|
||||||
|
|
||||||
// Done. Put the value in dbl_scratch into the value of the allocated heap
|
// Done. Put the value in dbl_scratch into the value of the allocated heap
|
||||||
// number.
|
// number.
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
__ sdc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
|
__ sdc1(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset));
|
||||||
__ StoreToSafepointRegisterSlot(reg, reg);
|
__ StoreToSafepointRegisterSlot(dst, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3810,25 +3813,23 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
|
|||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
void LCodeGen::DoSmiTag(LSmiTag* instr) {
|
||||||
LOperand* input = instr->InputAt(0);
|
|
||||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
|
||||||
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
|
||||||
__ SmiTag(ToRegister(input));
|
__ SmiTag(ToRegister(instr->result()), ToRegister(instr->InputAt(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
||||||
Register scratch = scratch0();
|
Register scratch = scratch0();
|
||||||
LOperand* input = instr->InputAt(0);
|
Register input = ToRegister(instr->InputAt(0));
|
||||||
ASSERT(input->IsRegister() && input->Equals(instr->result()));
|
Register result = ToRegister(instr->result());
|
||||||
if (instr->needs_check()) {
|
if (instr->needs_check()) {
|
||||||
STATIC_ASSERT(kHeapObjectTag == 1);
|
STATIC_ASSERT(kHeapObjectTag == 1);
|
||||||
// If the input is a HeapObject, value of scratch won't be zero.
|
// If the input is a HeapObject, value of scratch won't be zero.
|
||||||
__ And(scratch, ToRegister(input), Operand(kHeapObjectTag));
|
__ And(scratch, input, Operand(kHeapObjectTag));
|
||||||
__ SmiUntag(ToRegister(input));
|
__ SmiUntag(result, input);
|
||||||
DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
|
DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg));
|
||||||
} else {
|
} else {
|
||||||
__ SmiUntag(ToRegister(input));
|
__ SmiUntag(result, input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3876,10 +3877,9 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
|||||||
|
|
||||||
// Smi to double register conversion
|
// Smi to double register conversion
|
||||||
__ bind(&load_smi);
|
__ bind(&load_smi);
|
||||||
__ SmiUntag(input_reg); // Untag smi before converting to float.
|
__ SmiUntag(scratch, input_reg); // Untag smi before converting to float.
|
||||||
__ mtc1(input_reg, result_reg);
|
__ mtc1(scratch, result_reg);
|
||||||
__ cvt_d_w(result_reg, result_reg);
|
__ cvt_d_w(result_reg, result_reg);
|
||||||
__ SmiTag(input_reg); // Retag smi.
|
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,11 +1628,11 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
|||||||
return AssignEnvironment(DefineAsRegister(res));
|
return AssignEnvironment(DefineAsRegister(res));
|
||||||
} else {
|
} else {
|
||||||
ASSERT(to.IsInteger32());
|
ASSERT(to.IsInteger32());
|
||||||
LOperand* value = UseRegister(instr->value());
|
LOperand* value = UseRegisterAtStart(instr->value());
|
||||||
bool needs_check = !instr->value()->type().IsSmi();
|
bool needs_check = !instr->value()->type().IsSmi();
|
||||||
LInstruction* res = NULL;
|
LInstruction* res = NULL;
|
||||||
if (!needs_check) {
|
if (!needs_check) {
|
||||||
res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
|
res = DefineAsRegister(new LSmiUntag(value, needs_check));
|
||||||
} else {
|
} else {
|
||||||
LOperand* temp1 = TempRegister();
|
LOperand* temp1 = TempRegister();
|
||||||
LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
|
LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
|
||||||
@ -1668,12 +1668,12 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
|
|||||||
} else if (from.IsInteger32()) {
|
} else if (from.IsInteger32()) {
|
||||||
if (to.IsTagged()) {
|
if (to.IsTagged()) {
|
||||||
HValue* val = instr->value();
|
HValue* val = instr->value();
|
||||||
LOperand* value = UseRegister(val);
|
LOperand* value = UseRegisterAtStart(val);
|
||||||
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
if (val->HasRange() && val->range()->IsInSmiRange()) {
|
||||||
return DefineSameAsFirst(new LSmiTag(value));
|
return DefineAsRegister(new LSmiTag(value));
|
||||||
} else {
|
} else {
|
||||||
LNumberTagI* result = new LNumberTagI(value);
|
LNumberTagI* result = new LNumberTagI(value);
|
||||||
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ASSERT(to.IsDouble());
|
ASSERT(to.IsDouble());
|
||||||
|
@ -4517,6 +4517,30 @@ void MacroAssembler::JumpIfNotPowerOfTwoOrZero(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MacroAssembler::SmiTagCheckOverflow(Register reg, Register overflow) {
|
||||||
|
ASSERT(!reg.is(overflow));
|
||||||
|
mov(overflow, reg); // Save original value.
|
||||||
|
SmiTag(reg);
|
||||||
|
xor_(overflow, overflow, reg); // Overflow if (value ^ 2 * value) < 0.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MacroAssembler::SmiTagCheckOverflow(Register dst,
|
||||||
|
Register src,
|
||||||
|
Register overflow) {
|
||||||
|
if (dst.is(src)) {
|
||||||
|
// Fall back to slower case.
|
||||||
|
SmiTagCheckOverflow(dst, overflow);
|
||||||
|
} else {
|
||||||
|
ASSERT(!dst.is(src));
|
||||||
|
ASSERT(!dst.is(overflow));
|
||||||
|
ASSERT(!src.is(overflow));
|
||||||
|
SmiTag(dst, src);
|
||||||
|
xor_(overflow, dst, src); // Overflow if (value ^ 2 * value) < 0.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MacroAssembler::JumpIfNotBothSmi(Register reg1,
|
void MacroAssembler::JumpIfNotBothSmi(Register reg1,
|
||||||
Register reg2,
|
Register reg2,
|
||||||
Label* on_not_both_smi) {
|
Label* on_not_both_smi) {
|
||||||
|
@ -1222,24 +1222,13 @@ class MacroAssembler: public Assembler {
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Smi utilities.
|
// Smi utilities.
|
||||||
|
|
||||||
// Try to convert int32 to smi. If the value is to large, preserve
|
|
||||||
// the original value and jump to not_a_smi. Destroys scratch and
|
|
||||||
// sets flags.
|
|
||||||
// This is only used by crankshaft atm so it is unimplemented on MIPS.
|
|
||||||
void TrySmiTag(Register reg, Label* not_a_smi, Register scratch) {
|
|
||||||
UNIMPLEMENTED_MIPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmiTag(Register reg) {
|
void SmiTag(Register reg) {
|
||||||
Addu(reg, reg, reg);
|
Addu(reg, reg, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
|
// Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
|
||||||
void SmiTagCheckOverflow(Register reg, Register overflow) {
|
void SmiTagCheckOverflow(Register reg, Register overflow);
|
||||||
mov(overflow, reg); // Save original value.
|
void SmiTagCheckOverflow(Register dst, Register src, Register overflow);
|
||||||
addu(reg, reg, reg);
|
|
||||||
xor_(overflow, overflow, reg); // Overflow if (value ^ 2 * value) < 0.
|
|
||||||
}
|
|
||||||
|
|
||||||
void SmiTag(Register dst, Register src) {
|
void SmiTag(Register dst, Register src) {
|
||||||
Addu(dst, src, src);
|
Addu(dst, src, src);
|
||||||
|
Loading…
Reference in New Issue
Block a user