Reviewers: Toon Verwaest,

Description:
Fix phis for non-sse2 double values

Since hydrogen will try to merge phi-inputs using registers, even if
the values are spilled, we cannot mark LGoto as double clobbering
instruction.

BUG=

Please review this at https://codereview.chromium.org/23068038/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/ia32/lithium-codegen-ia32.h
  M src/ia32/lithium-codegen-ia32.cc
  M src/ia32/lithium-ia32.h
  src/ia32/lithium-ia32.cc


Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 75525ed5be95ee7723968a0084687de7c440c3c7..e6e763e6550f5913e59a9fd2d25bc64173252c55 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -359,9 +359,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();
@@ -659,6 +663,18 @@ void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
       __ fstp(0);
       stack_depth_--;
     }
+    __ VerifyX87StackDepth(0);
+  }
+}
+
+
+void LCodeGen::X87Stack::LeavingBlock(int current_block_id, LGoto* goto_instr) {
+  ASSERT(stack_depth_ <= 1);
+  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;
   }
 }

@@ -2439,6 +2455,10 @@ void LCodeGen::EmitGoto(int block) {
 }


+void LCodeGen::DoClobberDoubles(LClobberDoubles* instr) {
+}
+
+
 void LCodeGen::DoGoto(LGoto* instr) {
   EmitGoto(instr->block_id());
 }
Index: src/ia32/lithium-codegen-ia32.h
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 23b2e48fb0c5c403ecec0cb60a6143d1151212fa..a7a1a4755fc5b8fdb01540784a62fb0560bc3db6 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -468,6 +468,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_);
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 8d660858508411408bd1ffc9aa31f7a86a22873b..aa686bfe8307a8627beaef9492fb288b71d7369c 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -945,6 +945,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_);
   }
@@ -1037,7 +1047,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(


 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
+  return new(zone()) LGoto(instr->FirstSuccessor());
 }


@@ -1049,7 +1059,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();
Index: src/ia32/lithium-ia32.h
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 8b311b7ae9c857e392ef51e5445a8a026b78b0c3..9e072f26c4bd1a3d50ff5af2d00b1b73da367a51 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_;
 };




--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to