MIPS: First steps towards named Litihium operands.

Port r12383 (881d7d4d)

Original commit message:
Accessing Lithium operands via position is fragile and makes it impossible to
statically find all uses of a given operand. This CL is a step towards cleaning
this up, more to come...

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10911021
Patch from Akos Palfi <palfia@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12423 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cc17d6dc
......@@ -471,7 +471,8 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->MarkDuplicate();
AddToTranslation(translation,
environment->spilled_registers()[value->index()],
environment->HasTaggedValueAt(i));
environment->HasTaggedValueAt(i),
environment->HasUint32ValueAt(i));
} else if (
value->IsDoubleRegister() &&
environment->spilled_double_registers()[value->index()] != NULL) {
......@@ -479,18 +480,23 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
AddToTranslation(
translation,
environment->spilled_double_registers()[value->index()],
false,
false);
}
}
AddToTranslation(translation, value, environment->HasTaggedValueAt(i));
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(i),
environment->HasUint32ValueAt(i));
}
}
void LCodeGen::AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged) {
bool is_tagged,
bool is_uint32) {
if (op == NULL) {
// TODO(twuerthinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
......@@ -499,6 +505,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
} else if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
} else if (is_uint32) {
translation->StoreUint32StackSlot(op->index());
} else {
translation->StoreInt32StackSlot(op->index());
}
......@@ -512,6 +520,8 @@ void LCodeGen::AddToTranslation(Translation* translation,
Register reg = ToRegister(op);
if (is_tagged) {
translation->StoreRegister(reg);
} else if (is_uint32) {
translation->StoreUint32Register(reg);
} else {
translation->StoreInt32Register(reg);
}
......@@ -2776,11 +2786,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
break;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ lw(result, mem_operand);
// TODO(danno): we could be more clever here, perhaps having a special
// version of the stub that detects if the overflow case actually
// happens, and generate code that returns a double rather than int.
DeoptimizeIf(Ugreater_equal, instr->environment(),
result, Operand(0x80000000));
if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
DeoptimizeIf(Ugreater_equal, instr->environment(),
result, Operand(0x80000000));
}
break;
case EXTERNAL_FLOAT_ELEMENTS:
case EXTERNAL_DOUBLE_ELEMENTS:
......@@ -4066,12 +4075,26 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
}
void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
LOperand* input = instr->InputAt(0);
LOperand* output = instr->result();
FPURegister dbl_scratch = double_scratch0();
__ mtc1(ToRegister(input), dbl_scratch);
__ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22);
}
void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
class DeferredNumberTagI: public LDeferredCode {
public:
DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
: LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() { codegen()->DoDeferredNumberTagI(instr_); }
virtual void Generate() {
codegen()->DoDeferredNumberTagI(instr_,
instr_->InputAt(0),
SIGNED_INT32);
}
virtual LInstruction* instr() { return instr_; }
private:
LNumberTagI* instr_;
......@@ -4088,25 +4111,59 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
}
void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
class DeferredNumberTagU: public LDeferredCode {
public:
DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
: LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() {
codegen()->DoDeferredNumberTagI(instr_,
instr_->InputAt(0),
UNSIGNED_INT32);
}
virtual LInstruction* instr() { return instr_; }
private:
LNumberTagU* instr_;
};
LOperand* input = instr->InputAt(0);
ASSERT(input->IsRegister() && input->Equals(instr->result()));
Register reg = ToRegister(input);
DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
__ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue));
__ SmiTag(reg, reg);
__ bind(deferred->exit());
}
void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
LOperand* value,
IntegerSignedness signedness) {
Label slow;
Register src = ToRegister(instr->InputAt(0));
Register src = ToRegister(value);
Register dst = ToRegister(instr->result());
FPURegister dbl_scratch = double_scratch0();
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
// There was overflow, so bits 30 and 31 of the original integer
// disagree. Try to allocate a heap number in new space and store
// the value in there. If that fails, call the runtime system.
Label done;
if (dst.is(src)) {
__ SmiUntag(src, dst);
__ Xor(src, src, Operand(0x80000000));
if (signedness == SIGNED_INT32) {
// There was overflow, so bits 30 and 31 of the original integer
// disagree. Try to allocate a heap number in new space and store
// the value in there. If that fails, call the runtime system.
if (dst.is(src)) {
__ SmiUntag(src, dst);
__ Xor(src, src, Operand(0x80000000));
}
__ mtc1(src, dbl_scratch);
__ cvt_d_w(dbl_scratch, dbl_scratch);
} else {
__ mtc1(src, dbl_scratch);
__ Cvt_d_uw(dbl_scratch, dbl_scratch, f22);
}
__ mtc1(src, dbl_scratch);
__ cvt_d_w(dbl_scratch, dbl_scratch);
if (FLAG_inline_new) {
__ LoadRoot(t2, Heap::kHeapNumberMapRootIndex);
__ AllocateHeapNumber(t1, a3, t0, t2, &slow);
......
......@@ -110,7 +110,12 @@ class LCodeGen BASE_EMBEDDED {
void FinishCode(Handle<Code> code);
void DoDeferredNumberTagD(LNumberTagD* instr);
void DoDeferredNumberTagI(LNumberTagI* instr);
enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
void DoDeferredNumberTagI(LInstruction* instr,
LOperand* value,
IntegerSignedness signedness);
void DoDeferredTaggedToI(LTaggedToI* instr);
void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
void DoDeferredStackCheck(LStackCheck* instr);
......@@ -252,7 +257,8 @@ class LCodeGen BASE_EMBEDDED {
void AddToTranslation(Translation* translation,
LOperand* op,
bool is_tagged);
bool is_tagged,
bool is_uint32);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
......
......@@ -704,15 +704,20 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
right = UseRegisterAtStart(right_value);
}
// Shift operations can only deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32.
bool may_deopt = (op == Token::SHR && constant_value == 0);
bool does_deopt = false;
if (may_deopt) {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
does_deopt = true;
break;
if (FLAG_opt_safe_uint32_operations) {
does_deopt = !instr->CheckFlag(HInstruction::kUint32);
} else {
// Shift operations can only deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32.
bool may_deopt = (op == Token::SHR && constant_value == 0);
if (may_deopt) {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) {
does_deopt = true;
break;
}
}
}
}
......@@ -1585,7 +1590,10 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
if (to.IsTagged()) {
HValue* val = instr->value();
LOperand* value = UseRegisterAtStart(val);
if (val->HasRange() && val->range()->IsInSmiRange()) {
if (val->CheckFlag(HInstruction::kUint32)) {
LNumberTagU* result = new(zone()) LNumberTagU(value);
return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
} else if (val->HasRange() && val->range()->IsInSmiRange()) {
return DefineAsRegister(new(zone()) LSmiTag(value));
} else {
LNumberTagI* result = new(zone()) LNumberTagI(value);
......@@ -1593,8 +1601,13 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
}
} else {
ASSERT(to.IsDouble());
LOperand* value = Use(instr->value());
return DefineAsRegister(new(zone()) LInteger32ToDouble(value));
if (instr->value()->CheckFlag(HInstruction::kUint32)) {
return DefineAsRegister(
new(zone()) LUint32ToDouble(UseRegister(instr->value())));
} else {
return DefineAsRegister(
new(zone()) LInteger32ToDouble(Use(instr->value())));
}
}
}
UNREACHABLE();
......
......@@ -108,6 +108,7 @@ class LCodeGen;
V(InstanceOfKnownGlobal) \
V(InstructionGap) \
V(Integer32ToDouble) \
V(Uint32ToDouble) \
V(InvokeFunction) \
V(IsConstructCallAndBranch) \
V(IsNilAndBranch) \
......@@ -137,6 +138,7 @@ class LCodeGen;
V(MulI) \
V(NumberTagD) \
V(NumberTagI) \
V(NumberTagU) \
V(NumberUntagD) \
V(ObjectLiteral) \
V(OsrEntry) \
......@@ -1587,6 +1589,16 @@ class LInteger32ToDouble: public LTemplateInstruction<1, 1, 0> {
};
class LUint32ToDouble: public LTemplateInstruction<1, 1, 0> {
public:
explicit LUint32ToDouble(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
};
class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagI(LOperand* value) {
......@@ -1597,6 +1609,16 @@ class LNumberTagI: public LTemplateInstruction<1, 1, 0> {
};
class LNumberTagU: public LTemplateInstruction<1, 1, 0> {
public:
explicit LNumberTagU(LOperand* value) {
inputs_[0] = value;
}
DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
};
class LNumberTagD: public LTemplateInstruction<1, 1, 2> {
public:
LNumberTagD(LOperand* value, LOperand* temp1, LOperand* temp2) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment