From: svenpanne@chromium.org Date: Mon, 3 Sep 2012 06:36:19 +0000 (+0000) Subject: MIPS: First steps towards named Litihium operands. X-Git-Tag: upstream/4.7.83~16064 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7398b33c1fd94a17480306017cc83e4c6d1a086;p=platform%2Fupstream%2Fv8.git 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 . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12423 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 2b738e9a4..99728b5b8 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -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); diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index b811ab6f3..aeafbcd74 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -110,7 +110,12 @@ class LCodeGen BASE_EMBEDDED { void FinishCode(Handle 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); int DefineDeoptimizationLiteral(Handle literal); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 9cc282b9f..560ea534c 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -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(); diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index 2d35ede51..367cf2a90 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -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) {