From: olivf@chromium.org Date: Thu, 12 Sep 2013 11:54:47 +0000 (+0000) Subject: Reland "Fix phis for non-sse2 double values" X-Git-Tag: upstream/4.7.83~12532 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bd5fa9c93b9e6d002f8ff3cf21db973f0b509880;p=platform%2Fupstream%2Fv8.git Reland "Fix phis for non-sse2 double values" Remove VerifyX87StackDepth from non-debug code. BUG= R=verwaest@chromium.org Review URL: https://codereview.chromium.org/23621038 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16682 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 860646c..632ad97 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -382,9 +382,13 @@ bool LCodeGen::GenerateBody() { instr->CompileToNative(this); - if (!CpuFeatures::IsSupported(SSE2) && - FLAG_debug_code && FLAG_enable_slow_asserts) { + if (!CpuFeatures::IsSupported(SSE2)) { + if (instr->IsGoto()) { + x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr)); + } else if (FLAG_debug_code && FLAG_enable_slow_asserts && + !instr->IsGap() && !instr->IsReturn()) { __ VerifyX87StackDepth(x87_stack_.depth()); + } } } EnsureSpaceForLazyDeopt(); @@ -682,6 +686,21 @@ void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) { __ fstp(0); stack_depth_--; } + if (FLAG_debug_code && FLAG_enable_slow_asserts) __ VerifyX87StackDepth(0); + } +} + + +void LCodeGen::X87Stack::LeavingBlock(int current_block_id, LGoto* goto_instr) { + ASSERT(stack_depth_ <= 1); + // If ever used for new stubs producing two pairs of doubles joined into two + // phis this assert hits. That situation is not handled, since the two stacks + // might have st0 and st1 swapped. + if (current_block_id + 1 != goto_instr->block_id()) { + // If we have a value on the x87 stack on leaving a block, it must be a + // phi input. If the next block we compile is not the join block, we have + // to discard the stack state. + stack_depth_ = 0; } } @@ -2486,6 +2505,10 @@ void LCodeGen::EmitGoto(int block) { } +void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) { +} + + void LCodeGen::DoGoto(LGoto* instr) { EmitGoto(instr->block_id()); } diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index cc1747d..b097694 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -471,6 +471,7 @@ class LCodeGen V8_FINAL BASE_EMBEDDED { void PrepareToWrite(X87Register reg); void CommitWrite(X87Register reg); void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen); + void LeavingBlock(int current_block_id, LGoto* goto_instr); int depth() const { return stack_depth_; } void pop() { ASSERT(is_mutable_); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 07dbf13..e2eee19 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -954,6 +954,16 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { if (FLAG_stress_environments && !instr->HasEnvironment()) { instr = AssignEnvironment(instr); } + if (!CpuFeatures::IsSafeForSnapshot(SSE2) && instr->IsGoto() && + LGoto::cast(instr)->jumps_to_join()) { + // TODO(olivf) Since phis of spilled values are joined as registers + // (not in the stack slot), we need to allow the goto gaps to keep one + // x87 register alive. To ensure all other values are still spilled, we + // insert a fpu register barrier right before. + LClobberDoubles* clobber = new(zone()) LClobberDoubles(); + clobber->set_hydrogen_value(current); + chunk_->AddInstruction(clobber, current_block_); + } instr->set_hydrogen_value(current); chunk_->AddInstruction(instr, current_block_); } @@ -1046,7 +1056,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment( LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { - return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); + return new(zone()) LGoto(instr->FirstSuccessor()); } @@ -1058,7 +1068,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HBasicBlock* successor = HConstant::cast(value)->BooleanValue() ? instr->FirstSuccessor() : instr->SecondSuccessor(); - return new(zone()) LGoto(successor->block_id()); + return new(zone()) LGoto(successor); } ToBooleanStub::Types expected = instr->expected_input_types(); diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index ab964af..d96764f 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -73,6 +73,7 @@ class LCodeGen; V(ClampTToUint8) \ V(ClampTToUint8NoSSE2) \ V(ClassOfTestAndBranch) \ + V(ClobberDoubles) \ V(CompareNumericAndBranch) \ V(CmpObjectEqAndBranch) \ V(CmpHoleAndBranch) \ @@ -406,19 +407,32 @@ class LInstructionGap V8_FINAL : public LGap { }; +class LClobberDoubles V8_FINAL : public LTemplateInstruction<0, 0, 0> { + public: + LClobberDoubles() { ASSERT(!CpuFeatures::IsSafeForSnapshot(SSE2)); } + + virtual bool ClobbersDoubleRegisters() const { return true; } + + DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d") +}; + + class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> { public: - explicit LGoto(int block_id) : block_id_(block_id) { } + explicit LGoto(HBasicBlock* block) : block_(block) { } virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE; DECLARE_CONCRETE_INSTRUCTION(Goto, "goto") virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; virtual bool IsControl() const V8_OVERRIDE { return true; } - int block_id() const { return block_id_; } + int block_id() const { return block_->block_id(); } + virtual bool ClobbersDoubleRegisters() const { return false; } + + bool jumps_to_join() const { return block_->predecessors()->length() > 1; } private: - int block_id_; + HBasicBlock* block_; }; diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index fbfe9dd..b65d328 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -2798,6 +2798,8 @@ void MacroAssembler::Ret(int bytes_dropped, Register scratch) { void MacroAssembler::VerifyX87StackDepth(uint32_t depth) { // Make sure the floating point stack is either empty or has depth items. ASSERT(depth <= 7); + // This is very expensive. + ASSERT(FLAG_debug_code && FLAG_enable_slow_asserts); // The top-of-stack (tos) is 7 if there is one item pushed. int tos = (8 - depth) % 8;