Fix type propagation rules for count operation.
authorfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Mar 2010 16:39:29 +0000 (16:39 +0000)
committerfschneider@chromium.org <fschneider@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Mar 2010 16:39:29 +0000 (16:39 +0000)
Also treat const-variables as not side-effect free.

Review URL: http://codereview.chromium.org/982009

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4172 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ia32/codegen-ia32.cc
src/rewriter.cc
test/mjsunit/compiler/loopcount.js

index 2b3d4d9..c2ae3d8 100644 (file)
@@ -3763,6 +3763,21 @@ void CodeGenerator::VisitForStatement(ForStatement* node) {
     }
   }
 
+  // The update expression resets the type of the loop variable. So we
+  // set it to smi before compiling the test expression.
+  if (node->is_fast_smi_loop()) {
+    // Set number type of the loop variable to smi.
+    Slot* slot = node->loop_variable()->slot();
+    ASSERT(slot->type() == Slot::LOCAL);
+    frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi());
+    if (FLAG_debug_code) {
+      frame_->PushLocalAt(slot->index());
+      Result var = frame_->Pop();
+      var.ToRegister();
+      __ AbortIfNotSmi(var.reg(), "Loop variable not a smi.");
+    }
+  }
+
   // Based on the condition analysis, compile the backward jump as
   // necessary.
   switch (info) {
@@ -6867,7 +6882,12 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
       old_value = allocator_->Allocate();
       ASSERT(old_value.is_valid());
       __ mov(old_value.reg(), new_value.reg());
+
+      // The old value that is return for postfix operations has the
+      // same type as the input value we got from the frame.
+      old_value.set_number_info(new_value.number_info());
     }
+
     // Ensure the new value is writable.
     frame_->Spill(new_value.reg());
 
@@ -6931,6 +6951,8 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
     }
     deferred->BindExit();
 
+    // The result of ++ or -- is always a number.
+    new_value.set_number_info(NumberInfo::Number());
 
     // Postfix: store the old value in the allocated slot under the
     // reference.
index b05b045..e87fcce 100644 (file)
@@ -247,7 +247,9 @@ void AstOptimizer::VisitVariableProxy(VariableProxy* node) {
     }
 
     if (FLAG_safe_int32_compiler) {
-      if (var->IsStackAllocated() && !var->is_arguments()) {
+      if (var->IsStackAllocated() &&
+          !var->is_arguments() &&
+          var->mode() != Variable::CONST) {
         node->set_side_effect_free(true);
       }
     }
index d41eea1..0eadc38 100644 (file)
@@ -53,3 +53,6 @@ function f5() {
   return i;
 }
 assertEquals(-0x40000001, f5());
+
+function f6() { var x = 0x3fffffff; x++; return x+1; }
+assertEquals(0x40000001, f6());