Revision: 6748
Author: [email protected]
Date: Fri Feb 11 04:56:30 2011
Log: Add a genuine unary minus instruction to Crankshaft.

This change introduces an instruction for negation instead
of generating a multiplication with -1.

The code for x64 and ARM is not included in this change.


Review URL: http://codereview.chromium.org/6461021
http://code.google.com/p/v8/source/detail?r=6748

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/x64/lithium-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Thu Feb 10 12:04:54 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri Feb 11 04:56:30 2011
@@ -1296,6 +1296,12 @@
   ASSERT(instr->representation().IsInteger32());
return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value())));
 }
+
+
+LInstruction* LChunkBuilder::DoNeg(HNeg* instr) {
+  Abort("Unimplemented: %s", "DoNeg");
+  return NULL;
+}


 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Fri Feb 11 04:25:41 2011
+++ /branches/bleeding_edge/src/flag-definitions.h      Fri Feb 11 04:56:30 2011
@@ -120,6 +120,7 @@
 DEFINE_bool(trace_hydrogen, false, "trace generated hydrogen to file")
 DEFINE_bool(trace_inlining, false, "trace inlining decisions")
 DEFINE_bool(trace_alloc, false, "trace register allocator")
+DEFINE_bool(trace_all_uses, false, "trace all use positions")
 DEFINE_bool(trace_range, false, "trace range analysis")
 DEFINE_bool(trace_gvn, false, "trace global value numbering")
 DEFINE_bool(trace_representation, false, "trace representation types")
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Thu Feb 10 04:02:36 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Feb 11 04:56:30 2011
@@ -760,6 +760,12 @@
   if (CanTruncateToInt32()) stream->Add(" truncating-int32");
   if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
 }
+
+
+void HNeg::PrintDataTo(StringStream* stream) const {
+  HUnaryOperation::PrintDataTo(stream);
+  if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?");
+}


 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction(
@@ -965,6 +971,22 @@
     return HArithmeticBinaryOperation::InferRange();
   }
 }
+
+
+Range* HNeg::InferRange() {
+  if (representation().IsInteger32()) {
+    Range* input_range = value()->range();
+    Range* result = input_range->Copy();
+    Range neg_one(-1, -1);
+    if (!result->MulAndCheckOverflow(&neg_one)) {
+      ClearFlag(HValue::kCanOverflow);
+    }
+    result->set_can_be_minus_zero(input_range->CanBeZero());
+    return result;
+  } else {
+    return HValue::InferRange();
+  }
+}


 void HPhi::PrintTo(StringStream* stream) const {
@@ -1387,6 +1409,11 @@
 HType HBitNot::CalculateInferredType() const {
   return HType::TaggedNumber();
 }
+
+
+HType HNeg::CalculateInferredType() const {
+  return HType::TaggedNumber();
+}


 HType HUnaryMathOperation::CalculateInferredType() const {
@@ -1465,6 +1492,15 @@
   }
   return NULL;
 }
+
+
+HValue* HNeg::EnsureAndPropagateNotMinusZero(BitVector* visited) {
+  visited->Add(id());
+  if (range() == NULL || range()->CanBeMinusZero()) {
+    SetFlag(kBailoutOnMinusZero);
+  }
+  return NULL;
+}


 HValue* HSub::EnsureAndPropagateNotMinusZero(BitVector* visited) {
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Feb 11 02:17:52 2011 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Feb 11 04:56:30 2011
@@ -131,6 +131,7 @@
   V(LoadPixelArrayExternalPointer)             \
   V(Mod)                                       \
   V(Mul)                                       \
+  V(Neg)                                       \
   V(ObjectLiteral)                             \
   V(OsrEntry)                                  \
   V(OuterContext)                              \
@@ -1466,6 +1467,39 @@
 };


+class HNeg: public HUnaryOperation {
+ public:
+  explicit HNeg(HValue* value) : HUnaryOperation(value) {
+    set_representation(Representation::Tagged());
+    SetFlag(kFlexibleRepresentation);
+    SetFlag(kCanOverflow);
+    SetAllSideEffects();
+  }
+
+  virtual void RepresentationChanged(Representation to) {
+    // May change from tagged to untagged, not vice versa.
+    ASSERT(representation().IsTagged() || representation().Equals(to));
+    if (!to.IsTagged()) {
+      ClearAllSideEffects();
+      SetFlag(kUseGVN);
+    }
+  }
+
+  virtual Representation RequiredInputRepresentation(int index) const {
+    return representation();
+  }
+
+  virtual HType CalculateInferredType() const;
+  virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
+  virtual void PrintDataTo(StringStream* stream) const;
+  DECLARE_CONCRETE_INSTRUCTION(Neg, "neg")
+
+ protected:
+  virtual bool DataEquals(HValue* other) const { return true; }
+  virtual Range* InferRange();
+};
+
+
 class HUnaryMathOperation: public HUnaryOperation {
  public:
   HUnaryMathOperation(HValue* value, BuiltinFunctionId op)
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Fri Feb 11 03:57:11 2011
+++ /branches/bleeding_edge/src/hydrogen.cc     Fri Feb 11 04:56:30 2011
@@ -4700,7 +4700,7 @@
         instr = new HBitNot(value);
         break;
       case Token::SUB:
-        instr = new HMul(graph_->GetConstantMinus1(), value);
+        instr = new HNeg(value);
         break;
       default:
         UNREACHABLE();
@@ -5911,7 +5911,7 @@

     UsePosition* current_pos = range->first_pos();
     while (current_pos != NULL) {
-      if (current_pos->RegisterIsBeneficial()) {
+      if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) {
         trace_.Add(" %d M", current_pos->pos().Value());
       }
       current_pos = current_pos->next();
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Feb 11 03:24:38 2011 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Feb 11 04:56:30 2011
@@ -1033,6 +1033,36 @@
   ASSERT(input->Equals(instr->result()));
   __ not_(ToRegister(input));
 }
+
+
+void LCodeGen::DoNegI(LNegI* instr) {
+  Register input = ToRegister(instr->value());
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    __ test(input, Operand(input));
+    DeoptimizeIf(zero, instr->environment());
+  }
+  __ neg(input);
+  if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+    DeoptimizeIf(overflow, instr->environment());
+  }
+}
+
+
+void LCodeGen::DoNegD(LNegD* instr) {
+  XMMRegister reg = ToDoubleRegister(instr->value());
+  Register temp = ToRegister(instr->TempAt(0));
+  __ Set(temp, Immediate(0x80000000));
+  __ movd(xmm0, Operand(temp));
+  __ psllq(xmm0, 32);
+  __ xorpd(reg, xmm0);
+}
+
+
+void LCodeGen::DoNegT(LNegT* instr) {
+  UnaryOverwriteMode overwrite = UNARY_NO_OVERWRITE;
+  GenericUnaryOpStub stub(Token::SUB, overwrite, NO_UNARY_FLAGS);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}


 void LCodeGen::DoThrow(LThrow* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Feb 10 04:02:36 2011 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri Feb 11 04:56:30 2011
@@ -1314,6 +1314,29 @@
   LBitNotI* result = new LBitNotI(input);
   return DefineSameAsFirst(result);
 }
+
+
+LInstruction* LChunkBuilder::DoNeg(HNeg* instr) {
+  Representation r = instr->representation();
+  if (r.IsInteger32()) {
+    LOperand* input = UseRegister(instr->value());
+    LNegI* result = new LNegI(input);
+    if (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+        instr->CheckFlag(HValue::kCanOverflow)) {
+      AssignEnvironment(result);
+    }
+    return DefineSameAsFirst(result);
+  } else if (r.IsDouble()) {
+    LOperand* input = UseRegister(instr->value());
+    LOperand* temp = TempRegister();
+    return DefineSameAsFirst(new LNegD(input, temp));
+  } else {
+    ASSERT(r.IsTagged());
+    LOperand* input = UseFixed(instr->value(), eax);
+    LNegT* result = new LNegT(input);
+    return MarkAsCall(DefineFixed(result, eax), instr);
+  }
+}


 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h     Thu Feb 10 04:02:36 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h     Fri Feb 11 04:56:30 2011
@@ -128,6 +128,9 @@
   V(LoadPixelArrayExternalPointer)              \
   V(ModI)                                       \
   V(MulI)                                       \
+  V(NegI)                                       \
+  V(NegD)                                       \
+  V(NegT)                                       \
   V(NumberTagD)                                 \
   V(NumberTagI)                                 \
   V(NumberUntagD)                               \
@@ -1079,6 +1082,40 @@
 };


+class LNegI: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LNegI(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(NegI, "neg-i")
+  DECLARE_HYDROGEN_ACCESSOR(Neg)
+  LOperand* value() { return inputs_[0]; }
+};
+
+
+class LNegD: public LTemplateInstruction<1, 1, 1> {
+ public:
+  explicit LNegD(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(NegD, "neg-d")
+  LOperand* value() { return inputs_[0]; }
+};
+
+
+class LNegT: public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LNegT(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(NegT, "neg-t")
+};
+
+
 class LAddI: public LTemplateInstruction<1, 2, 0> {
  public:
   LAddI(LOperand* left, LOperand* right) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Thu Feb 10 08:33:01 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri Feb 11 04:56:30 2011
@@ -1248,6 +1248,12 @@
   LBitNotI* result = new LBitNotI(input);
   return DefineSameAsFirst(result);
 }
+
+
+LInstruction* LChunkBuilder::DoNeg(HNeg* instr) {
+  Abort("Unimplemented: %s", "DoNeg");
+  return NULL;
+}


 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to